![](https://habrastorage.org/webt/9_/-h/h1/9_-hh1gmda89jzynzqofliwqlds.jpeg)
Привет, Хабр.
В начале января 2025 года мне захотелось посмотреть, какие новые фишки CSS стали поддерживаться современными браузерами за прошлый год. Провести некий срез, что уже можно использовать. И тут меня посетила мысль: «А почему бы не поделиться новинками на Хабре?». Вот я и пришёл.
Сразу скажу, что эта статья — краткий обзор появившимся возможностей. Моя цель — уведомить вас. Я не буду закапываться в принцип работы и другие нюансы. По этой причине, пожалуйста, воспринимайте эту статью как список, что можно изучить в 2025 году.
Для составления списка я использовал сайт «Can I Use». Брал те новшества, которые стали «зелёными» в 2024 году. Смотрел последние версии браузеров Chrome, FireFox, Opera, Edge, Safari, iOS Safari, Samsung Internet и Android Browser.
Не буду больше тянуть. Давайте посмотрим, что я вам подготовил.
▍ Значение balance
для свойства text-wrap
Типографика является одним из главных предметов спора, по которому дизайнеры замучают фронтендера. Им же хочется, чтобы текст выглядел красиво. Да ещё на разных экранах. А тут уже возникают проблемы реализации.
Возьмём заголовки. Как сделать так, чтобы текст в них равномерно распределялся? Для пояснения задачи я создал пример.
<body>
<main class="content">
<h1>«Больше никогда не будет такого игрока». Овечкин поразил Америку 874-м голом и рекордом</h1>
<p>Когда казалось, что Александр Овечкин, забив всего один гол в пяти матчах — да и тот в пустые ворота, вновь попал в кризис, капитан «Вашингтона» вернулся — и как! Грандиозно! Ови забил в овертайме в сухом матче, принеся победу «столичным».</p>
</main>
</body>
.content {
box-sizing: border-box;
max-width: 80rem;
padding-inline: 1rem;
margin-inline: auto;
text-align: center;
}
![](https://habrastorage.org/webt/v2/ov/ng/v2ovngcwpo4n5ulfktpdrzscn1m.png)
Получилось так, что последнее слово осталось одиноким в своей строке. Я забыл, как в типографике называется такая ошибка. Вроде «висячие слова». Но я не уверен.
В общем это поведение супер критическое. Меня не раз просили его исправить. В те времена для решения проблемы я прибегал к помощи магии. Теперь есть значение balance
для свойства text-wrap
.
Не будем долго тянуть и добавим его для заголовка.
h1 {
text-wrap: balance
}
![](https://habrastorage.org/webt/ba/nd/zd/bandzdgibqvbtfcbfeltmfus5vo.png)
При значении balance
браузеры равномерно распределяют символы между строками. В итоге мы снижаем вероятность появления «висячего слова». А значит наши дизайнеры будут довольны.
▍ CSS-вложенность
Первый раз я узнал про CSS-препроцессоры в июле 2013 года. В то время ходил по собеседованиям. На одном из них мне как раз рассказали про новым инструмент, который позволяет вкладывать правила друг в друга. Например, так.
.awesome-block {
border: 2px solid lightblue;
padding: 1rem;
h3 {
font-size: 3rem;
}
}
Только у меня для вас сюрприз. Этот код будет работать в браузере. В CSS теперь тоже есть вложенность. Даже символ амперсанда сохранился.
.awesome-block {
border: 2px solid lightblue;
padding: 1rem;
&:hover {
background-color: tomato;
}
}
Я зашёл с плюсов, чтобы вы подумали: «Вау, как круто!». Конечно, есть и свои минусы. Нельзя использовать амперсанд в названии класса. Несколько видов синтаксиса. Подводные камни в алгоритме работы. Всё это есть.
Но всё же сама фишка зайдёт многим. Появится CSS с «нативной» вложенность, поэтому нам нужно уже начинать изучать её.
▍ Псевдо-классы :user-valid
и :user-invalid
При разработке формы есть обязательные поля. Они могут быть заполнены корректно или нет. В CSS для этого есть псевдо-классы :valid
и :invalid
.
Если честно говорить, то они работают странно. Рассмотрим пример.
<body>
<form class="form">
<div class="form__group">
<label for="name">Введите логин</label>
<input id="name" type="text" value="melnik909" required>
</div>
<div class="form__group">
<label for="password">Введите пароль</label>
<input id="password" type="password" required>
</div>
<button>Войти</button>
</form>
</body>
input:invalid {
box-shadow: 0 0 10px red;
}
input:valid {
box-shadow: 0 0 10px green;
}
![](https://habrastorage.org/webt/rc/v-/oq/rcv-oqs4llkvwohkpt7vokyf3q4.png)
Открыв страницу, мы увидим, что браузеры уже добавили зелёную и красную тень к полям. Хотя мы ещё даже не взаимодействовали с ними. Это как раз упущение авторов стандартов. По этой причине псевдо-классы :valid
и :invalid
были нелюбимы разработчиками.
Хорошо, что это упущение уже исправлено. Появились псевдо-классы :user-valid
и :user-invalid
. Они не сработают, пока пользователь не начнёт взаимодействовать с полем.
Исправим предыдущий пример, добавив их вместо предыдущих псевдо-классов.
input:user-invalid {
box-shadow: 0 0 10px red;
}
input:user-valid {
box-shadow: 0 0 10px green;
}
![](https://habrastorage.org/webt/3s/zx/e-/3szxe-o6kgjfscr-jwvyqk5-_fw.png)
Уже другое дело! Стили не применились после загрузки страницы. И так будет, пока я не буду взаимодействовать с полем.
▍ Свойство scrollbar-gutter
У меня есть грешок. Меня раздражают «прыжки» контента при открытии и закрытии модальных окон. В рамках этой статьи я не могу показать их. По этой причине я нашёл подходящий пример на сайте Дока.
Почему происходит такое поведение? Обратите внимание на полосу прокрутки браузера. Если модальное окно закрыто — она есть, когда оно открыто — полоса убирается. Такое поведение достигается с помощью значение hidden
для свойства overflow
, добавленного к элементу <body>
. Убирая и добавляя полосу прокрутки, браузеры смещают контент на её ширину. Следовательно, он «прыгает».
Решить эту проблему теперь просто. Появилось свойство scrollbar-gutter
, которое управляет пространством, выделяемым под полосу прокрутки. Например, значение stable
заранее зарезервирует место под полосу прокрутки.
html,
body {
scrollbar-gutter: stable;
}
Только посмотрите, как изменилось поведение модального окна. Больше никаких «прыжков».
▍ Математическая функция round()
При вёрстке интерфейсов иногда получаются значения с десятичной частью. Для примера посмотрите на значение у свойства margin
в инструментах разработчика.
.box {
width: 2rem;
height: 2rem;
background-color: lightblue;
box-sizing: border-box;
margin: 1.25rem;
}
![](https://habrastorage.org/webt/1l/wk/-_/1lwk-_nstldc_ab3s7cke-vxpz8.png)
Не знаю, какой у меня таракан в голове, но нецелые числа меня раздражают. Мне кажется, что целые числа «лучше». Объективно доказать это я не могу. Но сейчас не об этом.
В CSS никогда не было возможности округлить значение, а теперь есть специальная функция round()
. А самое главное — это значение to-zero
. Оно любимо мной, потому что отбрасывает дробную часть.
.box {
width: 2rem;
height: 2rem;
background-color: lightblue;
box-sizing: border-box;
margin: round(to-zero, 1.25rem, 1px);
}
![](https://habrastorage.org/webt/hr/bl/je/hrbljecu374bfzzvk5hn6mnj4na.png)
Если подойти более серьёзно к вопросу, то функция round()
супер полезна. Лично мой любимый способ сочетать её с функцией calc()
.
▍ Ключевые слова safe
и unsafe
Вы же знаете свойства align-items
и justify-content
? Я уверен, что да. Но, к сожалению, я сомневаюсь в том, что вы слышали об их главной особенности. При позиционировании элементов с помощью этих свойств может обрезаться часть элементов.
Как сказано в стандарте, это происходит, когда дочерние элементы больше по размерам, чем родительский контейнер. Случается переполнение и обрезка элементов, как в моём примере.
.parent {
width: 20rem;
height: 5rem;
background-color: lightblue;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow: hidden;
}
.child {
width: 150%;
background-color: tomato;
}
![](https://habrastorage.org/webt/mu/iz/ji/muizji-l-i1b0yluiccorruh4mk.png)
По этой причине авторы стандартов придумали ключевые слова safe
и unsafe
.
Ключевое слово safe
сообщает браузерам, что они должны применить значение start
. Это поможет избежать ситуации, когда элемент может быть обрезан в начале.
.parent {
width: 20rem;
height: 5rem;
background-color: lightblue;
display: flex;
flex-direction: column;
align-items: safe center;
justify-content: center;
overflow: hidden;
}
![](https://habrastorage.org/webt/wm/-v/mq/wm-vmqe3huhcgf_-hstxtnrnfm0.png)
Ключевое слово unsafe
вы наврятли будете задавать. Браузеры сами поймут, что его надо использовать, если вы просто указываете значение для свойств align-items
и justify-content
.
▍ Свойство align-content
Я хорошо помню времена, когда появились флексбоксы. Поэтому долгое время я считал, что при использовании свойства align-content
надо использовать «флексы». Ладно, или «гриды». Так тоже потом стало можно.
А теперь давайте покажу вам магию. Посмотрите в инструменты разработчика на этом скриншоте.
![](https://habrastorage.org/webt/2m/jy/ac/2mjyacj_jwurh9jt-lpmpwrb1bk.png)
Да! Теперь свойство align-content
работает само по себе. Нам не нужно добавлять flex
, inline-flex
, grid
и inline-grid
значения для свойства display
у родительского элемента. Вот код из моего примера в качестве доказательства.
.container {
height: 10rem;
background-color: lightblue;
align-content: center;
}
.awesome-block {
background-color: tomato;
}
У нас наконец-то появился способ отцентрировать элемент по вертикали с помощью одного свойства! Теперь все программисты, хейтившие CSS, получили ответ. Я уже думаю выпить за это. Всё-таки десять лет ждал.
▍ Вместо заключения
В рамках этой статьи я рассказал только про те CSS-фишки, пользу которых мог показать в рамках статьи. Но есть ещё те, которые не смог добавить. А они также очень полезны. Поэтому я их перечислю без объяснения.
Обратите, пожалуйста, внимание:
- на единицу измерения
cap
, которая рассчитывается относительно высоты заглавных букв; - свойство
content-visibility
, оптимизирующее скорость отображения страницы; - свойство
transition-behavior
, позволяющее анимировать элемент, даже если для него переключается значение для свойстваdisplay
; - математические функции
rem()
иmod()
.
Вот теперь обзор закончен. Я вам рассказал всё, что нашёл. Но как я оставлю вас без своей рекомендации? Я так не могу!
Я считаю самыми полезными следующие:
- значение
balance
для свойстваtext-wrap
; - псевдо-классы
:user-valid
и:user-invalid
; - функцию
round()
; - свойство
scrollbar-gutter
; - свойство
transition-behavior
.
Вот такой мой личный топ. Надеюсь, вы обратите на него внимание. Также мне будет интересно прочитать, что понравилось лично вам. Напишите свой список в комментариях. Также если я что-то упустил из виду, то, пожалуйста, дайте мне знать.
На этом всё. Спасибо за чтение!
P.S. Помогаю больше узнать про CSS в своём ТГ-канале CSS isn't magic. Присоединяйтесь. Ссылка в профиле.
© 2025 ООО «МТ ФИНАНС»
Telegram-канал со скидками, розыгрышами призов и новостями IT ?
![](https://habrastorage.org/webt/yo/se/km/yosekm4h_f7y7oia-ghbbpc0phi.png)
wadowad
По поводу первого примера: союз "и" практически никогда не должен "отлепляться" от последующего слова (за очень редким исключением). Предлоги так точно нужно переносить вместе со словом, к которому они относятся. Мне кажется, проблему "висячих" союзов и предлогов проще решать неразрывными пробелами. Особенно с таким зоопарком устройств, когда заранее неизвестно какой ширины будет блок с контентом.
Можно попытаться это дело автоматизировать по словарю предлогов и союзов или, например, договорится с редактором, что двойной пробел будет преобразовываться в неразрывный. Как вариант, банальный фильтр для Wordpress'а:
artptr86
Двойной пробел как неразрывный при наборе слов, которые должны быть «вместе» на строке, выглядит ещё хуже. Уж лучше тогда как в Латехе использовать тильду (~) в качестве символа неразрывного пробела. В наборе обычных текстов она практически не используется, при этом гораздо нагляднее, чем двойной пробел.