Магия CSS на практике: советы по вёрстке от гика. Часть 3

от автора

Хабр, привет! Я снова пришёл к вам со статьёй, где показываю мои любимые техники вёрстки. Моя цель — поделиться опытом с вами. Я использую не только трюки известных экспертов, есть лично мои придумки. Но, пожалуйста, относитесь к этому контенту, как к просто альтернативному мнению. Мои техники не являются единственными правильными решениями.

Сегодня мы рассмотрим:

  • подходы при стилизации элементов для вёрстки текста;
  • какая может быть проблема с радиокнопками в вашем проекте;
  • как задать размеры с использованием функций min() и max();
  • CSS-наследование и свойство line-height;
  • для чего делать подсказки в имени класса.

Давайте посмотрим, что я вам подготовил.

▍ Способы стилизации текста

Кажется, стилизация текста довольна простая задача. Написал всякие font-size и line-height и дело готово. Только есть пару нюансов.

В принципе у нас есть два вида текста. Разделяются они по способу добавления на страницу. К первому случаю относится текст, добавленный разработчиком при вёрстке макета. Например, текст на сайте Нижегородской области.

Раздел с заголовком, фото губернатора, кратким описанием задач правительства и его состава, списком ссылок на отдельные органы власти. Элементы расположены в две колонки. Заголовок, текст и список в левой, а фото в правой

Второй тип текста добавляется редактором сайта через редактор. Обычно это новостные страницы или страницы с документами.

Часть статьи с заголовком, несколькими абзацами текста и списком. Они отображены друг под другом

В первом случае, кажется, нет никаких нюансов. Добавил класс и написал стили для заголовков и абзацев. А вот во втором случае он есть. Многие редакторы не позволяют добавлять класс. После редактирования текста в редакторе, в коде будут просто элементы. Такие, как <p>, <ul>, <h2> и т. п.

Столкнувшись с этой проблемой, я начал гуглить, что же можно делать. Нашёл два подхода. Первый подход основан на сложном селекторе с классом и селектором типа. Пример можно найти на Хабре.

.article-formatted-body ol, .article-formatted-body ul {   padding-inline-start: 32px; }  .article-formatted-body h2 {   font-size: 1.25rem;   line-height: 1.625rem; }  .article-formatted-body p {   margin: 0;   padding: 0; } 

В данном подходе создаётся специальный класс .article-formatted-body. Он не даёт случиться утечке стилей, чтобы они не стали применяться к таким же элементам в других частях приложения.

Второй способ основан на селекторе :not([class]).

:is(ul, ol):not([class]) {   margin-block: 2rem 0; }  h2:not([class]) {   font-size: 1.25rem;   line-height: 1.625rem; }  p:not([class]) {   margin-block: 2rem 0; } 

Для реализации этой идеи существует правило. Атрибут class добавляется только для элементов, доступных для редактирования разработчиками. Элементы, редактируемые через редактор, должны быть без атрибута. В этом случае селектор :not([class]) сработает отлично.

Мне лично больше нравится второй подход. Во-первых, не надо придумывать имя класса. Во-вторых, код выглядит более структурировано. В-третьих, я люблю встроенные возможности CSS.

Но это всё личные предпочтения. А что выбираете вы? И как вы поступаете в таких задач? Напишите, пожалуйста, в комментариях.

▍ Подружим радиокнопки и режим высокой контрастности в Windows

Я посмотрел много популярных решений кастомных радиокнопок на Codepen. У них у всех есть общая проблема. Они используют свойство background-color для установки цвета точки при активном состоянии. Взгляните на псевдоэлемент ::before.

.toggle {   appearance: none;   margin: 0;   width: 1rem;   height: 1rem;    border: 1px solid #242424;   border-radius: 50%;    display: grid;   place-items: center; }  .toggle[type="radio"]::before {   content: "";   width: 0.5rem;   height: 0.5rem;   background-color: #242424;    border-radius: 50%;   opacity: 0;   position: absolute;   scale: 0; }  .toggle[type="radio"]:checked::before {   opacity: 1;   scale: 1; } 

Почему я говорю, что есть проблема. Давайте посмотрим на радиокнопки в режиме высокой контрастности в Windows.

На темном фоне отображены два кружка без точек внутри. У каждого рядом надпись. У первого кружка надпись Вариант №1. У второго Вариант №2.

Скажите теперь, какой из элементов активный. Не знаете? Вот, в этом заключается проблема. На деле активный первый.

<body>   <div class="custom-radio-button">     <input id="rb-1" class="toggle custom-radio-button__input" type="radio" name="radio" checked>     <label for="rb-1" class="custom-radio-button__label">Вариант №1</label>   </div>   <div class="custom-radio-button">     <input id="rb-2" class="toggle custom-radio-button__input" type="radio" name="radio">     <label for="rb-2" class="custom-radio-button__label">Вариант №2</label>   </div> </body> 

На белом фоне отображены предыдущие два кружка. У первого есть точка внутри

Почему так получилось? Дело в том, что в режиме высокой контрастности браузеры подставляют значение transparent для свойства background. Это изменить нельзя. Так, что наше значение пропадёт.

Правда, я нашёл решение. Достаточно точку сделать с помощью свойства border.

.toggle[type="radio"]::before {   content: "";   border: 0.25rem solid #242424;   /* оставшиеся CSS */ } 

На темном фоне отображены предыдущие два кружка. У первого есть точка внутри

Теперь радиокнопки отлично работают. Думаю, теперь вы знаете, что поправить в своём проекте. Надеюсь, вы это сделаете.

▍ Функции min() и max() помогают мне установить максимальный или минимальный размер у элемента

Периодически нам приходится ограничивать размеры элементов. Например, указывать ширину, но она не должна быть больше какого-то значения. Такая задача решается с помощью свойств width и max-width:

.container {   width: 100%;   max-width: 75rem; } 

Это надёжный фрагмент кода, проверенный временем. Лично я предпочитаю другой способ. Можно сократить код до одной строки. Для этого подходит математическая функция min().

.container {   width: min(100%, 75rem); } 

Весь трюк заключается в том, что данная функция позволяет браузеру выбрать наименьшее значение из представленных аргументов. В моём примере их два — 100% и 75rem. Далее браузеры рассчитывают итоговое значение для каждого аргумента в пикселях и сравнивают между собой. В итоге мы получим значение 100%, пока оно не станет больше значения 75rem.

Круто ещё то, что есть функция max(). С помощью неё я могу указать минимальный размер элемента. Например, ширину.

.container {   width: max(100%, 75rem); } 

Принцип тот же самый. Единственная разница в том, что браузеры выбирают максимальное значение.

▍ Моя самая обидная ошибка со свойством line-height

Я должен признаться. Раньше я постоянно встречал свойство line-height, определённое для элемента <body>. Отключая его в DevTools, я думал: «Зачем оно здесь?». Ленившись поискать ответ, забивал.

А моё недоумение было следствием моей привычки. Я для каждого типа элемента определял свойство line-height.

p {   line-height: 1.5; }  ul {   line-height: 1.5; } 

Скорее всего, вы знаете о том, что свойство line-height является наследуемым. И уже догадались, что я зря дублировал значение.

Я узнал об этом случайно. Мне попались CSS советы с типичным названием «CSS Protips». В этом списке был раздел, в котором написано: «Вам не нужно отдельно добавлять line-height для каждого элемента <p>, <h*> и других. Вместо этого добавьте свойство к элементу <body>».

body {   line-height: 1.5; } 

И всё. У меня щёлкнуло в голове. С тех пор объявляю всегда.

▍ Рассказываем о назначении класса с помощью его имени

Я фанат БЭМа с 2013 года. Мне нравится идея использовать библиотеку универсальных компонентов. Только у меня всегда был затык. В проектах с большим количеством кода сложно ориентироваться в нём. Приходится тратить очень много времени на осмысление нужного фрагмента кода. По этой причине мне нравится делать подсказки в названии CSS класса.

Саму идею я где-то встретил много лет назад. Не вспомню, где конкретно. Поэтому пошёл за примером к знакомым. Они прислали мне несколько. Одним из них был АБЭМ. Суть заключается в соединении БЭМа и принципов атомарного дизайна (Atomic Design).

Мы не будем подробно разбирать данную философию. Нам достаточно знать, что весь дизайн делится на организмы, молекулы и атомы. АБЭМ вносит специальные обозначения для них в имена классов.

Так, классы-организмы начинаются с o-, классы-молекулы с m-, классы-атомы с a-.

.o-accordion {   /* здесь свойства */ }  .m-revealer {   /* здесь свойства */ }  .a-control {   /* здесь свойства */ } 

Я не фанат этой идеи. Да, если честно, мне нравится изобретать свой велосипед. Так что АБЭМ натолкнул меня на идею: «А почему бы в названии класса не показать цель компонента?». Так у меня появились обозначения uia- и ra-.

<body class="page">   <header class="page__banner">     <div class="page__container">       <h1 class="page__cv-heading uia-heading ra-heading">         <span>Catherine Starobor-Strakhova</span>         <span class="page__cv-role">Full stack game UX/UI designer with strong visual development</span>       </h1>       <a href="#0" class="page__cv-download ra-link uia-control">         <span class="uia-control__group">Download CV</span>       </a>     </div>   </header> </body> 

В коде есть универсальные компоненты uia-heading и uia-control. Они используются в разных проектах. Я отношу их к интерфейсным компонентам, поэтому называю User Interface Atoms или кратко — uia-.

Кроме них есть компоненты для сброса браузерных стилей у заголовков и у ссылок, а именно ra-heading и ra-link. Они являются Reset Atoms, соответственно, у них обозначение — ra-.

Такая вот идея. При большом количестве кода она меня выручала. Надеюсь, вам она зайдёт.

▍ Заключение

Давайте подведём итог. В этой статье мы рассмотрели:

  • как селектор :not([class]) помогает при стилизации текста;
  • пользу свойства border при реализации кастомных радиокнопок;
  • сокращённую форму установки минимальных и максимальных размеров;
  • установку свойства line-height без дублирования значения в нескольких местах;
  • подсказки в именах классов, сообщающие их назначение.

Оставлю ссылки на все выпуски:

Спасибо за чтение!

P.S. Помогаю больше узнать про CSS в своём ТГ-канале CSS isn’t magic. Присоединяйтесь. Ссылка в профиле.

Telegram-канал со скидками, розыгрышами призов и новостями IT ?


ссылка на оригинал статьи https://habr.com/ru/articles/834478/