CSS не отстаёт от JavaScript. Постоянно развивается. Классно же. Мне особенно радостно видеть, как старые задачи, которые я решал при помощи костылей, теперь можно сделать при помощи одного свойства.
Только многие фишки неизвестны широкому кругу разработчиков. Честно говоря, некоторые я сам узнал недавно. В любом случае так дальше нельзя. Надо исправлять ситуацию!
Я собрал фишки, которые могут быть полезны в разного рода проектах. Неважно, верстаете ли вы сайт для малого бизнеса или создаёте супермодное React приложение. Они поддерживаются большинством браузеров начиная с 2021 года. Отдельно отмечу, что я не считаю IE11 браузером, который поддерживается в современной разработке. По этой причине я не учитывал его.
Больше не буду затягивать. Давайте посмотрим, что я вам подготовил.
▍ Что можно делать со свойством text-decoration
В 2011 году я изучал вёрстку, и, конечно, я узнал про свойство text-decoration
. С помощью него я убирал подчёркивание у ссылки, думаю, вы также делаете. А теперь хочу спросить вас. Вы знаете, что сейчас это свойство является краткой формой записи?
Я не знал этого и был в шоке. Оказывается, что text-decoration
включается в себя свойства: text-decoration-line
, text-decoration-thickness
, text-decoration-style
и text-decoration-color
. С помощью них мы можем определить тип, толщину, вид и цвет линии, как я сделал ниже:
/*
свойство text-decoration разворачивается в следующие свойства:
text-decoration-line: underline;
text-decoration-thickness: 3px;
text-decoration-style: solid;
text-decoration-color: tomato;
*/
a {
text-decoration: underline 3px solid tomato;
}
Чёрт, может это, конечно, очевидно для вас. Но я, правда, только недавно узнал об этом. И очень сильно радуюсь свойствам text-decoration-thickness
и text-decoration-color
. Почему?
Мне всегда попадались макеты, когда требовалось сделать подчёркивание толще, чем оно было по умолчанию в браузерах. А ещё и цвет поменять. И всё это нельзя было сделать с помощью text-decoration
. Приходилось обращаться к другим трюкам. А сейчас стало проще. Класс!
Менее важной для меня является свойство text-decoration-line
, но у него есть фишечка, которая может быть полезна вам. Мы можем установить несколько значений.
a {
text-decoration-line: underline line-through;
}
Думаете полезно? Если да, то напишите, пожалуйста, в комментариях, где это может пригодиться.
Теперь вроде всё рассказал. А, нет. Чуть не забыл. Есть свойство text-underline-offset
. Оно не входит в краткую форму записи text-decoration
, но оно, как мне кажется, очень полезное. С помощью него можно указать позицию подчёркиванию, созданное свойством text-decoration-line
, так как мы хотим.
a {
text-decoration: underline 3px solid tomato;
text-underline-offset: 5px;
}
Вот смотрю на эту ссылку и ностальгия. Сколько костылей раньше приходилось придумывать. Похожие ощущения у меня были, когда стало возможным использовать свойство border-radius
, и отпала необходимость нарезать скруглённые уголки.
▍ Стилизация каждого слова при переносе текста
Однажды я помогал ребятам создавать дизайн-систему. Мы настраивали стили для базовой типографики. Одна из задач заключалась в том, чтобы стилизовать ссылки в тексте с нестандартным подчёркиванием. Сложность заключалась в том, что подчёркивание должно было сохраняться при переносе текста на новую строку, как показано ниже на изображении:
Обратите внимание, что у ссылки есть отступ после последней буквы «n» в слове «Brendan» и перед первой буквой «E» в слове «Eich».
В чём заключается проблема? По умолчанию браузеры воспринимают контент элемента, как единое целое. По этой причине при переносе текста, его стилизация происходит целиком, а не по словам. Таким образом, когда я добавил свойство padding
, то браузеры отобразили отступ перед и после ссылки. А это приводило к тому, что подчёркивание резко обрывалось при переносе текста.
К счастью, это очень легко изменить. Свойство box-decoration-break
со значением clone
сообщает браузеру, что при переносе текста свойства background
, border
, border-image
, box-shadow
, clip-path
, margin
и padding
должны быть применены к каждому слову по отдельности.
В моём примере я добавил свойство к ссылке:
<body>
<div class="content">
<p>
JavaScript (or ECMAScript) is the programming language that powers the web. Created in May 1995 by
<a href="#0">Brendan Eich</a>,
it’s found its place...
</p>
</div>
</body>
.content a:not([class]){
text-decoration: none;
color: currentColor;
background-image: linear-gradient(#ff7eb2 0, #ff7eb2);
background-size: 100% .35em;
background-position: left bottom;
background-repeat: no-repeat;
padding-inline: 0.25em;
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
}
▍ Больше контроля над обрезкой изображения
Отображения изображений — мой ночной кошмар. Я думаю вам знакома ситуация, когда в дизайне изображения одного размера, а перед сдачей проекта изображения заказчика совершенно другого.
Например, по дизайну изображения квадратные, а у заказчика они прямоугольные. В результате они искажаются.
Эх, испортили фото кота. Конечно, здесь можно использовать свойство object-fit
. Значение cover
подскажет браузерам, что им нужно адаптировать изображение без нарушения пропорций под всю доступную область.
img {
display: block;
width: 350px;
height: 350px;
object-fit: cover;
}
И кажется, что всё будет хорошо. Но к сожалению, при адаптации происходит обрезка изображения. Она может пройти совсем неожиданно, потеряв важную часть.
Кот с обрезанным глазом — это непорядок! Надо исправить. Сделать это можно с помощью свойства object-position
.
Оно указывает смещение изображения при использовании свойства object-fit
. Другими словами, у нас появляется возможность сместить изображение так, чтобы оно обрезалось без потери важной части.
При определении свойства мы можем использовать единицы измерения и ключевые слова в качестве значения свойства. Например, я задам значение right top
.
img {
display: block;
width: 350px;
height: 350px;
object-fit: cover;
object-position: right top;
}
Вот другое дело. Теперь кот отображается во всю свою красоту. Только теперь моё дизайнерское начало негодует. Кот отображается не в центре! Слишком много пространства справа от него.
Я поэкспериментировал и подобрал значение 80% 0
.
img {
display: block;
width: 350px;
height: 350px;
object-fit: cover;
object-position: 80% top;
}
Идеально! Правда, здесь я хочу поделиться находкой. Когда я подбирал значение, я думал, что браузеры вычисляют значения от левой границы родительского элемента. Но, это не так!
Оказывается, сначала они анализируют ширину изображения и контентной области, в котором оно находится. Далее отсчитывают значение 80%
от левого края изображения и родительской контентной области. И на последнем этапе смещают изображение так, чтобы точки совпали.
Эх, как по мне, неочевидно. Я лично потратил несколько часов, чтобы понять, почему у меня 80%
рассчитываются странно. Но, что поделать. Зато котик красиво отображается. Главное, вы теперь знаете, как работает свойство. Надеюсь, сэкономил ваше время.
▍ Не позволяем браузерам скрыть часть контента после прокрутки страницы
При создании внутристраничной навигации одна из неочевидных проблем заключается в корректном переходе к разделу при клике по ссылке. Если этот момент не продумать, то получится так, что блок с навигацией скроет часть контента.
Для примера я создал лендинг, где кликнул по ссылке «Experience», а потом блок с навигацией закрыл заголовок.
Раньше нужно было немного шаманить, чтобы решить эту проблему. А сегодня всё просто.
Существует свойство scroll-margin-top
. С помощью него мы можем установить отступ между элементом, к которому происходит переход, и вьюпортом. В качестве значения используются такие же единицы измерения, как при привычном свойстве margin
.
Перейду теперь к исправлению ошибки в моём примере. Я использую следующую разметку раздела:
<section class="page-section">
<div class="main-container">
<h2 class="page-section__heading">
<span class="page-section__name">Experience</span>
<span class="page-section__hint">More about my experience</span>
</h2>
<div class="page-section__content">
<!-- здесь находится контент раздела -->
</div>
</section>
Корректное значение отступа будет рассчитываться, как сумма высоты блока с навигацией (75px
) и внутреннего отступа между верхней границей раздела и заголовком (9rem
). За суммирование в CSS отвечает функция calc()
. Добавлю её к заголовку вместе со свойством scroll-margin-top
.
.page-section {
padding-top: 9rem;
}
.page-section__heading {
scroll-margin-top: calc(9rem + 75px);
}
▍ Заключение
Давайте подведём итог. Сегодня CSS предоставляет нам:
- Свойства
text-decoration-line
,text-decoration-thickness
,text-decoration-style
,text-decoration-color
иbox-decoration-break
для красивых многострочных ссылок с дефолтным подчёркиванием; - Свойство
object-position
для более корректной обрезки изображений; - Свойство
scroll-margin-top
, сохраняющее контент видимым после прокрутки страницы;
Вы же будете использовать их? Или я зря написал эту статью? Пожалуйста, ответьте в комментариях.
Также мне будет интересно прочитать, какие CSS фишки вы используете, о которых другие могут не знать. Буду ждать их. Спасибо за чтение!
Автор: Стас Мельников