В Rails 3.1 действительно ли невозможно избежать включения дублирующих копий таблиц стилей? - PullRequest
12 голосов
/ 21 июня 2011

Я сталкиваюсь с проблемой, когда пытаюсь обмениваться переменными и миксинами в таблицах стилей Sass.

Если я использую @import для включения глобальной таблицы стилей, включающей глобальные цвета, миксины и т. Д., Она снова включается , когда Rails объединяет все таблицы стилей, указанные в файле манифеста.

В качестве альтернативы, если мой файл манифеста не включает глобальную таблицу стилей, но несколько файлов в манифесте импортируют его, глобальная таблица стилей все же будет включена более одного раза. GAH.

Как вы можете обойти это? У Sass есть секретные охранники включения? Я делаю что-то ужасно неправильно?

Ответы [ 4 ]

7 голосов
/ 22 июня 2011

Я не понимаю, почему это проблема для вашего конкретного вопроса. Переменные и объявления mixin не должны приводить к каким-либо селекторам или блокам объявлений в созданном вами файле css. Однако, когда вы используете mixins для нескольких селекторов, соответствующие объявления включаются для каждого такого селектора. Вот как SASS справляется с этим.

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

Если, однако, у вас также есть селекторы и объявления в базовом файле, от которых вы хотите наследовать в отдельных файлах, то они действительно будут включены несколько раз даже в скомпилированный файл. Было бы еще интересно узнать, как это предотвратить с помощью конфигурации. Однако, если вы рассматриваете каждый из своих файлов sass как один инкапсулированный набор правил без межфайлового наследования, тогда вы сможете предотвратить проблему по соглашению.

Например, при использовании bootstrap-sass, просто , миксины и определения переменных могут быть введены в область действия с помощью

@import "bootstrap/variables";
@import "bootstrap/mixins";
4 голосов
/ 22 июня 2011

Вы можете обойти это, выполнив следующее:

/* 
 * application.css.scss
 *= require_self
 * ----> Note the missing = require_tree 
*/  

@import "global.css.scss"; // Defines global mixins etc
@import "users.css.scss"; // Uses mixins defined in _global.css.scss

Тогда не импорт global.css.scss внутри users.css.scss или любых других зависимых файлов.

Если вы этого еще не сделали, посмотрите скринкаст Райана Бейтса на SASS и звездочки в рельсах 3.1 , это то, что он делает для решения этой проблемы.

1 голос
/ 11 июня 2015

Пока, пока не выпущен SASS 4, я предпочитаю модифицировать строки импорта примерно так:

@if not-imported("font") { @import "font"; }

Вам понадобится функция с именем not-import, тогда, конечно, она будет выглядеть следующим образом:

$imported-once-files: () !default;

@function not-imported($name) {
  $module_index: index($imported-once-files, $name);
  @if (($module_index == null) or ($module_index == false)) {
    $imported-once-files: append($imported-once-files, $name);
    @return true;
  }
  @return false;
}

Это прекрасно работает и поддерживает совместимость с другими инструментами (например, StyleDocco). Я писал об этом, здесь

0 голосов
/ 16 января 2014

В настоящее время невозможно использовать SASS для динамического включения файлов. @import нельзя использовать в директивах управления (например, @if) или миксинах, использование переменной в директиве import является ошибочным синтаксисом, и нет директивы для досрочного завершения выполнения файла (что эффективно позволило бы условный импорт). Однако вы можете решить свою проблему, изменив структуру правил вашего стиля.

Примечание

Существует плагин SASS , который изменит @import только включите файлы один раз. Тем не менее,

  1. Ваш код будет иметь дополнительную зависимость от среды
  2. Нам всем лучше понять, как правила стилей предназначены для структурирования, что позволит избежать дублирования правил.
  3. @import может быть скоро устарело . Команда SASS планирует « масштабная модернизация импорта », поэтому защита от повторного импорта может быть частью будущих версий SASS, так как она популярна запрашиваемая функция.

Решение

Если у вас есть стили, которые условно включены из нескольких файлов, они не являются «глобальными» стилями. Эти стили должны быть заключены в миксины, в файлы 'module' или 'library'. Основная идея заключается в том, что , импортирующий один такой файл, не будет выводить никакой CSS Таким образом, вы можете импортировать эти файлы избыточно, чтобы использовать миксины там, где они вам нужны.

Если вам нужно сделать это с переменными , тогда:

  1. Убедитесь, что вы определили переменные, прежде чем включать миксины, в противном случае они доступны только в миксине scope . Хороший способ сделать это - определить все переменные по умолчанию в файле vars.sass и импортировать его вместе с импортированными модулями / библиотеками, чтобы переменные были доступны глобально.
  2. Определите переменные, используя !default в mixin, чтобы его можно было переопределить даже до вызова mixin (как в файле vars.sass).

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

$was-defined: () !default;
@mixin define-once($name) {
    @if not index($was-defined, $name) {
        $was-defined: append($was-defined, $name);
        @content;
    }
}

// Example:
@include define-once('body-typography') {
    body {
        font-size: 100%;
        line-height: 2em;
        color: #444;
        font-family: monospace;
    }
}

Чтобы получить более полезные рекомендации по структурированию вашего кода, ознакомьтесь с этой статьей .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...