Привет. Я продолжаю рассказывать про неизвестные широкому кругу разработчиков CSS-фишки. Я отбираю их так, чтобы они были полезны в разного рода проектах. Неважно, верстаете ли вы сайт для малого бизнеса или создаёте супермодное React-приложение. Они поддерживаются большинством браузеров. Отдельно отмечу, что я не считаю IE11 современным браузером. По этой причине я не учитывал его.
Сегодня мы рассмотрим:
- как перестать вредить пользователям свойствами
justify-content
иalign-items
; - недавно появившиеся возможности разделять CSS на части и управлять их приоритетом;
- неизвестный нюанс применения псевдо-класса
:nth-child
.
Больше не буду затягивать. Давайте посмотрим, что я вам подготовил.
▍ Как однажды свойства justify-content
и align-items
заблокировали мой экран
Начну сразу с боли. У меня десятидюймовый ноутбук. И постоянно у меня не помещаются модальные окна в экран. Но это ещё мелкая неприятность. Реальная проблема заключается в том, что я не могу их закрыть. А всё почему?
Всегда мысленно говорю «Спасибо» разработчикам, использующим свойства justify-content
и align-items
для центрирования элемента. На примере покажу, что происходит с вашим модальным окном.
У нас будет один родительский элемент, являющийся флекс-контейнером. В него будет вложен элемент с текстом. Такая имитация модального окна с информацией.
<body>
<div class="flex-container">
<div class="flex-item">
<span>Будет ли виден этот текст?</span>
</div>
</div>
</body>
Дочерний элемент с текстом будет отцентрован с помощью свойств justify-content
и align-items
, и у него будет установлена высота больше, чем у родительского элемента.
.flex-container {
box-sizing: border-box;
width: 400px;
height: 300px;
margin: 30px;
border: 2px solid;
overflow: auto;
display: flex;
justify-content: center;
align-items: center;
}
.flex-item {
width: 100px;
height: 110%;
background-image: linear-gradient(to bottom, lightgreen 5%, pink 5% 95%, lightgreen 95%);
}
Поясню, зачем мы сделали так. Когда я открываю сайт со своего ноутбука, то высота модального окна часто больше высоты разрешения моего экрана. По этой причине я вижу полосу прокрутки. В теории не должно быть проблемы. Посмотрим, каким результат будет в браузере.
Часть текста обрезана. Именно так я вижу ваши модальные окна. А закрыть я их не могу, потому что кнопка «Крестик» скрылась за пределы экрана.
По этой причине раньше я советовал использовать метод центрирования на основе ключевого слова auto
для свойства margin
. В этом случае проблем нет. Только если быть честным, этот способ не пользуется популярностью среди разработчиков. Надеюсь, новый подход вам зайдёт. Встречайте, ключевое слово safe
.
Его суть заключается в том, что если флекс-элементы выходят за пределы родителя, то браузеры автоматически подставляют значение start
вместо установленного. Таким образом переполнения не происходит. Мы видим весь контент элемента.
Посмотрим на это поведение в нашем примере. Только сначала добавим ключевое слово safe
для свойств justify-content
и align-items
.
.flex-container {
box-sizing: border-box;
width: 400px;
height: 300px;
margin: 30px;
border: 2px solid;
overflow: auto;
display: flex;
justify-content: safe center;
align-items: safe center;
}
.flex-item {
width: 100px;
height: 110%;
background-image: linear-gradient(to bottom, lightgreen 5%, pink 5% 95%, lightgreen 95%);
}
Теперь текст «Будет ли виден этот текст?» можно прочитать полностью. Так что пользуйтесь на здоровье. Ещё замечу, что с осени этого года ключевое слово поддерживается во всех современных браузерах. А где не поддерживается, то там ничего не cломаетcя. Такие браузеры отобразят страницу так, как будто ключевое слово safe
не использовалось вовсе.
▍ CSS позволяет управлять приоритетом правил
Давайте я проверю вашу осведомлённость недавними нововведениями в CSS. Скажите, пожалуйста, какой цвет текста будет у элемента с классом heading
?
.heading {
color: pink;
}
@layer template {
.heading {
color: red;
}
}
Правильный ответ — pink
. Удивлены? Отлично. Значит, я не зря добавил этот пример в статью. Перед вами CSS-слои, а именно часть кода, начинающаяся с правила @layer
. С помощью неё я сбил вас с толку, потому что я поменял привычное понимание специфичности. Да, CSS-слои такие. Могут немного управлять специфичностью селекторов.
В этой статье я не буду подробно рассказывать про принцип работы правила @layer
. Это отдельная большая тема, в которой можно много что показать. Сегодня мы остановимся на возможностях, открывающихся перед нами. Начнём.
Если у вас есть опыт подключения CSS от готовых библиотек и компонентов, то вы могли столкнуться с неожиданным переопределением стилей. Та самая ситуация, когда открыл страницу, а там всё разъехалось. Приходилось танцевать с четырьмя бубнами.
Люди добавляли !important
, создавали отдельные классы, переписывали CSS. Я вообще соединял !important
с пользовательскими CSS-свойствами. В общем, все изобретали свои «велосипеды».
CSS-слои решают эту проблему. У нас появилась возможность указать приоритет специфичности и присвоить его определённой группе правил. Например, я сделаю так, чтобы у CSS из потусторонних библиотек приоритет был меньше, чем у основного.
@layer libs {
.heading {
color: green;
}
}
.heading {
color: pink;
}
Прикол заключается в том, что неважно, где находится слой. У правил в нём всегда будет более низкий приоритет, чем у правил без слоёв. Так что следующий код идентичен предыдущему.
.heading {
color: pink;
}
@layer libs {
.heading {
color: green;
}
}
В обоих вариант браузер применят значение pink
для свойства color
. Суперклассная штука. Эх, вот бы её лет десять назад. Так, надо вернуться. Ведь я рассказал только половину.
Когда я узнал про слои, мне захотелось раскидать весь код по ним. Конечно, это можно сделать без проблем.
@layer my-awesome-website {
.heading {
color: red;
}
}
@layer external-components {
.heading {
color: green;
}
}
В этом случае браузеры работают со слоями, как с обычными правилами. Кто последний, тот победил. В нашем примере браузеры применят значение green
для свойства color
.
@layer my-awesome-website {
.heading {
color: red;
}
}
@layer external-components {
.heading {
color: green; /* это значение победило */
}
}
Казалось бы, мы снова пришли к тому, что надо контролировать порядок. Только раньше были обычные правила, а теперь CSS-слои.
Спешу успокоить. У нас есть возможность сообщить нужный порядок слоёв с помощью директивы @layer
. Я сразу на примере покажу, как она выглядит.
@layer external-components, my-awesome-website; /* здесь я указываю, в каком порядке будет приоритет слоёв */
@layer my-awesome-website {
.heading {
color: red;
}
}
@layer external-components {
.heading {
color: green;
}
}
Первый слой является с наиболее меньшим приоритетом, а последний — с наивысшим. И неважно, в каком порядке далее в коде они идут. Таким образом, в нашем примере победило значение из слоя my-awesome-website
, потому что мы для него указали наивысший приоритет.
@layer external-components, my-awesome-website;
@layer my-awesome-website {
.heading {
color: red; /* это значение победило */
}
}
@layer external-components {
.heading {
color: green;
}
}
На этом мой краткий обзор закончен. Я считаю, что эта возможность ещё в полной мере не оценена сообществом. CSS-слои — мощнейший инструмент, позволяющий работать с CSS без боли. А вы уже используете их? Если да, поделитесь, пожалуйста, в комментариях вашим опытом.
▍ У нас есть возможность отобрать диапазон элементов
Знаете, я тринадцать лет занимаюсь вёрсткой и постоянно нахожу неизвестные мне нюансы в уже знакомых аспектах. Недавно собирал материал про синтаксис of S
для псевдо-класса :nth-child
. Я использую его уже больше десяти лет. Казалось, что мне всё уже известно про него. И что вы думаете? Я нашёл новый момент для себя.
Сразу перейду к примеру и создам разметку.
<body>
<span class="awesome-box">1</span>
<span class="awesome-box">2</span>
<span class="awesome-box">3</span>
<span class="awesome-box">4</span>
<span class="awesome-box">5</span>
<span class="awesome-box">6</span>
</body>
Как нужно написать стили, чтобы свойство outline
применялось для диапазона элементов? Например, со второго по пятый. Результат должным быть как на изображении.
Месяц назад я не знал, как такое можно сделать без дополнительных классов. За всю свою карьеру в продакшене всегда встречал только это решение. Ладно, не буду больше тянуть. Мы можем использовать комбинацию из псевдо-классов :nth-child
, чтобы добавить свойство outline
со второго по пятый элемент.
.awesome-box:nth-child(n+2):nth-child(-n+5) {
outline: 4px dashed coral;
outline-offset: 5px;
}
Первый псевдо-класс :nth-child(n+2)
создаёт счётчик, работающий на увеличение значения, начиная с двойки. Так создаётся минимальное значение из диапазона. Максимальное же мы получаем с помощью второго псевдо-классе :nth-child(-n+5)
. В нём используется -n
, поэтому счётчик работает на уменьшение значения, начиная с пятёрки.
Браузеры для поиска элементов используют пересекающиеся значения счётчиков. Так они находят со второго по пятый.
▍ Заключение
Давайте подведём итог. В этой статье мы рассмотрели:
- ключевое слово
safe
, которое не позволяет флекс-элементам выйти за пределы флекс-контейнера при использовании свойствjustify-content
иalign-items
; - встроенный в CSS метод управления приоритетом правил;
- использование псевдо-класса
nth-child
для создания диапазона отбора элементов.
Оставляю ссылки на все выпуски:
Также, пожалуйста, напишите в комментариях, какие CSS-фишки вы используете, о которых другие могут не знать. Буду ждать их. Спасибо за чтение!
P.S. Помогаю больше узнать про CSS в своём ТГ-канале CSS isn't magic. Присоединяйтесь. Ссылка в профиле.
Автор: melnik909