Кешируем селекторы здесь и сейчас

Кешируем селекторы здесь и сейчас

Будни верстальщика
https://tittleforparents.com/blog/top-five-parenting-mistakes/

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

Конечно же приверженцы БЭМ скажут: модификатор ставь. И закроют вопрос.

.button {}
.button--menu {}
.button--dropdown {}
.button--label {}

Эээ, погодите… не всем нравится БЭМ, не все хотят лишние классы к элементам добавлять, давайте просто применим контекстный селектор! 

.menu .button {}
.dropdown .button {}
.label .button {}

В общем, предстоит вам распихать каскадов по всем файлам родительских компонентов. Ну или как минимум положить это всё в самый низ файла стилей самой кнопки, чтобы не искать потом где определили.

Самое время вспомнить о родительском селекторе в SCSS: &. Следующая конструкция развернётся именно в то, что нам нужно:

.button {
  .menu & {}
  .dropdown & {}
  .label & {}
}

А знаете, что мы можем сделать на CSS-in-JS решениях вроде Styled Components, Emotion и идентичных? Мы можем обратиться прямо к компоненту-родителю из компонента-ребёнка! Ровно таким же образом, как в SCSS, но без обращения к классам (они всё равно будут сгенерированы). И не то чтоб я прямо топил за такой подход, но иногда это довольно таки удобно:

import {Menu} from ‘../Menu’;
import {Dropdown} from ‘../Dropdown’;

const Button = styled.button`
  border: 1px solid darkgreen;
  background: darkkhaki;

  ${Menu} & {
    border: none;
    background: transparent;
  }

  ${Dropdown} & {
    text-indent: -9999px;

    &::after {
      // create some arrow maybe
    }
}`;

В чём тут выгода? Очевидно, теперь компонент кнопки хранит все свои возможные состояния, вам не нужно запоминать, где и во что кнопка может превратиться.

Кнопка плохой пример? Окей, есть иконки. С иконками подобное представить будет легче: иконка в кнопке, в ссылке, в лейбле, в поле ввода, в меню…

В SCSS есть ещё один интересный трюк: кеширование родительского селектора. Правда, область видимости останется той же и финта ушами с объединением состояний компонента не выйдет, но это всё равно весьма мощная вещь:

.menu {
  display: flex;
  padding: 0;
  list-style: none;
  
  $this: &; // кешируем

  &__item {
    margin: 0 4px 0 0;
  }

  &__link {
    display: block;
    padding: 4px 8px;
    text-decoration: none;

    &:hover,
    #{$this}__item--active & { // используем
      background-color: $gray-very-light;
    }
  }
}

Здесь мы взяли родительский селектор и использовали его для изменения цвета наведённой ссылки активного пункта меню. Превратится эта вся конструкция в следующее:

...
.menu__item--active .menu__link {
...

Как видим, хоть до внедрения родительских и обратных селекторов в CSS ещё далеко, но это не значит, что мы не можем себе немного облегчить зрительную нагрузку уже сейчас.

Report Page