Вложения в Sass

Синтаксис

В Sass правила вложения CSS позволяют определить иерархию селекторов:

SCSS

.title {
  strong {}
  em {}
}

Это будет скомпилировано в следующее:

CSS

.title {}
.title strong {}
.title em {}

Поскольку strong и em появляются внутри правила .title (между двух фигурных скобок), то оба они будут начинаться с родительского селектора .title.

Цель вложения

Поскольку приоритет в CSS может оказаться непростым, то при написании селекторов обычно используют специфичность, путём комбинации нескольких классов или тегов, чтобы запретить взаимоисключающие правила CSS.

CSS

.description {}
.description p {}
.description p a {}
.description p a:hover {}
.description p strong {}
.description table {}
.description table tr {}
.description table tr:nth-child(2n) {}
.description table th,
.description table td {}
.description table td.empty,
.description table th.empty {}
.description table th {}

Чтобы предотвратить повторное написание .description давайте использовать вложения:

SCSS

.description {
  p {}
  p a {}
  p a:hover {}
  p strong {}
  table {}
  table tr {}
  table tr:nth-child(2n) {}
  table th,
  table td {}
  table th {}
  table td.empty,
  table th.empty {}
}

Вы можете пойти ещё дальше, заменив р и table для создания вложенных селекторов:

.description {
  p {
    a {
      &:hover {}
    }
    strong {}
  }
  table {
    tr {
      &:nth-child(2n) {}
    }
    th,
    td {
      &.empty {}
    }
    th {}
  }
}

Помните про вложенность в HTML? Отступы в Sass позволяют воспроизвести, как элементы HTML вложены друг в друга.

Обратите внимание, что мы написали table и .empty только один раз в примере.

Будет генерироваться точно такой же CSS, с которого мы начали:

.description {}
.description p {}
.description p a {}
.description p a:hover {}
.description p strong {}
.description table {}
.description table tr {}
.description table tr:nth-child(2n) {}
.description table th,
.description table td {}
.description table td.empty,
.description table th.empty {}
.description table th {}

Амперсанд родительского селектора

Когда вы вкладываете селекторы в Sass, то это в основном добавляет пробел между родительским селектором и его ребёнком. Итак:

// SCSS
.parent {
  .child {}
}
  
// превращается в CSS
.parent .child {}

Пробел между .parent и .child определяет иерархию: этот селектор нацеливается на элементы HTML с class="child" вложенные в class="parent".

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

// SCSS
.parent {
  &:hover {}
  &.other-class {}
}
  
// превращается в CSS
.parent:hover {}
.parent.other-class {}

Обратите внимание, что между .parent и :hover или .other-class нет пробела.

.parent.other-class будет нацелен на элементы HTML, которые содержат class="parent other-class".

Полный пример

CSS

.post-content {}
.post-content a {}
.post-content a:hover {}
.post-content aside {}
.post-content blockquote {}
.post-content code {}
.post-content h3 {}
.post-content h3 a {}
.post-content h4 {}
.post-content h4:before {}
.post-content h4:after {}
.post-content p {}
.post-content p:first-child {}
.post-content p:last-child {}
.post-content ul {}
.post-content ul ul {}
.post-content ul ul ul {}
.post-content dl {}
.post-content dl:before {}
.post-content dl dt {}
.post-content dl dd {}
.post-content pre {}
.post-content pre code {}
.post-content table {}
.post-content table tr {}
.post-content table tr:nth-child(2n) {}
.post-content table th,
.post-content table td {}
.post-content table th {}
.post-content table td.empty,
.post-content table th.empty {}
.post-content table code {}
.post-content table pre {}
.post-content table pre:before {}

SCSS

.post-content {
  a {
    &:hover {}
  }
  aside {}
  blockquote {}
  code {}
  h3 {
    a {}
  }
  h4 {
    &:before {}
    &:after {}
  }
  p {
    &:first-child {}
    &:last-child {}
  }
  ul {
    ul {
      ul {}
    }
  }
  dl {
    &:before {}
    dt {}
    dd {}
  }
  pre {
    code {}
  }
  table {
    tr {
      &:nth-child(2n) {}
    }
    th,
    td {
      &.empty {}
    }
    th {}
    code {}
    pre {
      &:before {}
    }
  }
}

Перейти к заданиям

Автор: Джереми Томас
Последнее изменение: 13.08.2017

См. также