Frog Proger 25 ноября 2024

🎨 5 CSS-приемов, которые нужно знать каждому фронтендеру

5 мощных CSS-техник для современной веб-разработки: селектор :has(), компактные медиазапросы, решение проблемы с порядком правил и другие приемы для профессиональных фронтенд-разработчиков.
🎨 5 CSS-приемов, которые нужно знать каждому фронтендеру
Этот материал взят из нашей еженедельной email-рассылки, посвященной фронтенду. Подпишитесь, чтобы быть в числе первых, кто получит дайджест.

Применение CSS-стилей в зависимости от количества дочерних элементов

CSS-селектор :has() позволяет стилизовать элементы, учитывая количество дочерних элементов в родительском контейнере – вместо того, чтобы вручную задавать разные стили для случаев с одним или несколькими дочерними элементами. Здесь :has(> :nth-child(2)) проверяет, есть ли у элемента .uia-control второй дочерний элемент. Если он есть, то к .uia-control применяется стиль gap: 1rem;, который задает расстояние между дочерними элементами:

        .uia-control {
  display: inline-flex;
  /* remaining CSS */
}

.uia-control:has(> :nth-child(2)) {
  gap: 1rem;
}
    

Эффективное управление зависимыми стилями

Вместо того, чтобы вручную корректировать стили для каждого элемента, можно использовать одну пользовательскую переменную, которая синхронизирует изменения во всех связанных местах. В этом примере вы задаете значение только один раз (в переменной --page-banner-height), а изменения распространяются на все элементы, которые ее используют – например, если вы решите изменить высоту баннера с 2rem на 3rem, нужно будет изменить только переменную в :root:

        :root {
  --page-banner-height: 2rem;
}

.banner {
  height: var(--page-banner-height);
  position: fixed;
}

.content {
  padding-top: var(--page-banner-height);
}

    

Решение проблемы с порядком правил

Использование CSS-переменных позволяет избавиться от проблемы, связанной с порядком CSS-правил одинаковой специфичности. Суть проблемы: в CSS, если два правила имеют одинаковую специфичность, применяется последнее правило в порядке их написания. Это может привести к неожиданным результатам, особенно если вы добавляете стили для разных модификаций одного компонента. Например, здесь порядок правил важен – если вы случайно поменяете их местами, модификация .heading_size-l может не примениться, и вы получите неправильный результат:

        .heading {
  font-size: 1rem;
} 
.heading_size-l {
  font-size: 2rem;
}

    

Используя CSS-переменные, вы определяете значения через свойства, а не жестко задаете их в каждом классе. Здесь порядок определения .heading и .heading_size-l не имеет значения:

        .heading_size-l {
  --heading-font-size: 2rem;
}

.heading {
  font-size: var(--heading-font-size, 1rem);
}

    

Компактные медиазапросы

Использование пользовательских CSS-переменных с медиазапросами упрощает код, делает его компактным и легко поддерживаемым: вместо того, чтобы прописывать стили для каждого элемента внутри медиазапроса, мы определяем переменные в одном месте. Это особенно полезно при работе с адаптивными дизайнами, где размеры, отступы и другие стили зависят от размера экрана:

        .intro__heading {
  font-size: 2rem;
}

.intro__description {
  font-size: 1rem;
}

@media (width >= 641px) {
  .intro__heading {
    font-size: 3rem;
  }

  .intro__description {
    font-size: 2rem;
  }  
}

    

Стилизация чекбоксов с помощью :has()

Селектор :has() помогает создавать гибкие и устойчивые к изменениям в HTML-структуре пользовательские чекбоксы. Этот метод решает одну из основных проблем, возникающих при использовании соседних селекторов (+, ~), которые зависят от фиксированного порядка элементов. До появления :has() для стилизации пользовательских чекбоксов обычно использовали селектор следующего соседа +:

        .cb__input:checked + .cb__label::before {
  /* Стили */
}

    

Этот подход работает, если порядок элементов строго фиксирован (чекбокс всегда идет перед меткой). Если порядок изменится, то стили перестанут работать, так как селектор + не сможет найти следующий элемент:

        <div class="cb">
  <label class="cb__label">Option</label>
  <input type="checkbox" class="cb__input">
</div>

    

Решение проблемы – селектор :has(): он работает независимо от порядка, проверяя только наличие дочернего элемента, удовлетворяющего условию (в данном случае :checked). Этот подход особенно полезен, если структура разметки может изменяться, например, при динамическом рендеринге элементов.

        .cb:has(:checked) .cb__label::before {
  /* CSS of the custom checkbox is here */
}

    
***

Какие еще продвинутые CSS-приемы вы используете в своей ежедневной работе? Поделитесь своим опытом!

***

Хочешь освоить современный Frontend с нуля? Proglib Academy запустили компактный курс: от основ HTML до React.js за 2 месяца с код-ревью от практикующих разработчиков из Газпромбанка и Аэрофлота.

Источники

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
Разработчик C++
Москва, по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ