Псевдоклассы
Псевдокласс выбирает элемент не по тегу или классу, а по его состоянию или положению: «элемент под курсором», «первый в списке», «отмеченный флажок». Его пишут после селектора через двоеточие, без пробела. Такие стили меняются сами, без единой строки JavaScript.
Наведение и нажатие
:hover срабатывает, пока над элементом находится курсор мыши, :active — в момент нажатия:
<style>
.button {
padding: 8px 16px;
border: 0;
border-radius: 8px;
background: rebeccapurple;
color: white;
}
.button:hover { background: indigo; }
.button:active { background: black; }
</style>
<button class="button">Наведите и нажмите</button>На телефоне курсора нет, поэтому важное действие нельзя прятать только за :hover.
Фокус
Элемент в фокусе — тот, с которым сейчас работает пользователь: поле, в котором мигает курсор, или кнопка, выбранная клавишей Tab. :focus срабатывает при любом фокусе, :focus-visible — только когда фокус важно показать, например при работе с клавиатуры:
<style>
input:focus { outline: 3px solid gold; }
button:focus-visible { outline: 3px solid deeppink; }
</style>
<input placeholder="Щёлкните сюда">
<button>Нажмите Tab, чтобы дойти до меня</button>Ссылки
У ссылок есть свои состояния: :link — ещё не посещённая, :visited — уже открытая. Их пишут в порядке link, visited, hover, active — иначе нижнее правило перекроет верхнее:
<style>
a:link { color: royalblue; }
a:visited { color: purple; }
a:hover { color: crimson; }
</style>
<p><a href="#nowhere">Наведите на ссылку</a></p>Положение среди соседей
Структурные псевдоклассы выбирают элемент по месту среди братьев — элементов с тем же родителем:
<style>
li:first-child { font-weight: 700; }
li:last-child { color: crimson; }
li:nth-child(even) { background: whitesmoke; }
</style>
<ul>
<li>Первый</li>
<li>Второй</li>
<li>Третий</li>
<li>Четвёртый</li>
</ul>| Псевдокласс | Что выбирает |
|---|---|
:first-child | первый элемент |
:last-child | последний элемент |
:nth-child(3) | третий элемент |
:nth-child(odd) | нечётные: 1, 3, 5… |
:nth-child(even) | чётные: 2, 4, 6… |
:nth-child(3n) | каждый третий |
Исключение
:not() выбирает все элементы, кроме указанных в скобках. Удобно, чтобы добавить линию между пунктами, но не после последнего:
<style>
li:not(:last-child) { border-bottom: 1px solid silver; }
</style>
<ul>
<li>Яблоки</li>
<li>Груши</li>
<li>Сливы</li>
</ul>Состояния полей формы
:checked выбирает отмеченный флажок или переключатель, :disabled — выключенное поле:
<style>
input:checked + label { color: seagreen; font-weight: 700; }
input:disabled { background: gainsboro; }
</style>
<input type="checkbox" id="news" checked> <label for="news">Подписка на новости</label>
<p><input disabled placeholder="Недоступно"></p>Знак + выбирает элемент, который идёт сразу за предыдущим: здесь — подпись после флажка. Снимите галочку, и подпись станет обычной.
Частая ошибка
:first-child проверяет, первый ли элемент среди всех соседей, а не среди элементов этого тега. Если перед абзацем стоит заголовок, p:first-child не сработает. Для этого есть :first-of-type — первый среди своего тега:
<style>
p:first-child { color: crimson; }
p:first-of-type { font-weight: 700; }
</style>
<div>
<h3>Заголовок</h3>
<p>Не красный: первым идёт h3. Но жирный — первый абзац.</p>
<p>Второй абзац.</p>
</div>