
Привет, Хабр!
В мире фронтенда активно всё меняется. Появляются одни инструменты, но только их выучишь — они устаревают, и нужно уже учить новые. Новые методы и API в JavaScript. Даже в HTML появляется что-то новое. И, конечно, CSS не отстаёт.
В общем не удивительно, что люди забывают или не успевают услышать о возможностях в CSS. В этой статье я постараюсь показать несколько из их, которые считаю полезными.
Давайте посмотрим, что я вам подготовил.
Ключевые слова min-content, max-content и fit-content
Давайте представим, что вам нужно сделать так, чтобы ширина элемента рассчитывалась строго по своему контенту. Как вы это сделаете?
Если вы думаете о свойстве display, то у меня для вас есть новости. CSS уже достаточно давно даёт возможность установить значение для свойств width и height строго по контенту. Для этого есть ключевые слова min-content, max-content и fit-content.
Я сразу покажу их в действии.
<body>
<div class="awesome-block min-content">Этот элемент с каким-то текстом, а размеры рассчитаны с помощью min-content</div>
<div class="awesome-block max-content">Этот элемент с каким-то текстом, а размеры рассчитаны с помощью max-content</div>
<div class="awesome-block fit-content">Этот элемент с каким-то текстом, а размеры рассчитаны с помощью fit-content</div>
</body>
.awesome-block {
background-color: pink;
}
.min-content {
width: min-content;
}
.max-content {
width: max-content;
}
.fit-content {
width: fit-content;
}

С помощью ключевого слова min-content браузеры рассчитают значение по ширине самого длинного слова.
Ключевые слова max-content и fit-content похожи. Они говорят браузерам: «Сделай, пожалуйста, так, чтобы контент элементов располагался на одной строке, а ширину элементов рассчитай по нему».
Разница между ключевыми словами заключается в том, что при использовании max-content нет переноса слов. Весь контент элемента всегда будет отображён на одной строке. Ключевое слово fit-content позволяет переносить контент на новую строку.

Вот такие классные значения теперь можно использовать для свойств width и height. И никакой магии больше не нужно.
Я даже вам немного завидую. Десять лет назад так легко установить размеры по контенту нельзя было. Приходилось хитрить. А теперь всё очевидно. Круто же!
Свойство border-image-source
Дизайнеры любят использовать медиа-контент. Особенно расположить текст поверх него. В таких задачах важной частью является создание оверлея — элемента, не дающего тексту слиться с изображением или видео. Я уверен, вы множество раз реализовывали такую штуку.
Есть разные способы. Многие используют отдельный псевдо-элемент, например ::before, который накладывается под текст поверх контента. Я рассказывал про метод с использованием слоёв для свойства background.
Но есть ещё один способ, который знают очень мало людей. Мы будем использовать свойство border! Давайте сразу перейдём к примеру.
Для начала создадим разметку и базовые стили оверлея.
<body>
<div class="awesome-hero">
<span>Привет! Это текст для красивого изображения</span>
</div>
</body>
.awesome-hero {
box-sizing: border-box;
min-height: 100dvh;
padding: 1rem;
display: grid;
place-items: center;
background-image: url("https://c.pxhere.com/images/ee/50/4d3a6b4fe0603a3aaa0bb1dbffaa-1577693.jpg!d");
background-size: cover;
background-repeat: no-repeat;
}

Теперь добавим градиент, используя свойства border-image-source. Для этого я также задам свойство border, чтобы результат был заметен.
.awesome-hero {
box-sizing: border-box;
min-height: 100dvh;
padding: 1rem;
display: grid;
place-items: center;
background-image: url("https://c.pxhere.com/images/ee/50/4d3a6b4fe0603a3aaa0bb1dbffaa-1577693.jpg!d");
background-size: cover;
background-repeat: no-repeat;
border-width: 50px;
border-style: solid;
border-image-source: linear-gradient(to top, rgba(15, 63, 122, 0.5), rgba(15, 63, 122, 0.5));
}

Наш градиент по какой-то причине решил расположиться строго по углам элемента. Так себе результат. Но самое забавное — это не баг, это фича!
В чём дело? Все детали кроются в том, что по умолчанию область, где будет отрисовано свойство border, делится на восемь отдельных зон. Для наглядности я нашёл отличную иллюстрацию на сайте MDN, которая прекрасно всё объясняет.

По умолчанию свойство border-image-source может быть отрисовано в зонах с первой по четвёртую. Именно это мы увидели в нашем примере после добавления градиента.
Конечно, можно это изменить. Браузеры могут отрисовать свойство border-image-slice в зонах с пятой по девятую, но для этого нужно использовать свойство border-image-slice.
Данное свойство разделяет элемент на сектора. Именно оно позволяет распределять указанное значение в свойстве border-image-source между секторами пять, шесть, семь и восемь.
С сектором девять интересная ситуация. Есть замечательное значение fill. Это ключевое слово сообщает браузерам, что значение свойства должно заполнить всё пространство. Получается, что сектор девять как бы становится на весь элемент.
Например, мы объявили градиент для свойства border-image-source. Мы хотим, чтобы он равномерно занял всё пространство. Для этого подойдёт значение 1.
.awesome-hero {
box-sizing: border-box;
min-height: 100dvh;
padding: 1rem;
display: grid;
place-items: center;
background-image: url("https://c.pxhere.com/images/ee/50/4d3a6b4fe0603a3aaa0bb1dbffaa-1577693.jpg!d");
background-size: cover;
background-repeat: no-repeat;
border-width: 50px;
border-style: solid;
border-image-source: linear-gradient(to top, rgba(15, 63, 122, 0.5), rgba(15, 63, 122, 0.5));
border-image-slice: fill 1;
}

Остался последний штрих. Мы уберём рамку, созданную свойством border.
.awesome-hero {
box-sizing: border-box;
min-height: 100dvh;
padding: 1rem;
display: grid;
place-items: center;
background-image: url("https://c.pxhere.com/images/ee/50/4d3a6b4fe0603a3aaa0bb1dbffaa-1577693.jpg!d");
background-size: cover;
background-repeat: no-repeat;
border-image-source: linear-gradient(to top, rgba(15, 63, 122, 0.5), rgba(15, 63, 122, 0.5));
border-image-slice: fill 1;
}

Вот таким способом мы создали оверлей. Конечно, такой способ больше подходит для ситуаций, когда не нужна анимация. Если вы хотите анимировать оверлей, то без метода на основе псевдо-элемента сложно обойтись.
Но теперь у вас есть как минимум несколько способов. Дальше уже сами выберите лучший для себя.
Медиа-функция scripting
Скорее всего, вы знаете про элемент noscript, позволяющий вывести своё содержимое, если JavaScript отключён у пользователя. Но CSS тоже не отстал от HTML. Мы можем стилизовать элементы в зависимости от того, включён ли JavaScript на текущей странице.
Для этого существую медиа-функция scripting. У неё есть несколько значений, при которых медиа-запрос сработает, а именно:
none— если JavaScript недоступен на текущей странице.initial-only— если JavaScript включён, пока идёт начальная загрузка. После неё он не сработает.enabled— если JavaScript включён на текущей странице.
Давайте посмотрим на примере, как медиа-запрос работает. Я уже подготовил разметку и стили.
<body>
<p class="javascript-none">JavaScript недоступен на странице :-(</p>
<p class="javascript-enabled">JavaScript включён на странице! :-)</p>
</body>
@media (scripting: none) {
.javascript-none {
color: lightblue;
}
}
@media (scripting: enabled) {
.javascript-enabled {
color: lightblue;
}
}
По умолчанию у меня, конечно же, включён JavaScript. Поэтому в моём примере браузеры покрасят текст у второго абзаца.

Далее с помощью инструментов разработчика я отключу JavaScript.

Теперь цвет текста будет изменён у первого абзаца.

Так что, если вы как-то проверяете поддержку JavaScript, вы можете добавить больше красоты. Пользуйтесь!
Свойство place-items
К моему большому удивлению, многие фронтендеры вообще не слышали о способе центрирования элементов по двум осям на основе свойства place-items. И всё ещё по старинке используют флексбоксы, в частности свойства justify-content и align-items.
.awesome-block {
display: flex;
justify-content: center;
align-items: center;
}
Если в вашем проекте есть такой код, то у меня есть несколько аргументов, чтобы вы перестали использовать данный подход. Вместо него добавьте гриды и свойство place-items.
.awesome-block {
display: grid;
place-items: center;
}
Во-первых, при использовании флексбоксов нам нужно объявлять три свойства, а именно: display, justify-content и align-items. Гриды же позволяют объявлять только два (display и place-items).
Во-вторых, свойства justify-content и align-items не учитывают размеры родительского элемента, если они находятся внутри элемента с установленным свойством display со значением flex или inline-flex. По этой причине контент может выходить за его пределы и быть обрезанным. Об этом я писал в отдельной статье.
Сейчас я покажу только демонстрацию. Обратите, пожалуйста, на начало текста.
<body>
<div class="awesome-block">
<span>
Этот текст не всегда будет отображён. Дальше я буду писать бессмысленный текст. Не обращайте на него внимания. Он нужен, чтобы продемонстрировать поведение.
</span>
</div>
</body>

Если мы используем свойство place-items, этого поведения не будет. Браузеры сразу сделают всё без проблем отображения элементов.

В-третьих, когда гриды только начали массово поддерживаться, фронтендеры не знали, для каких задач их использовать. В итоге сошлись на том, чтобы создавать сложные каркасы страницы. Но это один процент от всех возможностей гридов. Они дают больше возможностей, чем мы используем. Используйте их везде!
В частности, для центрирования элементов по двум осям с помощью свойства place-items.
Заключение
Давайте подведём итог. В этой статье мы рассмотрели:
возможность стилизации элементов при включённом или отключённом JavaScript у пользователя;
способ создания оверлея с использованием свойства
border-image-source;центрирование элементов по двум осям с помощью свойства
place-items;ключевые слова
min-content,max-contentиfit-content, помогающие задать значение для свойствwidthиheightпо контенту элемента.
Кстати, если вы тоже замечаете, что ваши коллеги не знают какие-то возможности CSS, то, пожалуйста, расскажите о них в комментариях. Мне будет интересно прочитать.
На этом всё. Спасибо за чтение!
P. S. Помогаю больше узнать про CSS в своём ТГ-канале CSS isn't magic. Присоединяйтесь. Ссылка в профиле.
© 2025 ООО «МТ ФИНАНС»