
Привет, Хабр.
В начале января 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;
}

Получилось так, что последнее слово осталось одиноким в своей строке. Я забыл, как в типографике называется такая ошибка. Вроде «висячие слова». Но я не уверен.
В общем это поведение супер критическое. Меня не раз просили его исправить. В те времена для решения проблемы я прибегал к помощи магии. Теперь есть значение balance
для свойства text-wrap
.
Не будем долго тянуть и добавим его для заголовка.
h1 {
text-wrap: balance
}

При значении 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;
}

Открыв страницу, мы увидим, что браузеры уже добавили зелёную и красную тень к полям. Хотя мы ещё даже не взаимодействовали с ними. Это как раз упущение авторов стандартов. По этой причине псевдо-классы :valid
и :invalid
были нелюбимы разработчиками.
Хорошо, что это упущение уже исправлено. Появились псевдо-классы :user-valid
и :user-invalid
. Они не сработают, пока пользователь не начнёт взаимодействовать с полем.
Исправим предыдущий пример, добавив их вместо предыдущих псевдо-классов.
input:user-invalid {
box-shadow: 0 0 10px red;
}
input:user-valid {
box-shadow: 0 0 10px green;
}

Уже другое дело! Стили не применились после загрузки страницы. И так будет, пока я не буду взаимодействовать с полем.
▍ Свойство 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;
}

Не знаю, какой у меня таракан в голове, но нецелые числа меня раздражают. Мне кажется, что целые числа «лучше». Объективно доказать это я не могу. Но сейчас не об этом.
В CSS никогда не было возможности округлить значение, а теперь есть специальная функция round()
. А самое главное — это значение to-zero
. Оно любимо мной, потому что отбрасывает дробную часть.
.box {
width: 2rem;
height: 2rem;
background-color: lightblue;
box-sizing: border-box;
margin: round(to-zero, 1.25rem, 1px);
}

Если подойти более серьёзно к вопросу, то функция 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;
}

По этой причине авторы стандартов придумали ключевые слова 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;
}

Ключевое слово unsafe
вы наврятли будете задавать. Браузеры сами поймут, что его надо использовать, если вы просто указываете значение для свойств align-items
и justify-content
.
▍ Свойство align-content
Я хорошо помню времена, когда появились флексбоксы. Поэтому долгое время я считал, что при использовании свойства align-content
надо использовать «флексы». Ладно, или «гриды». Так тоже потом стало можно.
А теперь давайте покажу вам магию. Посмотрите в инструменты разработчика на этом скриншоте.

Да! Теперь свойство 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 ?

Комментарии (20)
Luzinov
11.02.2025 14:41Классно, но пока 90% пользователей не обновятся до новейших браузеров мы не сможем использовать это в проде.
Azirel
11.02.2025 14:41Новейших?..
Luzinov
11.02.2025 14:41https://caniuse.com/mdn-css_properties_scrollbar-gutter
Декабрь 24 вас не смущает?
amakhrov
11.02.2025 14:41Конкретно это правило вполне можно использовать в проде - хуже-то не будет. Большинству браузеров будет лучше, а Сафари продолжит скакать как и раньше.
Sergei_Erjemin
11.02.2025 14:41Я забыл, как в типографике называется такая ошибка. Вроде «висячие слова». Но я не уверен.
Это называется "вдовы". Одинокие слова на последней строчке параграфа. Это не только в заголовках некрасиво.
А еще бывают "сироты" -- это одинокие строчки (и даже две или три) которые переползают на новую страницу или колонку (ну или остаются на предыдущей странице или колонке). За таким тоже надо следить.А еще бывают "колодцы". Это когда на нескольких строчках подряд пробелы между словами выстраиваются вертикально (это действительно выглядит как колодец). Как с этим бороться в веб-верстке пока не придумано (по крайне мере не придумано мной).
wadowad
По поводу первого примера: союз "и" практически никогда не должен "отлепляться" от последующего слова (за очень редким исключением). Предлоги так точно нужно переносить вместе со словом, к которому они относятся. Мне кажется, проблему "висячих" союзов и предлогов проще решать неразрывными пробелами. Особенно с таким зоопарком устройств, когда заранее неизвестно какой ширины будет блок с контентом.
Можно попытаться это дело автоматизировать по словарю предлогов и союзов или, например, договорится с редактором, что двойной пробел будет преобразовываться в неразрывный. Как вариант, банальный фильтр для Wordpress'а:
artptr86
Двойной пробел как неразрывный при наборе слов, которые должны быть «вместе» на строке, выглядит ещё хуже. Уж лучше тогда как в Латехе использовать тильду (~) в качестве символа неразрывного пробела. В наборе обычных текстов она практически не используется, при этом гораздо нагляднее, чем двойной пробел.
wadowad
Я руководствовался в первую очередь "обратной совместимостью". Если скрипт не отработает, то в html ничего критичного не произойдёт, т.к. двойной пробел будет считаться за один.
Да, двойной пробел не очень нагляден, особенно если следующее слово в редакторе переносится на другую строку. Но ничего другого в голову тогда не пришло, а теперь как-то устаканилось.
Знак тильды спорное решение, потому что нужно переключать раскладку, либо пользоваться комбинациями. По трудозатратам получается равносильно вводу неразрывного пробела Alt+255.
artptr86
А что означает "если скрипт не отработает"? Это же пхп, а не клиентский жс, если он не отработает, то пользователь вообще ничего не увидит. Кроме того, можно было бы организовать подстановку неразрывных пробелов по словарю и/или регуляркам.
wadowad
В приведённом выше примере с Wordpress подразумевается, что фильтр "зашит" в functions.php темы, а не оформлен отдельным плагином. При смене темы фильтр может потеряться.
artptr86
То есть вы поленились написать плагин, захардкодили фильтр в тему, а теперь этим оправдываетесь?
Безотносительно, замена по словарю всё равно обратно совместима.
wadowad
Не оправдываюсь. Я поленился привести код плагина, просто потому что он намного больше кода фильтра и мне не захотелось заниматься удалением из него других фильтров для контента.
Двойной пробел остаётся совместим с кодом для прохода по словарю. Но проход по словарю приставок не решит проблему с другими "висячими", такими, как единицы измерения, указание диапазонов. Также довольно часто требуется, чтобы два слова были неразлучны при любой ширине блока с текстом и нужно какое-то ручное редактирование. Может в этом холиваре всплывёт какая-нибудь умная идея для решения проблемы. Неразрывный пробел нужен, но доступ к нему через комбинации уж очень трудозатратный.
Per_Ardua
Если нужно что-то делать, но кому-то другому (редактору), то это называется не автоматизация, а перекладывание работы.
Если нужна именно автоматизация, то рабочим решением будет скрипт с подключением к LLM и необходимая предобработка через неё. Ошибки будут, но не больше чем при работе того же редактора.
gun_dose
Подключать LLM ради того, чтобы предлог не отрывался от последующего слова - это уже полный оверкилл. В любом языке количество предлогов будет не больше сотни. Написать функцию замены сможет даже школьник.
Per_Ardua
Тут да, вы правы, в этой задаче LLM будет лишней.
Видел как нейросеть используют для проставления неразрывных пробелов, и, на самом деле, они должны проставляться не только после предлогов и союзов. Но исходя из текущей постановки задачи это действительно оверхед.
gun_dose
Вообще, для конкретно этой задачи нужен типограф. Это софт, который приводит тексты к определённым стандартам - кавычки-ёлочки, длинные тире (—), убрать двойные пробелы, вставить неразрывные пробелы. И готовых решений для этого просто тьма, начиная от библиотек под любой популярный язык программирования, заканчивая онлайн-сервисами, как у студии Артемия Лебедева.
vanxant
Нормальные типографы для русского языка, которые убирали висячие строки, заменяли кавычки на лапки и ёлки, дефисы на тире где надо и т.д., появились лет так 20 назад. Без всяких там LLM.
GeorgeTudosi
Для неразрывного пробела есть символ U+00A0, который прекрасно вводится с помощью типографской раскладки. Уже много лет пользуюсь, и не представляю себе, как без неё люди-то живут :). Кроме пробела, там ещё много полезных символов.
Но дальше начинается интересное. Например, есть такой «конструктор сайтов» Тильда. Так вот, там программисты специально постарались, чтобы неразрывный пробел автомагически преобразовывался в обычный, а чтобы ввести именно неразрывный пробел, надо набрать
#nbsp;
. Что?!11 В каком бреду вообще можно было такое придумать?И Adobe тоже отличились, вот уж от кого не ожидал. Привычный
⌥+пробел
не работает, надо⌘+⌥+X
. Зачем так извращаться? Ну ладно, свой шорткат — понимаю, не у всех раскладка есть. Но чужой-то зачем ломать?riky
или договорится с редактором чтобы он сразу ставил неразрывный пробел alt + 0160.
также можно ему перех сохранением подсказывать места где пропустил (по словарю)