โครงสร้างสินทรัพย์ SCSS ที่เหมาะสมใน Rails


86

ดังนั้นฉันมีapp/assets/stylesheets/โครงสร้างไดเร็กทอรีที่มีลักษณะดังนี้:

   |-dialogs
   |-mixins
   |---buttons
   |---gradients
   |---vendor_support
   |---widgets
   |-pages
   |-structure
   |-ui_elements

ในแต่ละไดเร็กทอรีมีหลายส่วนของ sass (โดยปกติคือ * .css.scss แต่หนึ่งหรือสอง * .css.scss.erb)

ฉันอาจจะคิดมาก แต่ทางรถไฟควรรวบรวมไฟล์ทั้งหมดในไดเร็กทอรีเหล่านั้นโดยอัตโนมัติเนื่องจาก*= require_tree .ใน application.css ใช่ไหม?

ฉันเพิ่งลองปรับโครงสร้างไฟล์เหล่านี้โดยลบตัวแปรสีทั้งหมดและวางไว้ในไฟล์ในapp/assets/stylesheetsโฟลเดอร์รูท(_colors.css.scss) จากนั้นฉันสร้างไฟล์ในapp/assets/stylesheetsโฟลเดอร์รูทชื่อ master.css.scss ซึ่งมีลักษณะดังนี้:

// Color Palette 
@import "colors";

// Mixins
@import "mixins/buttons/standard_button";
@import "mixins/gradients/table_header_fade";
@import "mixins/vendor_support/rounded_corners";
@import "mixins/vendor_support/rounded_corners_top";
@import "mixins/vendor_support/box_shadow";
@import "mixins/vendor_support/opacity";

ฉันไม่เข้าใจจริงๆว่ารางจัดการลำดับการรวบรวมเนื้อหาอย่างไร แต่เห็นได้ชัดว่ามันไม่ได้อยู่ในความโปรดปรานของฉัน ดูเหมือนว่าไม่มีไฟล์ใดที่ทราบว่ามีการนำเข้าตัวแปรหรือมิกซ์อินจึงทำให้เกิดข้อผิดพลาดและฉันไม่สามารถรวบรวมได้

Undefined variable: "$dialog_divider_color".
  (in /home/blah/app/assets/stylesheets/dialogs/dialog.css.scss.erb)

Undefined mixin 'rounded_corners'.
  (in /home/blah/app/assets/stylesheets/widgets.css.scss)

ตัวแปร$dialog_divider_colorถูกกำหนดไว้อย่างชัดเจนใน _colors.css.scss และ_master.css.scssกำลังนำเข้าสีและส่วนผสมทั้งหมดของฉัน แต่เห็นได้ชัดว่ารางไม่ได้รับบันทึกนั้น

มีวิธีใดบ้างที่ฉันสามารถแก้ไขข้อผิดพลาดเหล่านี้ได้หรือฉันจะต้องใช้การกำหนดตัวแปรทั้งหมดของฉันกลับเข้าไปในไฟล์แต่ละไฟล์ตลอดจนการนำเข้า mixin ทั้งหมด

น่าเสียดายที่ผู้ชายคนนี้ไม่คิดว่าจะเป็นไปได้ แต่ฉันหวังว่าเขาจะคิดผิด ความคิดใด ๆ ที่ได้รับการชื่นชมอย่างมาก

คำตอบ:


126

ปัญหาเกี่ยวกับ CSS คือคุณไม่ต้องการเพิ่มไฟล์ทั้งหมดโดยอัตโนมัติ ลำดับการโหลดและประมวลผลแผ่นงานของคุณโดยเบราว์เซอร์เป็นสิ่งสำคัญ ดังนั้นคุณจะต้องนำเข้า css ทั้งหมดของคุณอย่างชัดเจนเสมอ

ตัวอย่างเช่นสมมติว่าคุณมีแผ่นnormalize.cssเพื่อให้ได้รูปลักษณ์เริ่มต้นแทนการใช้งานเบราว์เซอร์ต่างๆที่น่ากลัวทั้งหมด นี่ควรเป็นไฟล์แรกที่เบราว์เซอร์โหลด หากคุณเพียงสุ่มรวมแผ่นงานนี้ไว้ที่ใดที่หนึ่งในการนำเข้า css ของคุณมันจะไม่เพียง แต่แทนที่รูปแบบเริ่มต้นของเบราว์เซอร์เท่านั้น แต่ยังรวมถึงสไตล์ที่กำหนดไว้ในไฟล์ css ทั้งหมดที่โหลดก่อนหน้านั้นด้วย สิ่งนี้จะเหมือนกันสำหรับตัวแปรและมิกซ์อิน

หลังจากเห็นการนำเสนอโดยRoy Tomeijที่ Euruko2012 ฉันตัดสินใจใช้แนวทางต่อไปนี้หากคุณมี CSS จำนวนมากให้จัดการ

โดยทั่วไปฉันใช้แนวทางนี้:

  1. เปลี่ยนชื่อไฟล์. css ที่มีอยู่ทั้งหมดเป็น. scss
  2. ลบเนื้อหาทั้งหมดออกจาก application.scss

เริ่มต้นการเพิ่มคำสั่ง @import application.scssไป

หากคุณใช้ twitters bootstrap และ css แผ่นของคุณเองคุณต้องนำเข้า bootstrap ก่อนเนื่องจากมีแผ่นสำหรับรีเซ็ตสไตล์ ดังนั้นคุณเพิ่มที่คุณ@import "bootstrap/bootstrap.scss";application.scss

ไฟล์ bootstrap.scss มีลักษณะดังนี้:

// CSS Reset
@import "reset.scss";

// Core
@import "variables.scss";
@import "mixins.scss";

// Grid system and page structure
@import "scaffolding.scss";

// Styled patterns and elements
@import "type.scss";
@import "forms.scss";
@import "tables.scss";
@import "patterns.scss";

และapplication.scssไฟล์ของคุณมีลักษณะดังนี้:

@import "bootstrap/bootstrap.scss";

เนื่องจากลำดับของการนำเข้าตอนนี้คุณสามารถใช้ตัวแปรโหลดด้วยไฟล์@import "variables.scss";อื่น ๆ ที่.scssนำเข้าหลังจากนั้น ดังนั้นจึงสามารถใช้ในtype.scssโฟลเดอร์ bootstrap แต่ยังอยู่ในmy_model.css.scss.

หลังจากนี้ให้สร้างโฟลเดอร์ชื่อpartialsหรือmodules. นี่จะเป็นตำแหน่งของไฟล์อื่น ๆ ส่วนใหญ่ คุณสามารถเพิ่มการนำเข้าลงในapplication.scssไฟล์เพื่อให้มีลักษณะดังนี้:

@import "bootstrap/bootstrap.scss";
@import "partials/*";

ตอนนี้ถ้าคุณสร้าง css เล็กน้อยเพื่อจัดสไตล์บทความในหน้าแรกของคุณ เพียงแค่สร้างและมันจะถูกเพิ่มลงในการรวบรวมpartials/_article.scss application.cssเนื่องจากคำสั่งนำเข้าคุณยังสามารถใช้ส่วนผสมและตัวแปร bootstrap ในไฟล์ scss ของคุณเองได้

ข้อเสียเปรียบประการเดียวของวิธีนี้ที่ฉันพบคือบางครั้งคุณต้องบังคับให้คอมไพล์ไฟล์ / *. scss บางส่วนซ้ำเพราะรางไม่เคยทำเพื่อคุณเสมอไป


4
ขอบคุณนี่คือแนวทางที่ฉันลงเอยด้วย ฉันเกลียดโซลูชันนี้เพราะคุณต้องเพิ่มไฟล์ทุกไฟล์ที่คุณรวมทุกครั้งที่สร้างด้วยตนเอง แต่ดูเหมือนว่าเมื่อ CSS เกี่ยวข้องคำสั่งก็มีความสำคัญ โดยปกติฉันจะบอกว่านั่นเป็นเพียงการเขียน CSS ที่ไม่ดี แต่ถ้าคุณใช้สิ่งที่ผู้ขายจัดหาให้ (เช่น bootstrap ตามที่คุณกล่าวไว้ข้างต้น) คุณมักจะต้องการเขียนทับสิ่งต่างๆดังนั้นฉันจึงเห็นด้วยอย่างยิ่งว่านี่เป็นแนวทางที่ถูกต้อง
David Savage

1
ขอบคุณ! แนวทางที่ดีมากและคำอธิบายที่ดี! โครงการหนึ่งที่ควรกล่าวถึง: ปลั๊กอิน FireBug FireSassนี้แสดงหมายเลขบรรทัดของ my_model.css.sass แทนบรรทัดของ application.css ที่รวบรวม
BBQ Chef

ด้วยวิธีนี้หากฉันต้องการเปลี่ยนสีลิงก์เริ่มต้นเป็นสีแดงที่ใช้กับชิ้นส่วนทั้งหมดของฉันคุณจะทำอย่างไร คุณจะวางไว้ที่ไหน?
ch

1
โปรดทราบว่าวิธีการนี้ยังแนะนำในThe Asset ท่อส่งคู่มือราง ค้นหา "หากคุณต้องการใช้ไฟล์ Sass หลายไฟล์"
ybakos

1
@Lykos ใช่คุณเอาทุกอย่างจากและเปลี่ยนชื่อเป็นapplication.css application.scssเพราะrequire_treeรวมทุกอย่างและคุณต้องการควบคุมคำสั่งโดยปกติ
Benjamin Udink ten Cate

8

ในการใช้ตัวแปรและสิ่งอื่น ๆ ในไฟล์ต่างๆคุณต้องใช้ @import directive ไฟล์จะถูกนำเข้าตามลำดับที่ระบุ

จากนั้นใช้ application.css เพื่อต้องการไฟล์ที่ประกาศการนำเข้า นี่คือวิธีที่จะบรรลุการควบคุมที่คุณต้องการ

สุดท้ายในไฟล์ layout.erb ของคุณคุณสามารถระบุไฟล์ css "master" ที่จะใช้

ตัวอย่างจะเป็นประโยชน์มากขึ้น:

สมมติว่าคุณมีโมดูลสองโมดูลในแอปที่ต้องใช้ชุด css ที่แตกต่างกัน: "application" และ "admin"

ไฟล์

|-app/
|-- assets/
|--- stylesheets/
|     // the "master" files that will be called by the layout
|---- application.css
|---- application_admin.css
|
|     // the files that contain styles
|---- config.scss
|---- styles.scss
|---- admin_styles.scss
|
|     // the files that define the imports
|---- app_imports.scss
|---- admin_imports.scss
|
|
|-- views/
|--- layouts/
|---- admin.html.haml
|---- application.html.haml

นี่คือลักษณะของไฟล์ภายใน:

-------- THE STYLES

-- config.scss
// declare variables and mixins
$font-size: 20px;

--  app_imports.scss
// using imports lets you use variables from `config` in `styles`
@import 'config'
@import 'styles'

-- admin_imports.scss
// for admin module, we import an additional stylesheet
@import 'config'
@import 'styles'
@import 'admin_styles'

-- application.css
// in the master application file, we require the imports
*= require app_imports
*= require some_other_stylesheet_like_a_plugin
*= require_self

-- application_admin.css
// in the master admin file, we require the admin imports
*= require admin_imports
*= require some_other_stylesheet_like_a_plugin
*= require_self


-------- THE LAYOUTS

-- application.html.haml
// in the application layout, we call the master css file
= stylesheet_link_tag "application", media: "all"

--  admin.html.haml
// in the admin layout, we call the admin master css file
= stylesheet_link_tag "application_admin", media: "all"

7

สร้างโครงสร้างโฟลเดอร์ต่อไปนี้:

+ assets
|
--+ base
| |
| --+ mixins (with subfolders as noted in your question)
|
--+ styles
  |
  --+ ...

ในโฟลเดอร์baseสร้างไฟล์ "globals.css.scss" ในไฟล์นี้ให้ประกาศการนำเข้าทั้งหมดของคุณ:

@import 'base/colors';
@import 'base/mixins/...';
@import 'base/mixins/...';

ใน application.css.scss ของคุณคุณควรมี:

*= require_self
*= depends_on ./base/globals.css.scss
*= require_tree ./styles

และในขั้นตอนสุดท้าย (นี่เป็นสิ่งสำคัญ) ให้ประกาศ@import 'base/globals'ในไฟล์สไตล์ทุกรายการที่คุณต้องการใช้ตัวแปรหรือมิกซ์อิน คุณอาจพิจารณาค่าใช้จ่ายนี้ แต่ฉันชอบความคิดที่ว่าคุณต้องประกาศการอ้างอิงของสไตล์ของคุณในทุกไฟล์ แน่นอนว่าสิ่งสำคัญคือคุณต้องนำเข้ามิกซ์อินและตัวแปรใน globals.css.scss เท่านั้นเนื่องจากไม่ได้เพิ่มคำจำกัดความของสไตล์ มิฉะนั้นคำจำกัดความของสไตล์จะรวมหลายครั้งในไฟล์ที่คอมไพล์ล่วงหน้าของคุณ ...


ฉันลองใช้แล้ว แต่ไม่สามารถทำงานได้อย่างถูกต้อง (ยังคงได้รับข้อผิดพลาดของตัวแปรที่หายไป) บางทีฉันอาจจะทำบางอย่างไม่ถูกต้อง แต่ฉันคิดว่าในที่สุดวิธีการแสดงรายการแต่ละไฟล์ด้วยตนเองเป็นวิธีที่ถูกต้องเนื่องจากคำสั่ง CSS มีความสำคัญ
David Savage

คุณยังคงใช้แนวทางนี้ได้: แทนที่จะใช้ "require_tree ... " เพียงแค่เพิ่มบรรทัดสำหรับแต่ละไฟล์ สิ่งนี้จะทำให้ SASS นำเข้าไฟล์ตามลำดับที่ถูกต้อง เกี่ยวกับวิธีแก้ปัญหาที่คุณใช้อยู่ในตอนนี้โปรดดูที่โพสต์นี้ที่ฉันเพิ่งพบ: stackoverflow.com/questions/7046495/…ตรวจสอบให้แน่ใจว่าได้ใส่คำสั่งที่ขึ้นอยู่กับในไฟล์ application.css ของคุณ
emrass

4

ตามคำถามนี้คุณสามารถเท่านั้นใช้application.css.sassเพื่อกำหนดการนำเข้าและส่วนแบ่งตัวแปรระหว่างแม่แบบของคุณ

=> ดูเหมือนจะเป็นเพียงเรื่องของชื่อเท่านั้น

อีกวิธีหนึ่งคือรวมทุกอย่างและปิดการใช้งานไปป์ไลน์นี้


โดยพื้นฐานแล้วนี่เป็นสิ่งเดียวกับที่ Benjamin Udink ten Cate เสนอในส่วนที่สองของคำตอบของคุณ แต่การให้รางวัลแก่เขาเนื่องจากวิธีแก้ปัญหาของเขามีคำอธิบายมากกว่า
David Savage

1

ฉันมีปัญหาที่คล้ายกันมาก สิ่งที่ช่วยฉันคือใส่ขีดล่างของคำสั่ง @import เมื่อนำเข้าบางส่วน ดังนั้น

@import "_base";

แทน

@import "base";

อาจจะเป็นบั๊กแปลก ๆ ...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.