Упрощаем Sass используя амперсанд (&)

Амперсанд (&) - замечательный знак. Это древний символ, лигатура латинского "Et", объединяющий слова, фраз и мысли. В наши дни & получил более широкое применение, но все равно сохраняет свое оригинальное значение "и", "так же, как и", "тоже".

В контексте Sass, & представляет собой ссылку на родительский селектор определяемого блока, что позволяет селектору ссылаться на самого себя внутри определения. Это означает, что псевдоселекторы, одноуровневые селекторы и прочие подобные штуки можно сгруппировать вместе с остальными определениями, использующими данный селектор. & - мощное орудие для организации и расширения Sass.

Псевдоселкторы

У меня в Sass & чаще всего используется с псевдоселекторами: :hover, :active, и :focus в компании с селекторами a или input. Это позволяет определить один блок для <a>, и потом, уже внутри блока ссылаться на родительский селектор при помощи &:hover, &:active и &:focus.

Оригинальный Sass

a {
  color: #0090B2;
  &:hover {
    color: #FF7A00;
  }
  &:active {
    color: #B25500;
  }
}

Получившийся CSS

a {
  color: #0090B2;
}
a:hover {
  color: #FF7A00;
}
a:active {
  color: #B25500;
}

Этим работа с псевдоселекторами не ограничена, :nth-child:target:checked и прочие можно использовать аналогично.

Добавляем класс или идентификатор

Так, как & ссылается на селектор самого верхнего уровня, с его помощью этот селектор можно расширить, добавив класс и/или идентификатор (id). Пусть у нас есть селектор .feature-class и есть html-элемент, у которого этот класс будет использоваться одновременно с классом .style-class, изменяя внешний вид элемента. В этом случае, внутри блока с определением .feature-class у нас бы был блок &.style-class. Sass заменит & на .feature-class и в итоге в сгенерированном CSS мы получим .feature-class.style-class. Для демонстрации, просто обновим предыдущий пример, заменив селектор <a> на селектор класса .featire-class.

Оригинальный Sass

.feature-class {
  color: #0090B2;
  &:hover {
    color: #FF7A00;
  }
  &:active {
    color: #B25500;
  }
  &.style-class {
    color: #00CEFF;
    &:hover {
      color: #0090B2;
    }
    &:active {
      color: #FF7A00;
    }
  }
}

Получившийся CSS

.feature-class {
  color: #0090B2;
}
.feature-class:hover {
  color: #FF7A00;
}
.feature-class:active {
  color: #B25500;
}
.feature-class.style-class {
  color: #00CEFF;
}
.feature-class.style-class:hover {
  color: #0090B2;
}
.feature-class.style-class:active {
  color: #FF7A00;
}

Обратите внимание, что внутри блока с определением &.style-class есть блоки &:hover и &:active, которые позволяют применять псевдоселекторы к элементам с двумя классами, определенными выше. И хотя мы можем идти глубже, как герои фильма "Начало", но когда количество вложенных блоков превышает 4, управлять ими становится сложно.

Родительские селекторы внутри дочерних селекторов

Ключем к пониманию силы амперсадна в Sass является его расположение в определении. В первых двух примерах, & был первым символом, но ниже будут рассмотрены случаи, когда & используется в конце определения. В случаях, когда родиель, содержащий селектор, влияет на изменение стилей дочернего селектора, мы можем ссылаться на родительский селектор внутри блока определения дочернего селектора. Это достигается указанием родительского селектора перед знаком амперсанда в новом блоке определения. То есть, если стили .feature-class необходимо менять, когда этот класс используется внутри элементов с классом .parent-class, мы можем сделать это внутри блока .feature-class.

Оригинальный Sass

.feature-class {
  color: #0090B2;
  .parent-class & {
    color: #00CEFF;
  }
}

Получившийся CSS

.feature-class {
  color: #0090B2;
}
.parent-class .feature-class {
  color: #00CEFF;
}

Эта особенность очень полезна при определении специфичных для Internet Explorer стилей при помощи условных классов <html> тэга. Чтобы добавить любой стиль для IE8 или ниже, просто добавьте .lt-ie9 & внутри блока селектора.

Соседние селекторы

Мой любимый способ использования & - соседние селекторы. Эти типы селекторов используются, когда вам нужно изменить элемент, соответсвующий одному селектору, если он следует сразу же за элементом, соответствующим другому селектору. Чаще всего я использую расположенные рядом соседние селекторы чтобы изменить макет страницы, когда элементы с одинаковым селектором расположены друг за другом, как в случае с параграфами или элементами списка: они чаще всего следуют друг за другом. В простейшем примере, давайте сделаем чтобы у <p> не было отсутпов, но когда два <p> расположены друг за другом, добавим отступ между ними.

Оригинальный Sass

p {
  margin: 0;
  line-height: 1.5em;
  & + & {
    margin-top: 1em;
  }
}

Получившийся CSS

p {
  margin: 0;
  line-height: 1.5em;
}
p + p {
  margin-top: 1em
}

Конечно, когда дело касатеся соседних селекторов, никто не заставляет использовать один и тот же селектор. Предположим, вы не хотите иметь отступ после <h1>, за исключением случаев, когда за ним следует соответствующий подзаголовок.

Оригинальный Sass

h1, h2, h3 {
  margin: 0;
}

h1 {
  & + h2 {
    margin-top: 1em;
  }
}

Получившийся CSS

h1, h2, h3 {
  margin: 0;
}

h1 + h2 {
  margin-top: 1em;
}

Аналогично, комбинации соседних и дочерних селекторов можно использовать для написания соответствующих стилей, заменив + на ~ и > соответственно.

Выводы

Очевидно, что мы только начали постигать силу & в Sass. Намного большего можно достичь комбинируя описанные выше методы использования &. Возмжно, возникнет ситуация, когда вам будет необходимо выбрать соседний с селектором элемент, но только когда у него есть определенный родитель (т.е. .parent-class & + sibling-class). Сейчас же, вы можете поднять & на уровень выше, используя его совместно с миксинами и расшерениями, получая полезный код, вас ничего не ограничивает. 

Источник