Привет, Хабр!
Общаясь с коллегами, я заметил, что они незнакомы с последними возможностями CSS. Как обычно, у всех свои причины. У кого-то много повседневной рутины. Кому-то в принципе неинтересно, что нового происходит в CSS. А кто-то по привычке использует подходы десятилетней давности и ему норм.
Как фанату CSS, мне грустно. Сколько же прикольных вещей проходит мимо них. Да и их код может быть меньше, надёжнее и проще для понимания. В общем, я собрал несколько фрагментов кода, которые были популярны давным-давно, и переписал их с помощью новых возможностей CSS.
Давайте посмотрим, что я вам подготовил.
▍ Центрирование элемента с помощью свойства transform и значения translate(-50%, 50%)
Центрирование элементов всегда было камнем преткновения. Очень долго не было простого способа реализовать эту задачу. Даже на собеседованиях всегда спрашивали: «Как можно отцентрировать элемент со свойством position и значением absolute по двум осям?».
Потом появилось свойство transform, и все массово стали его использовать.
.parent { position: relative; } .parent::before { content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
Расскажу, что тут происходит. Сначала происходит смещение элемента с помощью свойств top и left. Важно помнить, что браузеры перемещают верхний левый угол. В итоге мы получим, что он будет находиться по центру родительского элемента.
А нам нужно, чтобы в центре была середина элемента. Для этого надо сместить его в противоположную сторону на половину ширины и высоты. Тут и помогает свойство transform.
Если для него задать значение в процентах, то итоговое значение смещения браузеры будут вычислять относительно свойств width и height. В результате мы увидим, как элемент сместится в центр родительского элемента.
Сегодня уже можно сделать проще. Нам больше не надо смещать элементы с помощью свойств top и left, а следовательно, и свойства transform. Значение center для свойства place-items сразу сделает всю магию.
.parent { display: grid; place-items: center; } .parent::before { content: ""; position: absolute; }
Также не надо добавлять свойство position со значением relative. Поскольку свойств top и left больше нет.
▍ Стилизация элементов на основе селекторов + или ~
Представим, что перед нами поставили задачу реализовать появление подсказки для поля ввода пароля. Когда пользователь ввёл пароль, который удовлетворяет требованиям, она должна будет исчезнуть.
С требованиями жестить не будем. Пусть минимальная длина пароля должна быть минимум четыре символа.
<body> <!-- встроенная валидация отключена, потому что чаще всего её реализуют самостоятельно --> <form class="form" novalidate> <!-- другие элементы --> <div class="field"> <label class="field__label" for="password">Пароль</label> <input class="field__input" id="password" type="password" minlength="4" required> <span class="field__hint">Пароль должен быть больше 3 символов</span> </div> <!-- другие элементы --> </form> </body>
Исчезновение подсказки будем реализовывать через свойство display. Будем его добавлять со значением none к элементу с классом .field__hint, если пользователь ввёл четыре и более символов.
В разметке нужный элемент находится после поля для ввода, значит, тут надо использовать селектор + или ~.
.field__input:valid + .field__hint { display: none; }
Только этот способ всегда вызывал проблемы. Кто-то случайно поменял порядок элементов, и код отваливался. Сегодня это можно побороть, заменив этот подход на решение с использованием псевдо-класса :has.
.field:has(.field__input:valid) .field__hint { display: none; }
Теперь наш код фиг сломаешь. Ему всё равно на то, как располагаются элементы в разметке. Больше не будет неожиданных ошибок!
▍ Объявление стека системных шрифтов
В комментариях под статьёй «Как фронтендеру сделать интерфейс дружелюбнее к пользователю. Коллекция HTML/CSS лайфхаков» я нашёл код с использованием ключевого слова system-ui, когда его поддержкой была неидеальной. Этот комментарий помог мне вспомнить, что раньше был подход использования системных шрифтов.
Суть заключалась в том, что указывались все семейства шрифтов, которые используются в операционных системах по умолчанию. Назвали такой подход «System Font Stack». Было несколько вариантов реализации.
/* реализация Github */ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; }
/* реализация Medium */ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue",sans-serif; }
Сегодня поддержка ключевого слова system-ui позволяет нам отказаться от этих фрагментов кода. Оно же само говорит браузерам использовать системный шрифт. Больше подсказки не нужны!
Нам осталось просто добавить его в качестве единственного значения для свойства font-family.
body { font-family: system-ui; }
Такой код пишу я. Но если вы хотите, можно добавить вторым значением sans-serif. Вдруг вам покажется такой код ненадёжным.
▍ Установка размеров с помощью свойств width и height для элементов с position: absolute или position: fixed
Несколько недель назад я проверил, сможет ли ChatGPT заменить меня. Одной из задач было сверстать модальное окно. Далее покажу, какой код написал ChatGPT для его стилизации.
.modal { display: none; width: 100%; height: 100%; position: fixed; top: 0; left: 0; z-index: 1000; justify-content: center; align-items: center; background-color: rgba(0, 0, 0, 0.5); }
Обращу внимание на свойства top, left, width и height. Браузеры, обработав их, расположат элемент в левом верхнем углу, растянув на всё пространство по ширине и высоте.
Супер решение, которое я лично использовал десять лет. Но его можно сократить до одной строки. Задайте значение 0 для свойства inset.
.modal { display: none; position: fixed; inset: 0; z-index: 1000; justify-content: center; align-items: center; background-color: rgba(0, 0, 0, 0.5); }
Ещё раз скажу, что в первом решении нет проблем. Просто второе короче. Мне кажется, чем меньше кода, тем лучше.
А также вы можете использовать свойство inset для случаев, когда используется значение absolute.
.awesome-block { position: absolute; inset: 0; background-color: rgba(0, 0, 0, 0.5); }
▍ Объявление значения для свойств margin и padding вместе со значением 0
Проводя код-ревью, я всё ещё замечаю старый подход к объявлению свойств margin и padding. Если требуется установить значение только по одной оси, разработчики вынужденно используют значение 0.
.awesome-block { margin: 0 auto; padding: 1rem 0 2rem; }
Уже не надо так делать. Есть логические CSS-свойства. Они позволяют установить отступ только по оси.
.awesome-block { margin-inline: auto; padding-block: 1rem 2rem; }
Есть стереотип, что логические свойства в этой задаче могут привести к ошибке. Если поменяется направление текста, то вёрстка поедет.
Да, логические свойства зависят от основного направления текста, которое задаётся свойством writing-mode. Но ошибка может произойти, только если вы будете использовать значения vertical-lr или vertical-rl. А это вряд ли случится — если только вы делаете интерфейс для азиатской аудитории, например, японской.
Если же вы поддерживаете японский язык, то уже точно знаете, где могут быть проблемы. И скорее всего, используете логические свойства массово. В других случаях никто не поменяет направление текста так, чтобы были проблемы.
▍ Установка ширины блочного элемента с использованием свойства display
У меня к вам вопрос: «Как можно сделать так, чтобы браузеры рассчитывали ширину блочного элемента по контенту?».
<body> <div class="awesome-block"> <span>Блочный элемент с текстом</span> </div> </body>
.awesome-block { padding: 0.5rem; background-color: lightblue; /* что ещё тут нужно дописать? */ }

Скорее всего, вы вспомните, что можно поменять значение свойства display на inline-block, inline-flex или inline-grid. И вы будете правы.
.awesome-block { padding: 0.5rem; background-color: lightblue; display: inline-grid; }
Без вопросов, это проверенный временем способ. Но он не всегда сработает, потому что не всегда можно менять значение свойства display. Лучше использовать ключевое слово fit-content.
Я сразу перейду к нашему примеру и добавлю свойство width со значением fit-content для элемента с классом .awesome-block.
.awesome-block { padding: 0.5rem; background-color: lightblue; width: fit-content; }
А главный плюс нового решения заключается в том, что элементы сохранят своё расположение. Например, в случае с блочными элементами они продолжат располагаться в столбец. В первом решении такого не было бы.
▍ Расположение элементов в столбец с помощью свойства flex-direction со значением column
Давайте решим простую задачу. Нам нужно расположить несколько элементов друг под другом и задать между ними отступ. А-ля блок с карточками новостей. Сразу скажу, что мы исключаем решение с блочными элементами и свойством margin для отступов.
Часто я встречаю, что разработчики используют свойство flex-direction и gap.
.container { display: flex; flex-direction: column; gap: 1rem; }
У меня всегда в голове вопрос: «Зачем?». Можно же просто использовать значение grid для свойства display.
.container { display: grid; gap: 1rem; }
Это вполне рабочий приём. Так что если вам нужно расположить два элемента в столбец с отступами, то имейте в виду это решение.
▍ Заключение
Вот и всё. Я постарался показать альтернативные подходы и их плюсы. Не знаю, получилось ли хорошо, но в любом случае надеюсь, что вы нашли что-то новое для себя и захотели это использовать в своём коде.
Обязательно напишите, что я упустил, написал не так и в чём не прав. Для этого есть комментарии. А я их читаю.
Спасибо за чтение!
P.S. Помогаю больше узнать про CSS в своём ТГ-канале CSS isn’t magic. Присоединяйтесь. Ссылка в профиле.
© 2025 ООО «МТ ФИНАНС»
Telegram-канал со скидками, розыгрышами призов и новостями IT 💻
ссылка на оригинал статьи https://habr.com/ru/articles/917204/

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