Abr@X@bra.ru
Как правильно работать с Sass

Как правильно работать с Sass

17.05.2017
239
Написание SASS во вложенном формате является хорошей практикой из-за улучшения организации проекта. Пример:
<div class='component'>
 <div class='component__card'>
   <div class='component__name'>John Doe</div>
   <a class='component__button' href='#'>View Profile</a>
 </div>
 <div class='component__card'>
   <div class='component__name'>Jane Doe</div>
   <a class='component__button' href='#'>View Profile</a>
 </div>
</div>
А вот как выглядит SCSS:
.component {
 padding: 2vw;
 &__card {
   background-color: #FFF;
 }
 &__name {
   color: #000;
 }
 &__button {
   background-color: blue;
   color: #FFF;
 }
}
Вы, наверное, уже знаете, что ampersand (&) является родительским селектором в SASS. Это ссылка для непосредственного родителя элементов. В этом примере & ссылается на .component, потому что это непосредственный родительский элемент. Выходной CSS:
.component {
 padding: 2vw;
}
.component__card {
 background-color: #FFF;
}
.component__name {
 color: #000;
}
.component__button {
 background-color: blue;
 color: #FFF;
}

Я думаю, мы все можем согласиться с тем, что Ampersand & действительно полезен, особенно если вы используете что-то вроде синтаксиса БЭМ. Это позволяет вам легко изменять имена классов в массовом масштабе, если это необходимо, при сохранении структуры CSS ваших компонентов.

Как правильно выбрать дочерние элементы?

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

В нашем примере предположим, что мы хотели изменить цвет .component__name, когда вы наводите курсор на его родителя: .component__card. Мы могли бы попробовать следующее:
.component {
 &__card {
   &:hover &__name {
     color: #BADA55;
   }
 }

 &__name {
   color: #000;
 }
}
На первый взгляд может показаться, что это сработает, но нет:
.component__card:hover .component__card__name {
 color: #BADA55;
}
Ладно, так не получилось. Родительский селектор отлично работает для псевдоклассов, но здесь терпит неудачу, потому что нам нужно выбрать элемент .component, который здесь является прародителем.

Вот такой тип – && был бы хорош, но его просто не существует)

Альтернативный подход заключается в следующем:
.component {
 &__card {
   ...
 }
 &__card:hover &__name {
   color: #BADA55;
 }

 &__name {
   color: #000;
 }
}

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

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

$ Переменные как селекторы

Конечно, вы знаете о переменных в SASS. Это одна из основных причин использования SASS. Это здорово для таких вещей:
$color: #323232;
.copy {
 color: $color;
}
h1 {
 border-bottom: $color;
}

Но знаете ли вы, что можно сделать и вот так?

.component {
 $c: &;      // The class name is in a variable now
}
Как бы вы использовали это? Вы должны использовать синтаксис интерполяции SASS. Это включает в себя перенос переменной в # {}, чтобы вывести ее как строку:
.component {
 $c: &;         // Set the parent as a variable
 padding: 2vw;
 &__card {
   background-color: #FFF;
  
   &:hover #{$c}__name {   // Use the variable here
     color: #BADA55;
   }
 }
 &__name {
   color: #000;
 }
 &__button {
   background-color: blue;
   color: #FFF;
 }
}
А вот результат:
.component {
 padding: 2vw;
}
.component__card {
 background-color: #FFF;
}
.component__card:hover .component__name {
 background-color: #BADA55;
}
.component__name {
 color: #000;
}
.component__button {
 background-color: blue;
 color: #FFF;
}
Отлично! Все получилось, так как мы и задумывали!  Очевидно, вы можете использовать это для любого элемента по дереву.

Что еще нам нужно знать?

Прежде всего, переменные остаются в пределах объявленной ими области. Так что это важно понимать. Данный код, будет работать неправильно:
.component {
 $c: &;
}
#{$c}__name {  // Undefined variable: "$c".

}

Кроме того, если вы не используете & в вложенной структуре, вы можете получить несколько странных селекторов (которые не имеют смысла):
.grid {
 $g: &;
 &__column {
   $c: &;
   color: #000;
 > div {
     #{$g}:hover & {   
       color: red;
     }
     // Result: .grid:hover .grid__column > div
    
     #{$g}:hover #{$c} {
       color: #blue;
     }
     // Result: .grid__column > div .grid:hover .grid__column
   }
 }
}
Это можно решить, используя @ at-root:
.grid {
 $g: &;
&__column {
   $c: &;
   color: #000;
> div {
     #{$g}:hover & {
       color: red;
     }
    
     @at-root {
       #{$g}:hover #{$c} {
         color: #blue;
       }
       // Result: .grid:hover .grid__column
     }
   }
 }
}

Вывод

В этой статье вы узнали, как использовать переменные SASS в качестве родительских селекторов (возможно, их следует называть селекторами-предками ...). Это позволяет вам оставаться в рамках организованного вложенного синтаксиса для лучшей организации и разграничения кода. Если вы можете придумать какие-либо другие интересные способы использования этого подхода, пожалуйста, оставьте комментарий!


SASS, CSS
Читайте также:
3 новых CSS-функции для изучения в 2017 году

3 новых CSS-функции для изучения в 2017 году

В этом посте, поговорить хочу про CSS, а если быть точнее про новые его фишки которые стоить знать.
Читать
PhpStorm, правильная настройка для web-разработки

PhpStorm, правильная настройка для web-разработки

В этом посте хочу поделится своим опытом, как правильно работать с IDE PhpStorm и удаленным web сервером. ...

Читать
Flexbox и как делать адаптивные сайты

Flexbox и как делать адаптивные сайты

Современный front-end разработчик активно должен уметь применять на практике различные инструменты, позволяющи...
Читать