Пошук уроків, статей та іншого контенту
Вивчите псевдокласи для стилізації станів елементів, взаємодії користувача та їхнього положення в DOM.
Псевдоклас — це спеціальне слово після двокрапки, яке описує певний стан елемента або його положення в структурі HTML.
селектор:псевдоклас {
властивість: значення;
}Наприклад:
button:hover {
background-color: blue;
}Це правило застосовується до кнопки, коли користувач наводить на неї курсор.
Псевдокласи не додають нові елементи в HTML. Вони дають змогу стилізувати елементи залежно від:
дій користувача;
стану форми;
наявності або відсутності дочірніх елементів;
положення елемента серед сусідів у DOM.
:hoverПсевдоклас :hover застосовується, коли вказівник миші перебуває над елементом.
.button:hover {
background-color: #1d4ed8;
color: white;
}Цей псевдоклас часто використовують для кнопок, посилань і пунктів меню.
:active:active описує момент активної взаємодії з елементом. Наприклад, для кнопки це короткий момент між натисканням і відпусканням кнопки миші.
.button:active {
transform: scale(0.98);
}Так можна створити ефект натискання кнопки.
:focus:focus застосовується до елемента, який отримав фокус. Наприклад, коли користувач натиснув на поле введення або перейшов до нього клавішею Tab.
input:focus {
border-color: #2563eb;
outline: 3px solid #bfdbfe;
}Фокус особливо важливий для доступності. Користувачі, які не використовують мишу, повинні бачити, який елемент зараз активний.
Не варто бездумно прибирати стандартний контур фокусу:
/* Небажано: користувач може втратити видимий індикатор фокусу */
input {
outline: none;
}Якщо потрібно змінити стандартний контур, створіть інший помітний стиль:
input:focus {
outline: 2px solid #2563eb;
outline-offset: 2px;
}:focus-visible:focus-visible застосовує стиль фокусу тоді, коли браузер визначає, що користувачеві потрібно його показати. Найчастіше це відбувається під час навігації клавіатурою.
.button:focus-visible {
outline: 3px solid #f59e0b;
outline-offset: 3px;
}Цей псевдоклас допомагає відрізнити фокус клавіатури від фокусу після звичайного кліку.
:visited:visited стилізує посилання, яке користувач уже відвідав.
a:visited {
color: #7c3aed;
}Псевдоклас застосовується саме до посилань із атрибутом href.
Для :visited браузери обмежують набір CSS-властивостей, які можна змінювати. Найчастіше використовують color.
Для посилань часто використовують такі стани:
a:link {
color: #2563eb;
}
a:visited {
color: #7c3aed;
}
a:hover {
color: #1d4ed8;
}
a:active {
color: #dc2626;
}Порядок важливий: пізніше правило може перекрити раніше, якщо селектори мають однакову специфічність.
:checked:checked застосовується до позначених прапорців і вибраних перемикачів.
input[type="checkbox"]:checked + label {
color: #15803d;
font-weight: bold;
}Селектор + означає «безпосередній наступний сусід». У цьому прикладі правило змінює label, який іде одразу після позначеного input.
:disabled:disabled вибирає вимкнені елементи форми.
button:disabled {
cursor: not-allowed;
opacity: 0.5;
}Елемент із атрибутом disabled не можна використати у звичайний спосіб.
:enabled:enabled вибирає доступні для взаємодії елементи форми.
input:enabled {
background-color: white;
}Зазвичай цей псевдоклас не потрібен, адже звичайний селектор уже вибирає активні елементи. Проте він може бути корисним, коли потрібно явно розділити стилі доступних і вимкнених контролів.
:required і :optional:required вибирає обов’язкові поля форми, а :optional — необов’язкові.
input:required {
border-left: 4px solid #dc2626;
}
input:optional {
border-left: 4px solid #9ca3af;
}Псевдоклас визначається на основі атрибута required.
<input type="email" required>
<input type="text">:valid і :invalidЦі псевдокласи показують, чи відповідає значення поля правилам валідації HTML.
input:valid {
border-color: #16a34a;
}
input:invalid {
border-color: #dc2626;
}Наприклад, поле з type="email" вважається невалідним, якщо введене значення не схоже на адресу електронної пошти.
Щоб поле не виглядало невалідним одразу після завантаження сторінки, можна використовувати :placeholder-shown:
input:not(:placeholder-shown):invalid {
border-color: #dc2626;
}Це правило застосовується до не порожнього поля, яке не пройшло перевірку.
Псевдокласи структури визначають положення елемента серед його батьківського елемента та сусідів.
:first-child:first-child вибирає елемент, який є першою дитиною свого батьківського елемента.
li:first-child {
font-weight: bold;
}HTML:
<ul>
<li>Перший пункт</li>
<li>Другий пункт</li>
</ul>У цьому прикладі жирним буде лише перший li.
Важливо: :first-child перевіряє першу дитину незалежно від її типу.
<div>
<h2>Заголовок</h2>
<p>Текст</p>
</div>У такій структурі p:first-child не спрацює, адже першим дочірнім елементом є h2.
:last-child:last-child вибирає елемент, який є останньою дитиною свого батьківського елемента.
li:last-child {
border-bottom: none;
}Це часто використовують, щоб прибрати нижню межу в останнього пункту списку.
:only-child:only-child вибирає елемент, який є єдиною дитиною свого батьківського елемента.
.message:only-child {
margin: 0;
}Правило спрацює лише тоді, коли в батьківському елементі немає інших дочірніх елементів.
:nth-child():nth-child() вибирає елементи за їхнім порядковим номером серед усіх дочірніх елементів.
li:nth-child(2) {
color: #2563eb;
}Це правило вибере другий дочірній елемент, якщо він є li.
Можна вибрати кілька елементів за допомогою ключових слів:
li:nth-child(odd) {
background-color: #f8fafc;
}
li:nth-child(even) {
background-color: #e0f2fe;
}odd — непарні позиції: 1, 3, 5;
even — парні позиції: 2, 4, 6.
Також можна використовувати формули:
li:nth-child(3n) {
color: #dc2626;
}Формула 3n вибирає кожен третій елемент: 3, 6, 9 і так далі.
li:nth-child(3n + 1) {
font-weight: bold;
}Це вибирає елементи з позиціями 1, 4, 7 і так далі.
:first-of-type і :last-of-type:first-of-type вибирає перший елемент певного типу серед сусідів, а :last-of-type — останній.
p:first-of-type {
color: #2563eb;
}
p:last-of-type {
color: #15803d;
}Розглянемо структуру:
<article>
<h2>Заголовок</h2>
<p>Перший абзац</p>
<p>Останній абзац</p>
</article>p:first-of-type вибере перший p, навіть якщо перед ним розташований h2.
Це відрізняється від :first-child:
:first-child перевіряє позицію серед усіх дітей;
:first-of-type перевіряє позицію серед елементів такого самого типу.
У наступному прикладі використано псевдокласи стану, форми та структури.
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Псевдокласи</title>
<style>
:root {
font-family: Arial, sans-serif;
color: #1f2937;
background-color: #f3f4f6;
}
body {
max-width: 720px;
margin: 0 auto;
padding: 32px 16px;
}
.card {
padding: 24px;
background-color: white;
border-radius: 12px;
box-shadow: 0 4px 12px rgb(0 0 0 / 10%);
}
.button {
padding: 10px 16px;
border: 0;
border-radius: 6px;
color: white;
background-color: #2563eb;
cursor: pointer;
}
.button:hover {
background-color: #1d4ed8;
}
.button:active {
transform: scale(0.98);
}
.button:focus-visible {
outline: 3px solid #f59e0b;
outline-offset: 3px;
}
input[type="email"] {
display: block;
width: 100%;
box-sizing: border-box;
margin: 8px 0 16px;
padding: 10px;
border: 2px solid #d1d5db;
border-radius: 6px;
}
input[type="email"]:focus {
border-color: #2563eb;
outline: 3px solid #bfdbfe;
}
input[type="email"]:not(:placeholder-shown):invalid {
border-color: #dc2626;
}
input[type="email"]:valid {
border-color: #16a34a;
}
input[type="checkbox"]:checked + label {
color: #15803d;
font-weight: bold;
}
.features {
padding: 0;
list-style: none;
}
.features li {
padding: 10px;
border-bottom: 1px solid #d1d5db;
}
.features li:last-child {
border-bottom: 0;
}
.features li:nth-child(even) {
background-color: #eff6ff;
}
.features li:first-child {
font-weight: bold;
}
</style>
</head>
<body>
<main class="card">
<h1>Підписка на новини</h1>
<p>Заповніть форму, щоб отримувати нові матеріали.</p>
<form>
<label for="email">Електронна пошта</label>
<input
id="email"
name="email"
type="email"
placeholder="you@example.com"
required
>
<input id="agreement" type="checkbox">
<label for="agreement">Я погоджуюся отримувати новини</label>
<p>
<button class="button" type="submit">Підписатися</button>
</p>
</form>
<h2>Переваги підписки</h2>
<ul class="features">
<li>Нові уроки щотижня</li>
<li>Практичні приклади</li>
<li>Корисні підказки</li>
</ul>
</main>
</body>
</html>У прикладі:
кнопка змінюється при наведенні через :hover;
під час натискання кнопка трохи зменшується через :active;
фокус клавіатури позначається через :focus-visible;
поле електронної пошти має різний колір для валідного та невалідного значення;
текст біля позначеного прапорця змінюється через :checked;
кожен парний пункт списку має інший фон через :nth-child(even);
у першого пункту змінюється насиченість шрифту;
у останнього пункту прибирається нижня межа через :last-child.
:nth-child() і :nth-of-type()Ці псевдокласи часто плутають.
<section>
<h2>Новини</h2>
<p>Перший абзац</p>
<p>Другий абзац</p>
</section>p:nth-child(1) {
color: red;
}
p:nth-of-type(1) {
color: blue;
}p:nth-child(1) не спрацює, тому що першим дочірнім елементом section є h2.
p:nth-of-type(1) спрацює, тому що це перший елемент типу p.
Використовуйте:
:nth-child() — коли важлива позиція серед усіх дітей;
:nth-of-type() — коли важлива позиція серед елементів одного типу.
До одного елемента можна застосовувати кілька псевдокласів.
button:hover:focus {
background-color: #1e40af;
}Це правило застосовується до кнопки, яка одночасно перебуває під курсором і має фокус.
Псевдоклас також можна комбінувати зі звичайними селекторами:
.form-field input:required:invalid {
border-color: #dc2626;
}Або використовувати у складнішому селекторі:
.card p:first-of-type {
font-size: 1.1rem;
}Тут вибирається перший абзац усередині елемента з класом card.
:not():not() вибирає елементи, які не відповідають переданому селектору.
li:not(:last-child) {
margin-bottom: 8px;
}Це правило додає нижній відступ усім пунктам, крім останнього.
Інший приклад:
input:not([type="checkbox"]) {
padding: 10px;
}Правило застосовується до всіх input, крім прапорців.
:not() особливо зручний, коли потрібно стилізувати більшість елементів, але виключити один або кілька випадків.
:first-child із першим елементом потрібного типуp:first-child {
color: blue;
}Це не означає «перший абзац». Це означає «абзац, який є першою дитиною батьківського елемента».
Для першого абзацу серед інших абзаців використовуйте:
p:first-of-type {
color: blue;
}:hover для важливих дійНа сенсорних пристроях наведення курсору може бути недоступним. Крім того, користувачі клавіатури не бачать стан :hover.
Для кнопок і посилань подбайте також про:
.button:hover {
background-color: #1d4ed8;
}
.button:focus-visible {
outline: 3px solid #f59e0b;
}*:focus {
outline: none;
}Таке правило ускладнює навігацію клавіатурою. Якщо змінюєте стандартний стиль фокусу, замініть його власним помітним оформленням.
Якщо кілька правил мають однакову специфічність, перевагу має правило, яке записане нижче.
a:hover {
color: red;
}
a:active {
color: green;
}Під час активного натискання застосовується правило :active, оскільки воно розташоване пізніше.
:nth-child()p:nth-child(2) {
color: red;
}Це вибере p лише тоді, коли він є другим дочірнім елементом загалом. Якщо перед ним є h2, div або інший елемент, результат може бути неочікуваним.
Псевдокласи описують стан елемента або його положення в DOM.
:hover, :active, :focus і :focus-visible використовують для стилізації взаємодії користувача.
:checked, :disabled, :required, :valid і :invalid описують стани елементів форми.
:first-child, :last-child, :only-child і :nth-child() залежать від положення елемента серед дочірніх елементів.
:first-of-type і :last-of-type враховують лише елементи такого самого типу.
:not() дає змогу виключити елементи з вибірки.
Не прибирайте видимий фокус без доступної заміни.
Для роботи зі структурою завжди перевіряйте, чи потрібна позиція серед усіх дітей (:nth-child()), чи лише серед елементів одного типу (:nth-of-type()).