Cấu trúc nội dung SCSS thích hợp trong Rails


86

Vì vậy, tôi có một app/assets/stylesheets/cấu trúc thư mục trông giống như sau:

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

Trong mỗi thư mục, có nhiều phần chia sass (thường là * .css.scss, nhưng một hoặc hai * .css.scss.erb).

Tôi có thể giả định rất nhiều, nhưng rails NÊN tự động biên dịch tất cả các tệp trong các thư mục đó vì *= require_tree .trong application.css, phải không?

Gần đây tôi đã thử cấu trúc lại các tệp này bằng cách loại bỏ tất cả các biến màu và đặt chúng vào một tệp trong app/assets/stylesheetsthư mục gốc (_colors.css.scss). Sau đó, tôi đã tạo một tệp trong app/assets/stylesheetsthư mục gốc có tên là master.css.scss trông giống như sau:

// 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";

Tôi không thực sự hiểu cách rails xử lý thứ tự biên dịch nội dung, nhưng rõ ràng là nó không có lợi cho tôi. Có vẻ như không có tệp nào nhận ra rằng chúng có bất kỳ biến hoặc hỗn hợp nào đang được nhập, và do đó, nó tạo ra lỗi và tôi không thể biên dịch.

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)

Biến $dialog_divider_color được xác định rõ ràng trong _colors.css.scss và _master.css.scssđang nhập màu và tất cả các mixin của tôi. Nhưng rõ ràng rails đã không nhận được bản ghi nhớ đó.

Có cách nào để tôi có thể sửa những lỗi này không hoặc tôi sẽ cần dùng đến việc đưa tất cả các định nghĩa biến của mình trở lại từng tệp riêng lẻ, cũng như tất cả các lần nhập mixin?

Thật không may, anh chàng này dường như không nghĩ là có thể, nhưng tôi hy vọng anh ta đã sai. Ý kiến ​​nào cũng được hoan nghênh.

Câu trả lời:


126

Vấn đề với CSS là bạn không muốn tự động thêm tất cả các tệp. Thứ tự các trang tính của bạn được tải và xử lý bởi trình duyệt là điều cần thiết. Vì vậy, bạn sẽ luôn kết thúc nhập tất cả css của mình một cách rõ ràng.

Ví dụ, giả sử bạn có normalize.css trang tính , để có giao diện mặc định thay vì tất cả các triển khai trình duyệt khác nhau khủng khiếp. Đây sẽ là tệp đầu tiên mà trình duyệt tải. Nếu bạn chỉ ngẫu nhiên bao gồm trang tính này ở đâu đó trong các lần nhập css của mình, thì nó sẽ không chỉ ghi đè các kiểu mặc định của trình duyệt mà còn cả bất kỳ kiểu nào được xác định trong tất cả các tệp css đã được tải trước đó. Điều này cũng xảy ra tương tự đối với các biến và mixin.

Sau khi xem bài thuyết trình của Roy Tomeij tại Euruko2012, tôi đã quyết định chọn cách tiếp cận sau nếu bạn có nhiều CSS cần quản lý.

Tôi thường sử dụng phương pháp này:

  1. Đổi tên tất cả các tệp .css hiện có thành .scss
  2. Xóa tất cả nội dung khỏi application.scss

Bắt đầu thêm chỉ thị @import vào application.scss.

Nếu bạn đang sử dụng twitters bootstrap và một vài trang css của riêng mình, trước tiên bạn phải nhập bootstrap, vì nó có một trang để đặt lại kiểu. Vì vậy, bạn thêm @import "bootstrap/bootstrap.scss";vào của bạn application.scss.

Tệp bootstrap.scss trông giống như sau:

// 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.scsstệp của bạn trông giống như:

@import "bootstrap/bootstrap.scss";

Do thứ tự của các lần nhập, bây giờ bạn có thể sử dụng các biến, được tải @import "variables.scss";trong bất kỳ .scsstệp nào khác được nhập sau nó. Vì vậy, chúng có thể được sử dụng trong type.scssthư mục bootstrap mà còn trong my_model.css.scss.

Sau đó, tạo một thư mục có tên partialshoặc modules. Đây sẽ là nơi chứa hầu hết các tệp khác. Bạn chỉ có thể thêm nhập vào application.scsstệp để tệp sẽ giống như sau:

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

Bây giờ nếu bạn thực hiện một chút css để tạo kiểu cho một bài viết trên trang chủ của bạn. Chỉ cần tạo partials/_article.scssvà nó sẽ được thêm vào biên dịch application.css. Do thứ tự nhập, bạn cũng có thể sử dụng bất kỳ hỗn hợp và biến bootstrap nào trong các tệp scss của riêng bạn.

Hạn chế duy nhất của phương pháp này mà tôi tìm thấy cho đến nay là, đôi khi bạn phải buộc biên dịch lại một phần tệp / *. Scss vì rails sẽ không làm việc đó cho bạn.


4
Cảm ơn, đây là cách tiếp cận mà tôi đã kết thúc. Tôi ghét giải pháp này vì bạn phải thêm thủ công mọi tệp bạn đưa vào mỗi khi bạn tạo một tệp, nhưng có vẻ như khi có CSS, thứ tự vẫn quan trọng. Thông thường, tôi sẽ nói đó chỉ là cách viết CSS tồi, nhưng nếu bạn đang sử dụng những thứ do nhà cung cấp cung cấp (tức là bootstrap như bạn đã đề cập ở trên), bạn có xu hướng muốn ghi đè lên mọi thứ, vì vậy tôi miễn cưỡng đồng ý rằng đây là cách tiếp cận đúng.
David Savage

1
Cảm ơn! Một cách tiếp cận rất tốt và một lời giải thích tốt! Một dự án đáng để đề cập đến: plugin Firebug này, FireSass , chương trình số dòng của my_model.css.sass thay vì dòng của application.css biên soạn
BBQ Chef

Với cách tiếp cận này, nếu tôi muốn thay đổi màu liên kết mặc định của mình thành màu đỏ áp dụng cho tất cả các phần của tôi, bạn sẽ làm như thế nào? bạn sẽ đặt nó ở đâu?
chh

1
Lưu ý rằng cách tiếp cận này cũng được khuyến nghị trong Hướng dẫn Đường ống Tài sản . Tìm kiếm "Nếu bạn muốn sử dụng nhiều tệp Sass".
ybakos

1
@Lykos vâng bạn xóa mọi thứ khỏi application.cssvà đổi tên nó thành application.scss. Bởi vì require_treebao gồm tất cả mọi thứ chỉ và bạn muốn thường kiểm soát trật tự
Benjamin Udink Ten Cate

8

để sử dụng các biến và các biến tương tự trên các tệp, bạn cần sử dụng chỉ thị @import. các tệp được nhập theo thứ tự được chỉ định.

sau đó, sử dụng application.css để yêu cầu tệp khai báo các lần nhập. đây là cách để đạt được sự kiểm soát bạn muốn.

cuối cùng, trong tệp layout.erb của bạn, bạn có thể chỉ định tệp css "chính" nào sẽ sử dụng

ví dụ sẽ hữu ích hơn:

giả sử bạn có hai mô-đun trong ứng dụng của mình cần các bộ css khác nhau: "application" và "admin"

Tập tài liệu

|-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

đây là những gì các tệp trông giống như bên trong:

-------- 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

Tạo cấu trúc thư mục sau:

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

Trong thư mục, hãy basetạo một tập tin "domains.css.scss". Trong tệp này, hãy khai báo tất cả các lần nhập của bạn:

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

Trong application.css.scss của bạn, bạn sẽ có:

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

Và bước cuối cùng (đây là bước quan trọng), hãy khai báo @import 'base/globals'trong mọi tệp kiểu mà bạn muốn sử dụng biến hoặc mixin. Bạn có thể cân nhắc chi phí này, nhưng tôi thực sự thích ý tưởng rằng bạn phải khai báo sự phụ thuộc của các kiểu của bạn trong mọi tệp. Tất nhiên, điều quan trọng là bạn chỉ nhập các mixin và các biến trong perfals.css.scss vì chúng không thêm định nghĩa kiểu. Nếu không, các định nghĩa kiểu sẽ được đưa vào nhiều lần trong tệp biên dịch trước của bạn ...


Tôi đã thử điều này nhưng không bao giờ có thể làm cho nó hoạt động bình thường (vẫn bị thiếu lỗi biến). Có thể tôi đã làm điều gì đó không chính xác, nhưng tôi nghĩ cuối cùng thì cách tiếp cận liệt kê từng tệp theo cách thủ công là cách phù hợp để đi, vì thứ tự CSS thực sự quan trọng.
David Savage

Bạn vẫn có thể sử dụng phương pháp này: Thay vì "request_tree ...", chỉ cần thêm một dòng cho từng tệp riêng lẻ. Điều này sẽ làm cho SASS nhập các tệp theo đúng thứ tự. Về giải pháp bạn hiện đang sử dụng, vui lòng xem bài đăng mà tôi vừa tìm thấy này: stackoverflow.com/questions/7046495/… Đảm bảo bao gồm chỉ thị phụ thuộc vào tệp application.css của bạn.
emrass

4

Theo câu hỏi này , bạn CHỈ có thể sử dụng application.css.sassđể xác định các biến nhập và chia sẻ giữa các mẫu của mình.

=> Đó dường như chỉ là vấn đề tên gọi.

Một cách khác có thể là bao gồm mọi thứ và vô hiệu hóa đường dẫn này .


Về cơ bản, đây chính là điều mà Benjamin Udink ten Cate đưa ra trong phần thứ hai của câu trả lời của bạn, nhưng việc trao tiền thưởng cho anh ta vì giải pháp của anh ta dễ giải thích hơn.
David Savage

1

Tôi đã có một vấn đề rất giống nhau. Điều đã giúp tôi là đặt dấu gạch dưới vào câu lệnh @import khi nhập một phần. Vì thế

@import "_base";

thay vì

@import "base";

Nó có thể là một lỗi lạ ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.