Правильная структура активов SCSS в Rails
Итак, у меня есть структура каталогов 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?
К сожалению, этот парень, похоже, не считает возможным, но я надеюсь, что он ошибается. Любые мысли приветствуются.
Ответы
Ответ 1
Проблема с CSS заключается в том, что вы не хотите автоматически добавлять все файлы.
Порядок, в котором ваши листы загружаются и обрабатываются браузером, имеет важное значение. Таким образом, вы всегда будете явно импортировать все свои css.
В качестве примера скажем, что у вас есть normalize.css лист, чтобы получить представление по умолчанию вместо всех ужасных различных реализаций браузера. Это должен быть первый файл, загруженный браузером. Если вы просто произвольно включаете этот лист где-нибудь в свой импорт css, он не только переопределяет стили браузера по умолчанию, но также и любые стили, определенные во всех файлах css, которые были загружены до него. Это одинаково для переменных и mixins.
После просмотра презентации Roy Tomeij в Euruko2012 я решил использовать следующий подход, если у вас есть много CSS для управления.
Обычно я использую этот подход:
- Переименуйте все существующие .css файлы в .scss
- Удалить все содержимое из application.scss
Начните добавлять директивы @import в application.scss
.
Если вы используете бутстрап для twitters и несколько собственных css-листов, вам сначала нужно импортировать bootstrap, потому что у него есть лист для стилей reset.
Поэтому вы добавляете @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
. Из-за заказа на импорт вы также можете использовать любые загрузочные микшины и переменные в ваших собственных файлах scss.
Единственным недостатком этого метода, который я нашел до сих пор, является то, что иногда приходится перекомпилировать частичные /*. scss файлы, потому что рельсы обычно не делают это за вас.
Ответ 2
Создайте следующую структуру папок:
+ 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'
в каждом файле стиля, где вы хотите использовать переменные или mixins. Вы можете подумать об этих накладных расходах, но мне действительно нравится идея, что вы должны объявлять зависимости ваших стилей в каждом файле. Конечно, важно, чтобы вы импортировали mixins и переменные в globals.css.scss, поскольку они не добавляют определения стилей. В противном случае определения стиля будут включены несколько раз в ваш предварительно скомпилированный файл...
Ответ 3
для использования переменных и таких файлов, вам необходимо использовать директиву @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", media: "all"
Ответ 4
В соответствии с этим вопросом вы можете ТОЛЬКО использовать application.css.sass
, чтобы определять импорт и обменивать переменные между вашими шаблонами.
= > Кажется, это только вопрос имени.
Другим способом может быть включить все и отключить этот конвейер.
Ответ 5
У меня была очень похожая проблема. То, что помогло мне, заключалось в том, чтобы подставить подчеркивание в оператор @import при импорте частичного. Так
@import "_base";
вместо
@import "base";
Это может быть странная ошибка...