Задать вопрос

Проблемы реализации подхода БЭМ с Sass 3.1.8?

По идеологии БЭМ стоит по возможности отказываться от наследования в css (так как это медленно и опасно, скажем так). Т.е вместо

.block{}
  .block .header{}
  .block .content{}


Следует писать так

.block{}
  .block_header{}
  .block_content{}


Для верстки используем compass основанный на sass. Раньше БЭМ легко реализовывался через sass c помощью & (sass подставлял родительский селектор на место амперсанда):

.block
  &_header
  &_content


Преобразовывался в нужный нам

.block{}
  .block_header{}
  .block_content{}


Но начиная с версии sass 3.1.8 амперсанд подставляет родительский селектор, только в валидное выражение.
Deprecate parent selectors followed immediately by identifiers (e.g. &foo). This should never have worked, since it violates the rule of & only being usable where an element selector would.


Следствием этого является то, что, видя конструкцию &_header, sass ставит пробел после амперсанда и мы получаем на выходе нерабочее правило:

.block _header{}

Внимание вопрос: если кто сталкивался, было ли найдено решение, кроме как сидеть на старой версии sass, либо повторять все имена родительских селекторов вручную?
  • Вопрос задан
  • 6266 просмотров
Подписаться 6 Оценить 2 комментария
Пригласить эксперта
Ответы на вопрос 2
aishek
@aishek
Не знаю, насколько это ещё актуально :)

Делаете initializer с вот таким кодом:

Rails.application.config.after_initialize do |app|
  app.assets.register_postprocessor 'text/css', :sass_bem_class_builder do |context, data|
    data.gsub(/([a-zA-Z0-9\-]+)[ ]([_]+)/i){ $1 + $2 }
  end
end
Ответ написан
@avrelian
Можно определить специальную переменную, в которой хранить селектор родителя, к примеру $_:
$_: '.block';
#{$_} { color: #111; }
  #{$_}_header { color: #222; }
  #{$_}_content { color: #333; }

$_: '.another';
#{$_}  { color: #444; }
  #{$_}_header { color: #555; }
  #{$_}_content { color: #666; }


Вот что выдает парсер Sass:
.block {
  width: 100px; }

.block_header {
  width: 200px; }

.block_content {
  width: 300px; }

.another {
  width: 100px; }

.another_header {
  width: 200px; }

.another_content {
  width: 300px; }
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы