Правильная структура активов SCSS в Rails - PullRequest
81 голосов
/ 04 февраля 2012

Итак, у меня есть структура каталогов app/assets/stylesheets/, которая выглядит примерно так:

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

В каждом каталоге есть несколько паролей sass (обычно * .css.scss, но один или два *)..css.scss.erb).

Я мог бы предположить много, но rails ДОЛЖЕН автоматически компилировать все файлы в этих каталогах из-за *= 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";

Я не совсем понимаю, как rails обрабатывает порядок компиляции ресурсов, но очевидно, чтоне в мою пользу.Похоже, что ни один из файлов не понимает, что в них импортированы какие-либо переменные или миксины, поэтому он выдает ошибки, и я не могу скомпилировать.

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 импортирует цвета и все мои миксины.Но, очевидно, rails не получил эту заметку.

Есть ли какой-нибудь способ, которым я могу исправить эти ошибки, или мне придется прибегнуть к тому, чтобы поместить все мои определения переменных обратно в каждый отдельный файл, а также весь миксин?импорт?

К сожалению, этот парень , кажется, не думает, что это возможно, но я надеюсь, что он неправ.Любые мысли с благодарностью.

Ответы [ 5 ]

122 голосов
/ 12 февраля 2012

Проблема с CSS в том, что вы не хотите автоматически добавлять все файлы.Порядок, в котором ваши листы загружаются и обрабатываются браузером, имеет важное значение.Таким образом, вы всегда будете явно импортировать все свои CSS.

В качестве примера, скажем, у вас есть лист normalize.css , чтобы получить внешний вид по умолчанию вместо всех ужасных различных реализаций браузера.Это должен быть первый файл, загружаемый браузером.Если вы просто случайно включите этот лист где-нибудь в свой импорт CSS, то он будет не только переопределять стили браузера по умолчанию, но также и любые стили, определенные во всех файлах CSS, которые были загружены до него.То же самое относится и к переменным и миксинам.

После просмотра презентации Роя Томей на Euruko2012 я решил использовать следующий подход, если у вас есть много CSS для управления.

Обычно я использую этот подход:

  1. Переименование всех существующих .css файлов в .scss
  2. Удаление всего содержимого из application.scss

Начните добавлять директивы @import к application.scss.

Если вы используете загрузчик твиттеров и несколько собственных листов CSS, сначала вам нужно импортировать загрузчик, потому что у него есть лист для сброса стилей.Таким образом, вы добавляете @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 в папке начальной загрузки, а также в my_model.css.scss.

. После этого создайте папку с именем partials или modules.Это будет место большинства других файлов.Вы можете просто добавить импорт в файл application.scss, чтобы он выглядел так:

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

Теперь, если вы сделаете немного CSS, чтобы оформить статью на своей домашней странице.Просто создайте partials/_article.scss и он будет добавлен к скомпилированному application.css.Из-за порядка импорта вы также можете использовать любые загрузочные миксины и переменные в своих собственных файлах scss.

Единственный недостаток этого метода, который я обнаружил, заключается в том, что иногда вам приходится принудительно перекомпилировать частичный / *Файлы .scss, потому что рельсы не всегда делают это для вас.

7 голосов
/ 11 ноября 2013

, чтобы использовать переменные и тому подобное в файлах, вам нужно использовать директиву @import. файлы импортируются в указанном порядке.

затем используйте application.css для запроса файла, который объявляет импорт. это способ добиться желаемого контроля.

наконец, в вашем файле layout.erb вы можете указать, какой "главный" файл CSS использовать

пример будет более полезным:

скажем, у вас есть два модуля в вашем приложении, которые нуждаются в разных наборах 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 голосов
/ 08 февраля 2012

Создайте следующую структуру папок:

+ 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, поскольку они не добавляют определения стилей. В противном случае определения стиля будут включены в ваш предварительно скомпилированный файл несколько раз ...

3 голосов
/ 08 февраля 2012

Согласно этому вопросу , вы можете ТОЛЬКО использовать application.css.sass, чтобы определить импорт и обмен переменными между вашими шаблонами.

=> Кажется, это только вопрос имени.

Другим способом может быть включить все и отключить этот конвейер .

1 голос
/ 13 марта 2013

У меня была очень похожая проблема.Что помогло мне, так это вставить подчеркивание в оператор @import при импорте партиала.Так что

@import "_base";

вместо

@import "base";

Это может быть странная ошибка ...

...