
Периодически я сталкиваюсь с проблемой — не хочу ставить лишний класс элементу внутри различных кнопок, ссылок и label-ов. Зачастую это текст, который нужно подсветить или галочка чекбокса или маленькая иконка.
Как же справиться с такой проблемой? Тут самым простым и понятным решением будет наследование. Возьмём код ссылки с иконкой, которую нужно анимировать:
<a href="#" class="text_arrow-btn"> <span>Все товары</span> <svg width="37" height="15" viewBox="0 0 37 15" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M0 7.5H36M36 7.5L31.1538 0.5M36 7.5L31.1538 14.5" stroke="#323F4C"></path> </svg> </a>
Сделать это несложно, достаточно просто прописать несколько правил:
/*БАЗОВЫЕ ПРАВИЛА*/ a { text-decoration: none; color: inherit; font-family: sans-serif; } .text_arrow-btn { display: flex; align-items: center; font-size: 22px; line-height: 142%; } /*ИСПОЛЬЗОВАНИЕ НАСЛЕДОВАНИЯ*/ .text_arrow-btn span { /*Для span которые внутри ссылки*/ margin-right: 16px; } .text_arrow-btn svg { /*Для svg которые внутри ссылки*/ transition: transform 0.3s; width: 36px; height: 14px; } .text_arrow-btn:hover span { text-decoration: underline; } .text_arrow-btn:hover svg { transform: translateX(12px); }
Пробел обращается ко всем детям элемента с подходящим селектором. Символ «больше» > обратится только к прямому потомку.
Да, в CSS выглядет не очень, но в SASS всё уже немного приятнее:
a text-decoration: none color: inherit font-family: sans-serif color: #323F4C .text_arrow-btn display: flex align-items: center span margin-right: 16px svg transition: transform 0.3s width: 36px height: 14px path transition: stroke 0.3s &:hover svg transform: translateX(12px) span text-decoration: underline &:active color: #B6B5B5 path stroke: #B6B5B5
Думаю что этим я глаза никому не открыл — вполне стандартная история.
Соседний комбинатор — «+»
Однако, на этом мы не останавливаемся. Теперь другая задача — стилизация чекбокса. Если вы хоть раз сталкивались с этой проблемой, то вы знаете лицо боли. Потому что убрать стандартные стили просто так не получится, получится только убрать чекбокс к чёртовой бабушке и стилизовать заново из div или span. Но чтобы добавить неинтерактивным элементам интерактивности придётся использовать JS. Или не придётся?..
Тут нам поможет волшебный + — это комбинатор родственных элементов. Он объединяет два элемента, находящихся на одном уровне, и второй должен следовать СРАЗУ за первым.
Звучит сложно — работает просто. Выбирается следующий сразу за элементом селектор. Вот так:
<label class="main-checkbox"> <input type="checkbox"> <span> <svg width="13" height="10" viewBox="0 0 13 10" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M1 3.85714L5.30435 9L12 1" stroke="#323F4C"></path> </svg> </span> </label>
.main-checkbox cursor: pointer span display: inline-block width: 24px height: 24px background: #F8F8F8 display: flex align-items: center justify-content: center transition: background 0.3s svg width: 12px height: 9px opacity: 0 transition: opacity 0.3s &:hover span background: #EBEBEB input display: none &:checked+span /*вот он*/ background: #F8F8F8 svg opacity: 1
Обращаем внимание на: &:checked+span тут «+» говорит нам о том, что будет выбран следующий за чекнутым input span. И вуаля — чекбокс работает как часы и он стилизован.
Родственный комбинатор — «~»
Но мы не останавливаемся. Имеем ещё одну задачу: чекбокс у которого внутри идёт span и svg одновременно и нужно при наведении изменить цвет и текста и svg. Да, можно обернуть элементы в div и использовать +, но фу, лишний тег — это полный отстой.
Тут нам поможет тильда ~ (не путать с тильтом). Этот символ не выражает усталость и безысходность — совсем наоборот. Он даёт нам выбрать теги, находящиеся на одном уровне с элементом.
Вот наш чекбокс с иконкой:
<label class="radio-sort"> <input type="checkbox"> <span>По возрастанию цены</span> <svg width="11" height="14" viewBox="0 0 11 14" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M5.5 14V1M5.5 1L10 5.78947M5.5 1L1 5.78947" stroke="#323F4C" /> </svg> </label>
И вот стили:
.radio-sort font-family: sans-serif margin-right: 48px cursor: pointer display: flex align-items: center &:last-child margin-right: 0 input display: none span display: inline-block svg width: 10px height: 14px display: inline-block margin-left: 12px input:checked + span font-weight: 800 input:hover + span color: #1eaf9f input:hover ~ svg path stroke: #1eaf9f
тильда выберет следующий за span svg — очень удобно!
Итак, подведём итог.
Пробел — выберет все дочерние элементы, соответствующие селектору:

Знак больше > выберет только дочерние элементы, являющиеся прямыми потомками:

Знак + выберет следующего за элементом потомка:

Тильда ~ выберет всех одноуровневых потомков:

ссылка на оригинал статьи https://habr.com/ru/post/722962/
Добавить комментарий