24.09.2021

Вложенность CSS, специфика и вы

Вложенность CSS, специфичность и вы

От создателя: вложенность CSS скоро появится в браузерах. С помощью вложенности, с которой вы, может быть, знакомы по Sass или Less, вы сможете значительно сократить количество повторяющихся селекторов. Но вы также сможете загнать себя в угол, если не будете аккуратны. Это обзор того, как вы уже сможете использовать ее сегодня, подводных камней и того, как их избежать.

Как смотрится вложенность CSS?

Если вы работали в Sass либо Less, возможно, вы знакомы с вложенностью, которая смотрится следующим образом:

CSS

Тот же самый блок, написанный с помощью вложенного CSS, смотрится так:

CSS

Вы увидели & перед p? Это «селектор вложенности», который докладывает браузеру, что вы хотите вложить p в div. Вы сможете добавить селектор вложенности только в начале. У нас также есть такая возвожность в Sass, но это необходимо только тогда, когда вы хотите добавить что-то в предшествующий селектор, например, класс:

CSS

И это на самом деле точно так же, как и при вложении собственного CSS. Думайте об этом так, как как будто & просто необходим для каждого селектора. Помните, что в CSS, & всегда на первом месте.

Сейчас есть способ разместить & где-нибудь еще, и это благодаря правилу вложенности @nest. Добавив к селектору префикс @nest, вы сможете выбрать, где вы хотите разместить селектор.

CSS

В приведенном выше коде вы не придаете секции красноватый цвет, но вы создаете новый селектор section div (& заменяется селектором над ним), который имеет стиль css.

Вы сможете добавлять селекторы вложенности только после вашего обыденного CSS. Любые свойства CSS после селектора вложенности будут проигнорированы. Таким образом, последующее неверно:

CSS

В конце концов, вы также можете вкладывать медиа-запросы, убедившись, что вы используете селектор вложенности для перезапуска блока «набора правил».

CSS

Как и ранее, & будет заменен родительским селектором, потому приведенный выше код будет тем же CSS, что и этот:

CSS

Используем вложенность сейчас с postcss-preset-env

Вложенность CSS еще не поддерживается во всех браузерах, но если вы используете PostCSS, вы сможете установить плагин PostCSS Preset Env, и PostCSS конвертирует вложенный CSS в CSS, который сейчас понятен браузерам.

Чтобы использовать PostCSS, вам пригодится этап сборки, например, с помощью Webpack, Parcel либо Gulp. Вы можете найти обзор опций в документации PostCSS по использованию, так что изберите тот, который вам подходит.

Чтоб поиграть с предустановленным Env PostCSS, посетите их площадку, которая компилирует код на лету.

Обычный способ начать работу с postcss-preset-env в вашем проекте — использовать интерфейс командной строчки, установив PostCSS CLI и postcss-preset-env:

JavaScript

И сделаем файл postcss.config.js, который смотрится так:

JavaScript

Потом запустите postcss в терминале из той же папки, что и ваш файл конфигурации.

JavaScript

Вот как вы сможете использовать это сегодня, но когда вы это делаете, есть кое-что, о чем необходимо знать, и это специфичность.

Специфика: большая ловушка

Чтобы осознать, что здесь происходит, я должен признать, что в приведенных выше примерах вложенности я сделал вещи незначительно проще, чем они есть на самом деле. Браузер оборачивает селектор is() вокруг хоть какого родительского селектора, и в этом есть своя специфика.

Селектор is()

Если вы не знакомы с ним (он относительно новый) — селектор is() позволяет вам обернуть кучу различных селекторов, чтобы предотвратить дублирование:

CSS

Два примера дают один и тот же итог, но обратите внимание, что во втором примере мы написали «main» только один раз, тогда как в первом примере нам пришлось написать его три раза. Когда дело доходит до специфики, селектор :is() получает свою специфичность от самого определенного элемента в перечне.

Незнакомы со специфичностью?

Если элементу задано несколько селекторов, браузер употребляет специфичнось селектора, чтобы определить, какой стиль применить. Каждый селектор имеет специфика, которая определяется тем, что вы используете в этом селекторе: элементы, идентификаторы, классы и т. д.

Обычно это смотрится как три корзины, вот так: 1.2.3. 1-ая — это количество идентификаторов, вторая — количество классов, псевдоклассов и селекторов атрибутов, а последняя содержит элементы и псевдоэлементы.

Одно значение на более высочайшем уровне важнее, чем все уровни ниже него. К примеру, у вас может быть один селектор с 1000 именами классов и один селектор с одним идентификатором, последний все равно будет более определенный.

Если вы желаете лучше почувствовать специфичность, я построил калькулятор специфики CSS, который поддерживает селекторы вплоть до уровня 5. Введите свои селекторы и поглядите, какой специфичностью они обладают.

Вернемся к селектору :is()

В нашем примере :is(h1, h2, h3) специфика невысока 0.0.1, так как там только элементы. Но для селектора :is(#start, h1) специфика :is() резко возрастает 1.0.0 из-за идентификатора.

Это просто заметить, если вам каждый раз необходимо вводить весь селектор, но круто во вложении то, что вам больше не необходимо этого делать.

К огорчению, это означает, что вы можете получить очень специфичные селекторы CSS и не знать об этом!
К примеру, давайте посмотрим на этот «простой» пример перечня новостей. Поскольку они сами по для себя составляющие, имеет смысл держать их совместно.

CSS

Так как каждый селектор сам по себе смотрится так просто, вы можете продолжать вложение, до этого чем вы узнаете том, что вы смотрите на правило css, которое смотрится так:

CSS

Которое имеет специфику 1.3.4 и перезапишет большая часть других CSS-селекторов, которые вы пишете. Делая так довольно часто, вы обнаружите, что создаете более непростой селектор или добавляете !important где-то, чтоб заставить CSS работать правильно, и к тому времени вы проиграли.

Предупредить проблемы со специфичностью

Очень соблазнительно просто продолжать вложение (это так просто! и вам необходимо так мало печатать!), но чтобы предупредить проблемы со специфичностью, вам нужно ограничить глубину вложенности и вырваться из нее, если это может быть.

Ограничьте вложенность

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

Совершенно ненаучно, но, смотря на мой собственный код, установка лимита на 3, кажется, работает лучше всего. Это позволяет вам определять и стилизовать контейнер верхнего уровня, его дочерние элементы и дочерние от его дочерних частей.

Вырваться из вложенности

Если вы ограничиваете глубину вложенности вы, может быть, также хотите как можно скорее вырваться из вложенности. Думайте о вложенном CSS как о замкнутом наборе стилей, практически как о компоненте. Если один из дочерних частей должен быть их собственным компонентом, запустите новый «контекст» вложенности.

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

main

#intro

.newsitems

div.newsitem

Но так как каждый из них находится в собственном родительском элементе, где вы можете добавить собственный собственный стиль? В их собственном блоке либо вложенном в их родительский блок.

Чтоб сделать это немного понятнее, допустим, в блоке newsitems есть три элемента новостей, и мы желаем, чтобы они были в горизонтальном гибком макете, чтоб элементы располагались рядом.

Для .newsitems мы настроили гибкий макет:

CSS

Чтоб сделать элементы новостей одинаковой ширины, мы можем добавить к ним flex: 1 1 33%, но это имеет смысл только в контексте .newsitems. Мы могли бы использовать .newsitem в другом месте, так как «flex» не является частью стиля для отдельного новостного сообщения. Мы токже можем сделать селектор малость менее специфичным, изменив & .newsitem на & > div.

CSS

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

Возможная проблема заключается в том, что .newsitems > div более специфически, чем .newsitem (0.1.1 против 0.1.0), потому любой стиль в .newsitem будет перезаписан во вложенном селекторе CSS. Обычно это то, что вам необходимо, но не всегда.

Возможный способ обойти это — быть более серьезным в отношении стиля, и есть несколько методов, каждый из которых имеет свои достоинства и недостатки.

Разделение меж стилями макета и стилями компонентов

Пустые родительские элементы

Автономные составляющие стиля

Разделение между стилями макета и стилями компонент

Некоторые CSS используются для определения макета, к примеру, position и flex, в то время как другие употребляются для определения стиля, например, background и font-size. Вы сможете сохранить логику макета во вложенном селекторе, а логику стиля — в селекторе верхнего уровня:

CSS

Сейчас стиль компонента отделен от его макета в родительском компоненте, что делает его более гибким. Это просит определенной дисциплины, и вам придется находить в разных местах в зависимости от того, желаете ли вы изменить макет или стиль.

Держите пустыми родительские элементы

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

CSS

Таким образом, вы всегда стилизуете содержимое компонента (как бы) и используете способности вложения исключительно как средство организации вашего CSS.

Оборотной стороной здесь является то, что это не всегда будет работать, и если те же самые .newsitems также показываются где-то на боковой панели, вы в конечном итоге дублируете все их стили для боковой панели. Несмотря на то что некоторые из них могут отличаться, вы сможете получить дублирование, которого можно было бы избежать.

Автономные составляющие стиля

По сути, это назад, тому когда все ваши стили производятся внутри компонента, и вы используете дополнительные классы для размещения в различных родительских элементах:

CSS

Это сохраняет все совместно, но добавляет сложность использования дополнительных классов в зависимости от того, где расположен ваш компонент, поэтому вы не сможете просто перетащить HTML в другое место DOM.

Какой из этих 3-х работает лучше всего, зависит от того, что вы предпочитаете, и от проекта, над которым вы работаете. Принципиально отметить, что намеренное использование вложенности CSS окупается. При преднамеренном использовании это прекрасный способ упорядочить собственный CSS и уменьшить повторение кода.

Скоро вложенность CSS появится в браузерах!

По материалам webformyself.com

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *