Сложные селекторы с состояниями ссылок на CSS
Все сложные селекторы, которые мы изучали ранее, можно применять и для ссылок.
Давайте посмотрим на примере. Пусть наши
ссылки находятся в блоке с заданным id
:
<div>
<a href="#">ссылка</a>
<a href="#">ссылка</a>
<a href="#">ссылка</a>
</div>
Давайте зададим стили для ссылок из этого блока:
#block a:link, #block a:visited {
color: red;
}
#block a:hover {
text-decoration: none;
}
Как правило, состояния link
и visited
не разделяют, поэтому код можно упростить
следующим образом:
#block a {
color: red;
}
#block a:hover {
text-decoration: none;
}
Ссылка с классом
Пусть теперь сами ссылки имеют класс:
<a href="#">ссылка</a>
<a href="#">ссылка</a>
<a href="#">ссылка</a>
Давайте зададим стили для ссылок, имеющих такой класс:
a:link. eee, a:visited.eee {
color: red;
}
a:hover.eee {
text-decoration: none;
}
Не имеет значения в каком порядке писать класс ссылки и псевдоклассы состояний. Можно переставить их местами и от этого ничего не изменится:
a.eee:link, a.eee:visited {
color: red;
}
a.eee:hover {
text-decoration: none;
}
Практические задачи
Расскажите, что выбирает селектор в приведенном ниже коде. Затем напишите HTML код, подходящий под этот селектор. Вот код с селектором:
a {
color: red;
}
a:hover {
text-decoration: none;
}
Расскажите, что выбирает селектор в приведенном ниже коде. Затем напишите HTML код, подходящий под этот селектор. Вот код с селектором:
a.zzz {
color: red;
}
a.zzz:hover {
text-decoration: none;
}
Расскажите, что выбирает селектор в приведенном ниже коде. Затем напишите HTML код, подходящий под этот селектор. Вот код с селектором:
#block a.zzz {
color: red;
}
#block a.zzz:hover {
text-decoration: none;
}
Расскажите, что выбирает селектор в приведенном ниже коде. Затем напишите HTML код, подходящий под этот селектор. Вот код с селектором:
.block a.zzz {
color: red;
}
.block a.zzz:hover {
text-decoration: none;
}
Простой CSS • Селекторы: подводные камни
Селекторы по ID #
Все селекторы в CSS имеют свой вес, например, селектор по классу весит больше, чем селектор по тегу. Это означает, что если два блока стилей перекрывают друг друга, выиграет тот, у кого тяжелее селектор. Подробнее об этом можно почитать тут.
Селектор по ID — самый тяжелый из всех, а это означает, что если вы задали стили по ID (например,
#header A
), переопределить их будет довольно сложно: для этого потребуется!important
или ещё один селектор с ID.При дальнейшем развитии такого кода проблемы специфичности селекторов буду возникать постоянно, такой код будет очень трудно поддерживать, поэтому постарайтесь не использовать для стилизации селекторы по ID.
Составные селекторы #
Такие селекторы следует использовать с осторожностью. Во-первых, по причине специфичности: например, чтобы перебить селектор из двух классов, вам так же придется использовать селектор как минимум из двух классов или
!important
.Во-вторых, понять к чему применится селектор из двух и более частей без подглядывания в разметку может быть затруднительно, а переходы между файлами занимают время и замедляют процесс вёрстки.
Например, сравните:
.post .header SPAN
и.post__author
. У второго селектора ниже специфичность, сразу понятно что это за элемент, а кроме того, стили применятся только к элементам с таким классом, не затрагивая все прочие спаны, которые есть там сейчас, и которые могут появиться там в будущем.Пример может показаться несколько синтетическим, и на простых страницах он не вызовет особых проблем, но в крупных проектах блоки страницы могут иметь очень развесистую структуру, и там сложные селекторы могут оказаться легким способом выстрелить себе в ногу.
Проблему составных селекторов хорошо решает методология именования классов по БЭМ. При её грамотном использовании представление о разметке можно получить не выходя из CSS, а необходимость использовать сложные селекторы возникает крайне редко.
Код с простыми селекторами удобнее читать и приятнее поддерживать, постарайтесь сохранять ваш код простым и легко читаемым.
nth-child
иnth-of-type
#С этими и подобными селекторами очень интересно играться, но в долгоживущих проектах их лучше не использовать из-за проблем с читабельностью: не заглядывая в код не всегда можно понять куда целится селектор. Если таких селекторов в коде много, придётся каждый раз выяснять куда целится каждый из них.
Использование таких селекторов вместо классов выглядит заманчивой идеей, но развивать и поддерживать такой код может быть неудобно. Лучше использовать БЭМ-классы с модификаторами.
Исключением могут быть совсем простые случаи, когда надо, например, покрасить строки таблицы через одну. Это удобно делать с помощью
nth-child(odd)
.
Дополнительные селекторы
В последних нескольких уроках были рассмотрены основные понятия CSS. В этом уроке мы начнем отходить от уже известного нам контента и приступим к изучению более продвинутой теории, начиная с продвинутых селекторов.
Расширенные селекторы относятся к селекторам CSS, которые делают что-то более сложное, чем выбор тега, класса или идентификатора. Это включает в себя выбор типа тега внутри другого тега или выбор элемента с определенным идентификатором или классом, но только при наведении на него мышки.
Обязательное видео
Расширенные селекторыПродолжая серию видео DevTips «Основы CSS» на YouTube, посмотрите следующее видео о продвинутых селекторах CSS:
youtube.com/embed/oh3JLo2yxCM?rel=0&showinfo=0&start=7″ frameborder=»0″ allow=»autoplay; encrypted-media» allowfullscreen=»»/>Расширенные селекторы
Для справки, вот пример обсуждаемых расширенных типов и форматов селекторов. в видео:
Селектор Stacking
Селектор Stacking выбирает несколько типов элементов. Элементы перечислены в той же строке, что и правило CSS, разделенные запятой, например:
а, сильный { красный цвет; }
В этом примере все теги
и
будут окрашены в красный цвет. Селекторы стекирования помогают сохранить таблицы стилей СУХИМИ, применяя одинаковые стили к нескольким элементам в одном правиле.
Селектор All/Universal
Селектор all
*
. Он выбирает всего в HTML:* { маржа: 0; }
Чаще всего используется для сброса стилей браузера по умолчанию. Например, в приведенном выше примере поле
каждого элемента сбрасывается до 0
.
Селектор потомков
Список нескольких селекторов с пробелом между ними создает селектор потомков , например:
li a { красный цвет; }
Это правило превратит все теги
, которые являются дочерними тегами
теги красные.
ли ли { красный цвет; }
Во втором примере
тега вложены в
тега, из которых также вложены в другой
тег красного цвета.
Классы и идентификаторы элементов также могут использоваться в селекторах потомков. Например, это сделало бы дочерние элементы Обратите внимание на разницу между селекторы потомков и селекторы с накоплением . Как видите, разделение двух селекторов пробелом и запятой приводит к совершенно разным результатам! Селектор прямого потомка выбирает дочерние элементы, вложенные в один слой глубоко внутри DOM. Обозначается символом Если бы это правило применялось к следующему HTML-коду, один Смежный селектор , обозначенный символом Мы можем использовать родственный комбинатор , добавив символ Будет выбран любой абзац после Псевдоклассы предназначены только для элементов, когда они находятся в определенном состоянии или взаимодействуют с ними определенным образом. Например, это правило будет применяться только к Знайте, как быстро распознать селектор псевдокласса, но пока не беспокойтесь об их использовании. Мы изучим их позже. Мы также можем использовать несколько расширенных селекторов в одном правиле. Проверьте это: Мы используем соседний селектор с псевдоклассом . Результат? При наведении курсора на элемент с классом Независимо от того, решите ли вы полностью написать свой собственный CSS, или использовать фреймворк, или вам необходимо создавать в системе дизайна — понимание селекторов, каскада и специфики имеет решающее значение для разработки CSS и изменение существующих правил стиля. Вероятно, вы хорошо знакомы с созданием селекторов CSS на основе идентификаторов, классов и типов элементов. И вы, вероятно, часто использовали символ скромного пробела для выбора потомков. В этой мини-серии, состоящей из двух частей, мы рассмотрим некоторые из более сложных селекторов CSS и примеры их использования. Ключевой концепцией для успешной настройки селекторов CSS является понимание того, что известно как специфика CSS, и «C» в CSS, что является каскадом. Специфичность — это вес, который применяется к данному объявлению CSS, определяемый номером каждого типа селектора в соответствующем селекторе. Когда несколько объявлений имеют одинаковую специфичность, к элементу применяется последнее объявление, найденное в CSS. Специфичность применяется только тогда, когда один и тот же элемент предназначен для нескольких объявлений. Согласно правилам CSS, непосредственно целевые элементы всегда будут иметь приоритет над правилами, которые элемент наследует от своего предка. — Документы MDN Правильное использование специфичности каскада и селектора означает, что вы сможете полностью избежать использования Повышение специфичности происходит в результате переопределения наследования от каскада. В качестве небольшого примера — какого цвета будет диапазон.элемент { .item { Это не означает добавлять Ключевая концепция : Чем выше специфичность, тем труднее обойти правило. Каждый проект уникален по своим потребностям с точки зрения повторного использования правил. Желание поделиться правилами с низкой специфичностью привело к появлению фреймворков, основанных на утилитах CSS, таких как Tailwind и Bulma. С другой стороны, желание жестко контролировать наследование и специфичность, например, в системе проектирования, делает популярными соглашения об именах, такие как БЭМ. В этих системах родительский селектор тесно связан с дочерними селекторами для создания повторно используемых компонентов, которые создают свой собственный пузырь специфичности. Если вы думаете: «Мне не нужно их изучать, потому что я использую фреймворк/систему дизайна», то вы сильно ограничиваете себя в плане использования CSS в полной мере. Прелесть языка заключается в создании элегантных селекторов, которые делают ровно столько, сколько достаточно , и позволяют создавать аккуратные маленькие таблицы стилей. Универсальный селектор — Раньше были рекомендации против его использования, особенно в качестве потомка, из-за проблем с производительностью, но это больше не является действительным соображением. На самом деле, это не было проблемой более десяти лет. Вместо этого позаботьтесь о размере вашего пакета JS и об оптимизации изображений, а не об улучшении селекторов CSS из соображений производительности 😉 Лучшая причина использовать его с осторожностью заключается в том, что он имеет нулевую специфичность при использовании сам по себе, что означает, что его можно переопределить с помощью одного селектора идентификатора, класса или элемента. Мое наиболее частое использование в качестве моего самого первого правила сброса CSS: Это означает, что мы хотим, чтобы все элементы включали отступов и границ в расчете блочной модели вместо добавления этих значений ширины к любым определенным размерам. Например, в следующем правиле Другое очень полезное приложение было рекомендовано Энди Беллом и Хейдоном Пикерингом на их сайте и в книге Every Layout и называется «Стек», который в самом простом виде выглядит так: При использовании с правилом сброса или родительским правилом, которое уменьшает все поля элемента до нуля, это применяет верхнее поле ко всем элементам , которые следуют за другим элементом . Это быстрый способ набрать вертикальный ритм. Если вы хотите быть немного более — ну, избирательным — тогда мне нравится использовать его в качестве потомка в определенных обстоятельствах, таких как следующие: Это похоже на идею стека, но больше ориентировано на элементы заголовков, чтобы обеспечить немного больше передышки между разделами контента. Это чрезвычайно мощная категория, но часто не используется в полной мере. Знаете ли вы, что можно добиться результатов сопоставления, аналогичных регулярному выражению, используя селекторы атрибутов CSS? Это исключительно полезно для изменения систем в стиле БЭМ или других сред, которые используют связанные имена классов, но, возможно, не используют одно общее имя класса. Давайте посмотрим на примере: Этот селектор выберет все элементы, класс которых содержит строку «component_», что означает, что она будет соответствовать «component_title» и «component_content». И вы можете убедиться, что совпадение нечувствительно к регистру, включив Но вам не нужно указывать значение атрибута, вы можете просто проверить его наличие, например: Что бы выбрать все Просмотрите документы MDN для всех возможных способов сопоставления значений в селекторах атрибутов. Эти селекторы можно использовать для выполнения некоторых базовых анализов специальных возможностей, таких как следующие: Это добавит контур ко всем изображениям, которые не включают 9Атрибут 0031 alt
. класса
красным: div .emphasis {
красный цвет;
}
Селектор прямого потомка
>
. Левая сторона символа содержит родителя, а правая сторона содержит прямого потомка, на которого мы ориентируемся, например: .контейнер > ул {
граница: 4 пикселя сплошного красного цвета;
}
имел бы красную рамку, а другой — нет, потому что только один является прямым потомком элемента div с контейнером
класса
: ...
<дел>
// Этот
будет иметь красную рамку, потому что он вложен непосредственно в
// родитель с классом 'контейнер':
<ул>
*НЕ* будет иметь красную рамку, потому что это не напрямую
// внутри div-контейнера:
<ул>
Смежный селектор
+
, изолирует элементы определенного типа, но только если они непосредственно следуют за другим определенным типом. Например, приведенное ниже правило сделает содержимое
элементов красным, а — только , если они сразу следуют за
:
ul + p {
красный цвет;
}
Sibling Combinator
~
между двумя элементами в селекторе, например: ul ~ p {
красный цвет;
}
. Любой
до
не будет наследовать стиль. Обратите внимание, что он отличается от соседнего селектора тем, что ко всем тегам
, следующим за
, будет применен стиль, а не только к самому ближайшему.
Псевдоклассы
элементам, когда над ними находится курсор: a:hover {
текстовое оформление: нет;
}
Объединение нескольких расширенных селекторов
.peeka:hover + .boo {
дисплей: блок;
}
peeka
этот стиль будет применен к элементу с классом boo
сразу после него. Дополнительные ресурсы
Руководство по продвинутым селекторам CSS — часть первая
Часть первая (эта статья):
#*
[атрибут]
>
~
+
Часть вторая:
# :checked / :focus
::before / ::after
Специфика CSS и каскад
# !important
в своих таблицах стилей. .item
?
Элемент
#specific . item {
цвет: красный;
}
цвет: зеленый;
}
цвет: синий;
} .item
будет красным , потому что специфичность включения #id
в селектор выигрывает у каскада и над селектором элемента. #ids
ко всем вашим элементам и селекторам, а скорее осознавать их влияние на специфичность. Универсальный переключатель
#*
— назван так потому, что применяется ко всем элементам универсально. Практическое применение универсального селектора
# Сброс блочной модели CSS
*,
*::before,
*::after {
box-sizing: border-box;
} .box
будет иметь ширину 200 пикселей
, а не 200 пикселей + 20 пикселей
от заполнения: .box {
ширина: 200 пикселей;
отступ: 10 пикселей;
} Вертикальный ритм
* + * {
margin-top: 1. 5rem;
} ст*+h3 {
margin-top:4rem;
} Селектор атрибутов
# [класс*="компонент_"]
i
перед закрытием селектора атрибутов: [класс*="component_" я]
а[класс]
a
(элементы связи), которые имеют любое значение класса . Практическое применение селекторов атрибутов
# Помощь в анализе специальных возможностей
img:not([alt]) {
контур: 2 пикселя сплошной красный;
}
Присоединение к Aria для обеспечения специальных возможностей
Селекторы атрибутов также могут помочь обеспечить доступность, если они используются в качестве селектора только , из-за чего отсутствие атрибута препятствует соответствующему стилю. Один из способов сделать это — присоединить к обязательным атрибутам aria
Одним из примеров является реализация взаимодействия аккордеона, когда вам нужно включить следующую кнопку, независимо от того, переключается ли логическое значение aria через JavaScript:
Связанный CSS может затем использовать aria-expanded
в качестве селектора атрибутов вместе с соседним родственным комбинатором, чтобы открыть или закрыть связанное содержимое:
button[aria-expanded="false"] + .content {
/* скрытые стили */
}
button[aria-expanded="true"] + .content {
/* видимые стили */
}
Стилизация некнопочных навигационных ссылок
При работе с навигацией у вас может быть смесь ссылок по умолчанию и ссылок, стилизованных под «кнопки». В этом случае может быть очень полезно использовать следующее для выбора некнопочных ссылок:
навигация: не ([класс])
Удалить стиль списка по умолчанию
Еще один совет, который я начал использовать от Энди Белла и его современного сброса CSS, заключается в удалении стиля списка на основе наличия атрибута роли
:
/* Удалить стили списка для элементов ul, ol с ролью списка,
что предполагает удаление стилей по умолчанию */
ul[role="list"],
ol[role="list"] {
list-style : никто;
}
Детский комбинатор
# Селектор дочернего комбинатора — >
— очень эффективен для добавления небольшого количества специфичности, чтобы уменьшить область применения стилей к потомкам элементов. Это единственный селектор, который работает с уровнями элементов и может быть объединен для выбора вложенных элементов.
Дочерний комбинатор определяет стиль потомка от любого потомка, который соответствует дочернему селектору, до только прямых потомков .
Другими словами, тогда как article p
выбирает все p
внутри article
, article > p
выбирает только те абзацы, которые находятся непосредственно внутри статьи, не вложенные в другие элементы.
✅ Выбрано с статьей > стр
Привет, мир
🚫 Не выбрано с артикулом > p
Привет, мир
Практическое применение детского комбинатора
#Вложенные ссылки списка навигации
Рассмотрим список навигации на боковой панели, например, для сайта документации, где есть вложенные уровни ссылок. Семантически это означает внешний ul
, а также вложенный ul
внутри li
.
Для визуальной иерархии вы, вероятно, захотите оформить ссылки верхнего уровня иначе, чем вложенные ссылки. Чтобы настроить таргетинг только на ссылки верхнего уровня, вы можете использовать следующее:
nav > ul > li > a {
вес шрифта: полужирный;
}
Вот CodePen, где вы можете поэкспериментировать с тем, что произойдет, если вы удалите любой из дочерних комбинаторов в этом селекторе.
Селекторы элементов области видимости
Мне нравится использовать селекторы элементов для основных вещей в моих макетах страниц, таких как верхний колонтитул
или нижний колонтитул
. Но у вас могут возникнуть проблемы, поскольку эти элементы являются действительными дочерними элементами некоторых других элементов, таких как 9.0031 нижний колонтитул внутри цитаты
или статьи
.
В этом случае вы можете изменить footer
на body > footer
.
Стилизация встроенного/стороннего контента
Иногда вы действительно не можете контролировать имена классов, идентификаторы или даже разметку. Например, для рекламы или другого контента на основе JavaScript (не iframe).
В этом случае вы можете столкнуться с морем элементов div или span, и в этом случае дочерний комбинатор может быть очень полезен для присоединения стилей к разным уровням содержимого.
Обратите внимание, что многие другие рассмотренные селекторы также могут помочь в этом сценарии, но только дочерний комбинатор работает с уровнями и может влиять на вложенные элементы.
Комбинатор общего назначения
# Общий комбинатор родственных элементов — ~
— выбирает определенные элементы, расположенные где-то после предшествующего (ранее определенного) элемента и находящиеся внутри одного и того же родителя .
Например, p ~ img
будет стилизовать все изображения, расположенные где-то после абзаца, при условии, что они имеют одного и того же родителя.
Это означает, что будут выбраны все следующие изображения:
Абзац
Заголовок 2
png" alt="Image" />
Заголовок 3
Но , а не изображение в этом сценарии:
Абзац
Скорее всего, вы хотели бы быть немного более конкретным (см. также: смежный комбинатор родственных элементов), и этот селектор, как правило, чаще всего используется в творческих упражнениях по программированию, таких как моя игра CommitSweeper на чистом CSS.
Практическое применение универсального одноуровневого комбинатора
#Визуальная индикация изменения состояния
Объединение общего родственного комбинатора с селекторами псевдоклассов с отслеживанием состояния, такими как :checked
может дать интересные результаты.
Учитывая следующий HTML-код для флажка:
Мы можем изменить стиль абзацев терминов, используя общий комбинатор родственных элементов , только когда установлен флажок:
#terms:checked ~ p {
стиль шрифта: курсив;
цвет: #797979;
}
Вариации с низкой специфичностью
Если мы также воспользуемся универсальным селектором, мы сможем быстро создать небольшие вариации, например, для простых макетов карт.
Вместо того, чтобы перемещать содержимое между вложенными элементами div и из них с помощью классов для изменения расположения заголовка и абзацев, мы можем использовать общий комбинатор родственных элементов для создания следующих вариантов.
Правило добавляет небольшое поле, уменьшает размер шрифта и осветляет цвет текста для любого элемента, следующего за изображением:
img ~ * {
размер шрифта: 0.9rem;
цвет: #797979;
поля: 1rem 1rem 0;
}
Вы можете поэкспериментировать с этими общими результатами комбинатора родственных элементов в этом CodePen.
Это правило имеет крайне низкую специфичность, поэтому его можно легко переопределить, добавив более точное правило.
Кроме того, поскольку оно применяется только в том случае, если элементы являются общими прямыми потомками родительского элемента изображения (в данном случае это li
), после переноса содержимого в другой элемент правило будет применяться только до тех пор, пока наследование не будет использоваться дочерними элементами. Чтобы лучше понять это, попробуйте обернуть содержимое последнего элемента карточки в div. Цвет и поля будут унаследованы на div
и элементы type, но собственный стиль браузера для h4
предотвращает наследование размера шрифта
из общего родственного комбинатора, поскольку собственное правило браузера имеет более высокую специфичность, чем универсальный селектор, который технически нацелен на . раздел
.
Соседний одноуровневый комбинатор
# Комбинатор соседнего элемента — +
— выбирает элемент, который следует непосредственно за предшествующим (ранее определенным) элементом.
Мы уже использовали это в примерах универсального селектора — * + *
— чтобы применить верхнее поле только к элементам, которые следуют за другим элементом — так что давайте перейдем к другим примерам!
Практическое применение смежного комбинатора одноуровневых элементов
#Polyfill For Lack для поддержки Flexbox Gap в навигации
Поддержка разрываFlexbox находится в разработке, но на момент написания статьи она еще не была доступна в Safari, за исключением предварительной версии технологии.
Итак, в случае чего-то вроде навигации по веб-сайту, где гибкая компоновка очень полезна, мы можем использовать смежный комбинатор родственных элементов, чтобы помочь добавить поле в качестве полифилла для промежутка
.
nav ul li + li {
margin-left: 2rem;
}
Что обеспечивает эффект разрыва между элементами списка без необходимости очищать дополнительное поле для первого:
Применение интервалов между метками формы и входными данными
Теория, применяемая в «стеке», который мы исследовали для универсальных селекторов, заключается в применении поля только в одном направлении.
Мы можем использовать эту идею для формирования объектов полей, чтобы обеспечить достаточное расстояние для сохранения визуальной иерархии между типами полей. В этом случае мы добавляем гораздо меньший отступ между меткой и ее входными данными и больший отступ между входными данными и метками:
.label + input {
margin-top: 0.