Селектори CSS: повний гайд

Привіт:) Цей великий гайд присвячений селекторам CSS: навіщо потрібні, які бувають та приклади їх застосування у реальних задачах.

Зміст

На початку варто познайомитися із поняттями "предок", "дочірній елемент" у HTML-структурі.

Предки, нащадки, батьки та дочірні елементи в HTML

Візьмемо для прикладу найпростішу HTML-розмітку

<html>
  <head>
    <title>Простий документ</title>
  </head>
  <body>
    <h1>Заголовок документу</h1>
    <p>Абзац із <strong>важливим </strong>текстом.</p>
  </body>
 </html>
  • Предок. HTML-елемент, який містить інші елементи, — це предок. У даному випадку це <html>, в той час як <body> — предок для всіх елементів, що містяться в ньому: <h1> , <p> і <strong>.
  • Нащадок. Елемент, розташований усередині одного або більше типів, — нащадок. Тут <body> — нащадок <html>, тоді як <p> — нащадок одночасно і для <body>, і для <html>.
  • Батьківський елемент. Він пов'язаний з іншими елементами нижчого рівня і знаходиться вище у дереві. <html> є батьківським лише для <head> та <body>. Елемент <p> — батьківський по відношенню до <strong>.
  • Дочірній елемент. Елемент, безпосередньо підпорядкований іншому елементу вищого рівня, є дочірнім. Тут <h1> і <p> — дочірні по відношенню до <body>, але <strong> не є дочірнім для <body>, оскільки він розташований безпосередньо всередині елементу <p>, він є дочірнім для цього елементу.
  • Споріднений елемент. Елементи, які є дочірніми для одного і того ж батьківського елементу, називаються спорідненими, як братися або сестри. Вони розташовані поруч один з одним. <head> та <body> — елементи одного рівня, як і <h1> і <p>.
до змісту ↑

Що таке селектори CSS та які бувають

CSS селектори використовуються для вибору (пошуку) HTML-елементів на сторінках сайтів, які потрібно стилізувати. Дозволяють вибрати як цілу групу елементів DOM-дерева, так і більш дрібні за конкретними атрибутами.

Селектори можна класифікувати за 5-ма основними категоріями:

  1. Прості селектори, які дозволяють обирати елементи за їх ім'ям, ідентифікатором або класом.
  2. Комбінаторні селектори обирають елементи на основі їхніх відношень один до одного.
  3. Селектори псевдокласів — вибір елементів за їхнім поточним станом або умовою.
  4. Селектори псевдоелементів, які використовуються для стилізації конкретних частин елементів.
  5. Селектори атрибутів, що дозволяють обирати елементи за наявністю атрибутів або їхніх значень.

Почну із найпростіших.

до змісту ↑

* — універсальний селектор

/* Обрати всі теги */

* {
  margin: 0px;
  padding: 0px;
  border: 0px;
}

Універсальний селектор обирає всі елементи на сторінці. Це означає, що вказаний вище код обере кожен тег на сторінці та застосує до нього 3 вказані CSS-правила стилізації.

Зазвичай застосовується для скидання (очищення) стилів на початку верстки проекту. Не рекомендується використовувати далі у коді, бо досить завантажує браузер клієнта.

За допомогою універсального селектору також можна обирати нащадки елементів.

/* Обрати всі дочірні елементи тегу із id="wrapper" */

#wrapper * {
  padding: 0px 15px 0px 15px;
}


/* Обрати лише прямі нащадки тегу із id="wrapper" */

#wrapper > * {
  padding: 0px 15px 0px 15px;
}
до змісту ↑

#A — вибір за ідентифікатором

#wrapper {
  padding: 0px;
}

Символ решітки дозволяє звернутися до елементу із визначеним унікальним ідентифікатором:

<div id="wrapper">
  ...
</div>
Нагадаю, що ідентифікатор id повинен бути унікальним і використовуватися в межах сторінки лише один раз.
Вибір елементів за ідентифікатором вважається поганою практикою. Використання такого селектора невиправдано через пріоритети стилів браузера. У майбутньому буде досить тяжко його перевизначити, щоб змінити стилі цього елементу. Кращий варіант — селектор за класом.
до змісту ↑

.A — вибір за класом

.wrapper {
  padding: 0px;
}

Обирає HTML-елементи за назвою класу.

Кількість елементів із однаковим класом в межах однієї сторінки може бути будь-якою.
<nav class="nav">
  <a class="nav__link nav__link--active">Головна</a>
  <a class="nav__link" href="#">Друга</a>
  <a class="nav__link" href="#">Третя</a>
  <a class="nav__link" href="#">Четверта</a>
  <a class="nav__link" href="#">Кінцева</a>
</nav>
до змісту ↑

A B — контекстний селектор

Використовують для вибору елементів, які задовольняють певному контексту. Наприклад, є код

<div class="content">
  <p>text 1</p>
  <p>text 2</p>
  <div class="content__body content-body">
    <p>text 3</p>
    <p>text 4</p>
    <div class="content-body__text">
      <p>text 5</p>
    </div>
  </div>
</div>

У ньому потрібно для всіх тегів <p> змінити колір:

.content p {
  color: red;
}
до змісту ↑

AB — контекстний селектор елементу одного рівня

Іноді можна зустріти наступний код

h2.slider__title {
  color: red;
}

Такий код застосується до HTML-елементу

<h2 class="slider__title">Slider Title</h2>

Селектор обере елемент, у якому одночасно присутні тег <h2> та клас .slider__title.

У цьому селекторі нема ніякого смислу, бо то й же результат можна отримати так:

.slider__title {
  color: red;
}

Діло в тому, що у верстці тег заголовку може змінитися із <h2>, наприклад, на <h3>. У цьому випадку конструкція h2.slider__title{} вже не спрацює.

до змісту ↑

A > B — селектор прямого нащадку

Якщо потрібно змінити колір лише для прямих нащадків основного контейнеру (це текст "text 1" та "text 2"):

.content > p {
  color: red;
}

A ~ B — сусідній селектор

Якщо потрібно обрати лише "правих сусідів", тобто на тому ж рівні вкладеності з контейнером <div class="content"></div>. Наприклад:

<p>text 8</p>
<p>text 9</p>
<div class="content">
  <p>text 1</p>
  <p>text 2</p>
  <div class="content__body content-body">
    <p>text 3</p>
    <p>text 4</p>
    <div class="content-body__text">
      <p>text 5</p>
    </div>
  </div>
</div>
<p>text 6</p>
<p>text 7</p>

Наступний код зафарбує наступні рядки: "text 6" та "text 7":

.content ~ p {
  color: red;
}
до змісту ↑

A + B — перший сусідній селектор

Щоб обрати перший сусідній елемент (текст "text 6"):

.content + p {
  color: red;
}

A — селектор за типом (тегом)

Також можна звернутися до елементу за його типом (або тегом).

/* Вибір всіх <div> */

div {
  padding: 15px;
}

/* Вибір всіх <a> */

a {
  color: red;
}

A[title] — селектор за атрибутом

Нехай є блок посилань.

<div class="list">  
  <a class="list__item" href="#" title="Link 1 Title">Link 1</a>
  <a class="list__item" href="#">Link 2</a>
  <a class="list__item" href="#">Link 3</a>
  <a class="list__item" href="#" title="Link 4 Title">Link 4</a>
</div>

Необхідно змінити колір тексту в тих, які мають атрибут title. Наступний код обере перший та останній теги <a>:

/* ВАРІАНТ 1 */

a[title] {
  color: red;
}


/* ВАРІАНТ 2 */

.list__item[title] {
  color: red;
}
до змісту ↑

A[атрибут="значення"] — селектор за конкретним значенням атрибуту

<div class="list">
  <a href="https://site1.com">Link 1</a>
  <a href="https://site2.com">Link 2</a>
  <a href="https://site3.com">Link 3</a>
  <a href="https://site4.com">Link 4</a>
</div>

Нехай потрібно зафарбувати текст посилання, значення href якого рівне "https://site1.com".

a[href="https://site1.com"] {
  color: red;
}

A[атрибут*="значення"] — селектор за групою значень атрибуту

Нехай є група посилань:

<div class="list">
  <a href="https://site-1.com">Link 1</a>
  <a href="https://site2.com">Link 2</a>
  <a href="https://site3.com">Link 3</a>
  <a href="https://site-4.com">Link 4</a>
</div>

У ній потрібно обрати посилання, значення href яких містить "site-".

a[href*="site-"] {
  color: red;
}

A[атрибут^="значення"] — селектор за початком значення атрибуту

Нехай у прикладі вище потрібно вибрати всі елементи <a>, значення href яких починаються із "https://site-". В результаті роботи коду нижче будуть вибрані посилання "Link 1" та "Link 4".

a[href^="https://site-"] {
  color: red;
}

A[атрибут$="значення"] — селектор за кінцем значення атрибуту

Стоїть задача із блоку посилань вибрати усі ті, в яких значення href закінчується символами ".org".

<div class="list">
  <a href="https://site.com">Link 1</a>
  <a href="https://site.net">Link 2</a>
  <a href="https://site.info">Link 3</a>
  <a href="https://site.org">Link 4</a>
  <a href="https://site2.org">Link 5</a>
</div>

Код нижче вибере останні два лінки.

a[href$=".org"] {
  color: red;
}
до змісту ↑

A[атрибут~="значення"] — селектор за значенням атрибуту із пробілами

<div class="list">
  <a href="https://site.com" data-info="Custom Data 1">Link 1</a>
  <a href="https://site.net" data-info="Custom Data 2">Link 2</a>
  <a href="https://site.info" data-info="My Data 3">Link 3</a>
  <a href="https://site.org" data-info="My Data 4">Link 4</a>
  <a href="https://site2.org" data-info="My Data 5">Link 5</a>
</div>

Щоб вибрати всі елементи, у яких значення атрибуту data-info містить вказані символи:

/* Обере перші 2 посилання */

a[data-info~="Custom"] {
  color: red;
}


/* Обере всі посилання */

a[data-info~="Data"] {
  color: red;
}
до змісту ↑

Псевдоклас стану :link використовується для стилізації посилань, на які користувач ще не натискав.

Стан :visited відповідає за посилання, на які користувач натиснув або відвідав.

a:link { 
  color: red; 
}

a:visted { 
  color: blue; 
}

A:checked — селектор відмічених радіокнопки або чекбоксу

input[type=radio]:checked {
  color: red;
}

A::before та X::after — селектори псевдокласів

.about {
  position: relative;
  dispay: block;
  width: 100px;
  height: 100px;
}

.about::before {
  content: "";
  position: absolute;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;
  background-color: red;
}

.about::after {
  content: "";
  position: absolute;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;
  background-color: blue;
}

A:hover — селектор елементу при наведенні курсору миші

div:hover {
  background-color: blue;
}


a:hover {
  text-decoration: underline;
}

A:not(selector) — селектор псевдокласу заперечення

<div class="list">
  <a href="#">Link 1</a>
  <p>Paragraph Text</p>
  <span>Span text</span>
</div>

Нехай для прикладу потрібно вибрати всі елементи у контейнері <div>, за виключенням тегу <a>.

.list:not(a) {
   color: red;
}

Ще один приклад — серед всіх HTML-елементів сторінки вибрати усі, окрім тегу <p>:

*:not(p) {
  color: red;
}
до змісту ↑

A::псевдоелемент — селектор псевдоелементу

<p>Line 1<br>Line 2</p>

Декілька прикладів.

/* Обрати лише рядок "Line 1" */

p::first-line {
   color: red;
}


/* Обрати перший символ тегу <p>: "L" */

p::first-letter {
   color: red;
}

A:first-child та A:last-child — селектори першого та останнього дочірніх елементів

Нехай є список:

<ul>
  <li>Element 1</li>
  <li>Element 2</li>
  <li>Element 3</li>
  <li>Element 4</li>
  <li>Element 5</li>
  <li>Element 6</li>
</ul>

Код нижче вибере перший та останній елементи, тобто <li>:

/* Вибір першого елементу списку */

ul li:first-child {
  color: red;
}


/* Вибір останнього елементу списку */

ul li:last-child {
  color: blue;
}
до змісту ↑

A:only-child — селектор єдиного дочірнього елементу

Дозволяє вибрати лише той елемент, який є єдиним спадкоємцем свого батька.

div p:only-child {
  color: red;
}

У прикладі нижче абзац <p>, який є єдиним спадкоємцем елемента <div>, зафарбується у червоний колір (текст "Text 1").

<div><p>Text 1</p></div>
<div>
   <p>Text 2</p>
   <p>Text 3</p>
</div>
Вибір елементу незалежно від його типу.
до змісту ↑

A:nth-child(n) — селектор конкретного номеру елементу

Щоб вибрати із попереднього прикладу 3-й елемент списку (тобто <li>Element 3</li>):

ul li:nth-child(3) {
   color: red;
}

Селектор у якості параметру приймає число. Відлік ведеться із 1. Також його можна використати і для вибору зразу декількох елементів. Наприклад, потрібно вибрати кожен третій елемент списку. Для цього попередній приклад матиме вигляд:

ul li:nth-child(3n) {
   color: red;
}

Також можна використовувати оператори "+" та "-".

до змісту ↑

A:nth-last-child(n) — селектор конкретного номеру елементу з кінця

Щоб обрати 4-й елемент списку із кінця списку:

ul li:nth-last-child(4) {
  color: red;
}

A:nth-of-type(n) — селектор за місцем серед сусідів з тим самим тегом

Селектор має той самий сенс, що й звичайні :first-child, :last-child і так далі, але під час підрахунку ігноруються елементи з іншими тегами, ніж той, до якого застосовується фільтр.

Бувають випадки, коли замість вибору дочірнього елемента потрібно обрати відповідно до типу елемента.

Наприклад, на сторінці є 5 списків <ul>.

<ul>
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>

<ul>
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>

<ul>
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>

<ul>
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>

<ul>
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>

Потрібно стилізувати лише третій. І у нього немає унікального ідентифікатора (id) та окремого класу. У наведеному прикладі лише у 3-го списку буде рамка.

ul:nth-of-type(3) {
  border: 1px solid red;
}
до змісту ↑

A:nth-last-of-type(n) — селектор за місцем серед сусідів з тим самим тегом з кінця

Код нижче візьме у рамку останній список.

ul:nth-last-of-type(1) {
  border: 1px solid red;
}

A:only-of-type — селектор дочірнього елементу, лише якщо він єдиний у батька

<ul>
  <li>One</li>
</ul>

<ul>
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>

<ul>
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>

Наступний код обере лише <li> у першому <ul>:

ul > li:only-of-type {
  color: red;
}

A:first-of-type — селектор першого спадкоємця вказаного типу

<div>
  <p>Text</p>
  <ul>
    <li>List Item 1</li>
    <li>List Item 2</li>
  </ul>
  <ul>
    <li>List Item 3</li>
    <li>List Item 4</li>
  </ul>   
</div>

Нехай потрібно стилізувати тег <li> із вмістом "List Item 2". Тут є декілька варіантів.

/**
  * СПОСІБ 1
  * 
  * Знайти перший список <ul>, потім його прямого спадкоємця <li>. Далі обрати другий елемент.
  */

ul:first-of-type > li:nth-child(2) {
  color: red;
}


/**
  * СПОСІБ 2
  * 
  * Знайти список <ul> наступний відразу ж за тегом (сусідній) <p>, потім його останній дочірній елемент.
  */

p + ul li:last-child {
  color: red;
}


/**
  * СПОСІБ 3
  * 
  * Знайти перший список <ul>, потім перший елемент списку з кінця.
  */

ul:first-of-type li:nth-last-child(1) {
  color: red;
}
до змісту ↑

A:has — універсальний селектор батьківського елементу або предка

Дозволяє стилізувати батьківський чи предковий елемент. Потім можна його розширити для вибору одного чи декількох сусідів чи дітей. Завдяки йому є можливість стилізувати практично будь-яку комбінацію елементів як окремі елементи чи діапазони.

:has — комбіновані селектори

Селектор :has() можна поєднувати з іншими селекторами для більш складних вибірок. Наприклад, ви можете вибрати всі елементи <div>, які містять зображення з певними класами:

div:has(img.my-class) {
  border: 2px solid blue;
}

:has — псевдокласи

Псевдокласи можна використовувати всередині :has() для більш точної фільтрації. Наприклад, щоб вибрати всі елементи з тегом <a>, але лише ті, що містять зображення:

div:has(a:has(img)) {
  background-color: red;
}

:has — декілька рівнів вкладеності

:has() підтримує декілька рівнів вкладеності. Це робить його потужним інструментом для вибірки глибоко вкладених елементів. Наприклад, щоб обрати всі елемент <div>, які містять <p>, що в свою чергу містять <a>:

div:has(p:has(a)) {
  text-decoration: none;
}

:has — приклади використання

/* Виділити усі цитати <q>, що знаходяться усередині абзацу <p> */

p:has(q) {
  background-color: #fff;
  border-left: 1px solid #888;
  padding: 15px;
}


/* Приховати усі порожні <div> */

div:has(:empty) {
  display: none;
  visibility: hidden;
}


/* Виділити посилання <a> всередині зносок <sup> */

sup:has(a) {
  color: #0066cc;
  text-decoration: underline;
}

Групування селекторів

Для кращої читабельності коду часто селектори групують. Наприклад, є код:

h2 {
  text-align: center;
  color: red;
}

h3 {
 text-align: center;
  color: red;
}

span {
  text-align: center;
  color: red;
}

Його можна скоротити, згрупувавши селектори, та записати так:

h2, h3, span {
  text-align: center;
  color: red;
}

Як браузер читає CSS-селектори

Браузер читає селектори справа наліво. Наприклад:

#main .article p {
  color: red;
}

Він в першу чергу знайде всі <p>, потім вибере лише ті, які лежать усередині .article, а потім залишить тільки ті <p>, що лежать всередині #main.

Це здається нелогічним, але причина такої поведінки в тому, що завдання розробника та браузера дещо відрізняються. Задача розробника — отримати відповідний набір елементів. Із браузером складніше.

Перш ніж змалювати сторінку, браузер будує дерево відображення (render tree). Воно складається з об'єктів відображення — візуальних елементів сторінки, розташованих у тому порядку, в якому вони повинні бути виведені на сторінці. Дерево відображення будується на основі DOM, але в нього не потрапляють невізуальні або сховані елементи на зразок тегу <head> або елементи з display: none, а складним елементам на зразок <select> можуть відповідати декілька об'єктів відображення.

Відображення сторінки виконується у кілька етапів, але нас цікавить лише один — компонування об'єктів відображення. На цьому кроці браузер проходить деревом відображення та розраховує розміри та положення кожного об'єкта на сторінці. Щоб обчислити ці значення для об'єкта, браузеру потрібно знати стилі, які застосовані до цього об'єкта. Для цього йому потрібно знайти в таблиці стилів всі блоки правил, які застосовуються до елемента, що відповідає об'єкту відображення.

Ключова різниця — розробнику потрібно знайти відповідні елементи для CSS-селектора, а браузеру потрібно знайти відповідні CSS-селектори для елемента. У такому разі браузеру набагато ефективніше читати селектор справа наліво, щоб одразу відсіяти більшість невідповідних селекторів.

Розглянемо приклад вище. Припустимо, що браузеру потрібно визначити, чи цей селектор підходить до елемента <div>. Якби браузер читав селектор зліва направо, йому довелося б знайти на сторінці елемент id="main", всередині нього знайти всі елементи з класом .article, а вже потім знайти всередині всі <p> та перевірити, чи є серед них той самий <div>. Це надмірно багато роботи. А завдяки читанню справа наліво браузер може відразу визначити, що <p> і <div> — принципово різні елементи і тому селектор не підходить.

до змісту ↑

Наслідування у CSS

Відступи, поля та границі (серед інших властивостей) не успадковуються вкладеними елементами. Уявіть сторінку, де ви встановили червоний колір шрифту для елемента <body> та зелений колір шрифту для елементу <p>. Тепер припустимо, що всередині абзацу є елемент <strong>. Він успадковує стиль як <body>, так і елемента <p>. То тоді якого кольору буде текст усередині елементу <strong>: червоний чи зелений? Правильна відповідь: зелений колір успадкований від стилю абзацу. Браузер застосує стиль, який є найближчим до форматованого елемента. Будь-які властивості, успадковані від <body>, є скоріше загальними. Вони належать до всіх елементів веб-сторінки. Однак стиль <p> ближчий до <strong> і, можна сказати, знаходиться поруч із ним. Форматування <p> застосовується безпосередньо до абзацу та його вкладених елементів. По суті, якщо елемент не має власного, явно вказаного стилю, то при виникненні конфліктів із успадкованими властивостями переможуть найближчі предки.

body {
  font-family: Arial, Helvetica, sans-serif;
  color: red;
}
p {
  /* Цей колір буде застосований для <strong>, який знаходиться всередині <p> */     
  color: green;
}

Якщо є CSS-стиль, що визначає колір тексту для таблиці <table>, і ще один, що визначає інший колір для комірки <td>, то елементи, вкладені в комірки даної таблиці (<td>) — елементи абзацу, заголовка, маркованого списку — успадкують колір стилю <td>, оскільки він є найближчим предком.

Гіперпосилання, що знаходиться всередині абзацу, текст якого відформатований червоним шрифтом, як і раніше, буде відображено у вікні браузера синім з підкресленням. Це тому, що є власний, попередньо визначений, стиль для елемента прив'язки <a>. Таким чином, успадкований колір тексту не буде застосовано. Тобто для посилань потрібно робити стиль окремо: a {color: black;}.

<head>
  <style>
    body {
      font-family: Arial, Helvetica, sans-serif;
      color: red;
    }
    p {
      color: green;
    }
    strong {
      font-size: 24px;
    }
 </style>
</head>
<body>
  
<!-- Тут текст посилання залишиться синім, тобто за замовчуванням. Хоча вся решта тексту буде зеленою. Властивість font-family все ж буде успадковано.-->

<p>
Текст <strong>текст</strong>, текст <a href="https://site.com/">ТЕКСТ ПОСИЛАННЯ</a>.
</p>
  
</body>

Можна зробити наступним чином. Тут текст посилання буде помаранчевим.

<head>
  <style>
    body {
      color: red;
    }
    p {
      color: green;
    }
    a {
      color: inherit;
    }
    .my-link {
      color: orange;
    }
 </style>
</head>
<body>

<p>
Текст <strong>текст</strong>, текст <a class="my-link" href="https://site.com/">ТЕКСТ ПОСИЛАННЯ</a>.
</p>
  
</body>
до змісту ↑

Скільки "важать" селектори (каскадність, специфічність, пріоритет)

Всі CSS-селектори мають свою вагу, яка визначає як взаємодіють однакові властивості, задані в різних місцях коду одному й тому ж елементу.

Іноді це може створювати труднощі, коли властивість, оголошена нижче в коді, перекривається оголошеною вище, тому що селектор першого специфічніший (має більшу вагу).

Перемагають (мають перевагу) властивості найближчого до форматованого елементу, найспецифічнішого стилю.

Вирішення конфліктів: перемагає останній стиль.

Однак, не завжди зрозуміло, який із селекторів є найбільш специфічним. Для цього CSS пропонує метод визначення пріоритетів. Він ґрунтується на присвоєнні значень в умовних одиницях кожному типу селекторів: селекторам тегів, класам, ідентифікаторам тощо.

  • Загальний селектор (*) має специфічність, рівну 0 умовних одиниць.
  • Селектор тегів (p, body, div, ...) — 1 умовна одиниця.
  • Класс (.class) — 10 умовних одиниць.
  • Атрибут ([attr=value]) — 10 умовних одиниць.
  • Ідентифікатор (#class) — 100 умовних одиниць.
  • Інлайновий(Inline) стиль (style="color: red;") — 1000 умовних одиниць.

Чим більше числове значення, тим вища специфічність (значимість) цього типу селектора. Припустимо, ви створили три стилі:

  • стиль тегу для елементу <img> (специфічність = 1);
  • клас з іменем .highlight (10);
  • ідентифікатор з іменем #logo (100).

Веб-сторінка містить наступний HTML-код:

<img id="logo" class="highlight" src="logo.gif">

Якщо визначити однаковий атрибут у всіх трьох стилях (наприклад, властивість border), то буде застосований стиль ідентифікатора (#logo) як найбільш специфічний.

p .email { 
  color: blue; 
}

.byline a { 
  color: red; /* Цей стиль буде застосований, бо вказаний останнім у таблиці стилів. */
}

<p class="byline">Створено <a class="email" href="mailto:test@site.com">Михайлом Петровим</a></p>

Тепер уявіть, що два стилі помінялися місцями, і таблиця стилів має такий вигляд:

.byline a { 
  color: red; 
}

p .email { 
  color: blue; 
}

У даному випадку посилання буде синім. Стиль із селектором p .email розташований у таблиці після рядка .byline a, тому його властивості мають перевагу.

Ще приклад:

#class-3 {
  color: green;
}

.class-1 {
  color: red;
}

.class-2 {
  color: blue;
}
<div class="class-1 class-2">
  <!--
    Блок буде синім, бо .class-1 та .class-2 мають однаковий пріоритет (специфічність).
    А тому застосовується той, який у CSS-стилях вказаний нижче.
  -->
</div>

<div class="class-2 class-1">
  <!--
    Блок буде синім, бо .class-1 та .class-2 мають однаковий пріоритет (специфічність).
    А тому застосовується той, який у CSS-стилях вказаний нижче.
  -->
</div>

<div class="class-1 class-2" id="class-3">
  <!--
    Блок буде зеленим. Вибірка за id вища за пріоритетом за .class-1 та .class-2.
  -->
</div>

<div class="class-2 class-1" id="class-3">
  <!--
    Блок буде зеленим. Вибірка за id вища за пріоритетом за .class-1 та .class-2.
  -->
</div>

<div style="color:hotpink;" class="class-2 class-1" id="class-3">
  <!--
    Блок буде рожевим. Inline-стиль вищий за пріоритетом.
  -->
</div>
до змісту ↑

Анулювання специфічності

Каскадні таблиці стилів дозволяють повністю скасувати специфічність стилів. Ви можете використовувати цей прийом, щоб ніякий інший більш специфічний стиль не замінив конкретну властивість елементу веб-сторінки. Для цього вставте після необхідної властивості значення !important.

Розглянемо приклад. Нехай існує два стилі:

.nav a { 
  color: red; 
}
  
a { 
  color: blue !important; 
}

За замовчуванням посилання, вкладене в елемент із класом .nav, було б червоного кольору, оскільки стиль, визначений селектором .nav а, біль специфічніший, аніж селектор тегу <a>. Однак додавання слова !important передбачає, що ця властивість завжди матиме більший пріоритет. Так, у наведеному вище прикладі всі посилання веб-сторінки, у тому числі вкладені з класом .nav, будуть відображені синім кольором.

Зауважу, що !important застосовується до окремої властивості, а не до всього стилю, тому потрібно додати слово !important в кінці кожної властивості, яка не повинна бути заміщена.

Коли для двох однакових властивостей різних стилів вказана директива !important, знову набирає чинності правило специфічності, та пріоритет має більш специфічний атрибут із зазначених.

Будьте обережні, застосовуючи !important. Оскільки цей спосіб кардинальний, при надто частому його використанні ваші стилі не відповідатимуть звичайним правилам каскаду, що призведе до "ескалації" використання мітки !important. Іншими словами, щоб компенсувати специфічність властивості з !important в одному стилі, ви будете використовувати її в іншому. Потім, щоб компенсувати дію !important у другому стилі, вам доведеться додати його до третього стилю і т.п. Тому не рекомендую використовувати !important занадто часто. Перш ніж додавати цю директиву, спробуйте інший спосіб подолати конфлікт, наприклад, перейменуйте або поміняйте місцями стилі в таблиці.
до змісту ↑

Чи існує якийсь спосіб наочного відображення впливу механізму каскадності на кінцевий дизайн веб-сторінки

У правій частині панелі інструментів розробника (DevTools) ви побачите стилі, застосовані до конкретного елемента. Зазвичай це кінцевий стиль, тобто підсумок усіх CSS-властивостей, застосованих до елемента шляхом успадкування та каскадування. Трохи нижче будуть показані правила стилів, застосовані до елемента, перелічені в порядку від більш специфічних (у верхній частині списку) до менш (у нижній частині списку). Найімовірніше, ви побачите, що в переліку стилів деякі властивості закреслені. Це свідчить про те, що ці властивості або не застосовуються до елементу, або були заміщені більш специфічним стилем.

до змісту ↑

Що станеться, якщо є конфліктуючі стилі (або їхні властивості) у зовнішній та внутрішній таблицях стилів

У цьому випадку важлива послідовність їх розміщення на веб-сторінці (в HTML-коді файлу). Якщо ви спочатку додаєте внутрішню таблицю, використовуючи елемент style, а потім приєднуєте зовнішню таблицю за допомогою елемента link, то буде застосований стиль останньої. Висновок: будьте послідовними у розміщенні в коді веб-сторінки посилання на зовнішню таблицю стилів. Спочатку її потрібно приєднати, а лише потім додавати внутрішні стилі, якщо абсолютно неможливо обійтися без одного або декількох стилів, що застосовуються до однієї сторінки.

до змісту ↑

Приклади із практики

Готові рішення, які використовую у своїй роботі.

Відступ справа елементів списку, крім останнього (приклад 1)

<ul class="menu__list">
  <li class="menu__item"><a href="" class="menu__link">Home</a></li>
  <li class="menu__item"><a href="" class="menu__link">Product</a></li>
  <li class="menu__item"><a href="" class="menu__link">Pricing</a></li>
  <li class="menu__item"><a href="" class="menu__link">Contact</a></li>
</ul>
.menu__item:not(:last-child) {
  margin: 0px 21px 0px 0px;
}

Відступ справа елементів списку, крім останнього (приклад 2)

<form class="form" action="/" method="POST">
    <div class="form__group">
        <p>Ім'я</p>
        <input class="input" type="text" placeholder="Михайло">
    </div>
    <div class="form__group">
        <p>Телефон</p>
        <input class="input input--dark input--phone" type="tel" placeholder="+380 XX XXX-XX-XX">
    </div>
    <div class="form__group">
        <p>E-mail</p>
        <input class="input input--dark input--email" type="email" placeholder="Приклад: petrov@example.com">
    </div>
    <div class="form__group">
        <p>Повідомлення</p>
        <input class="input input--dark input--message" type="text" placeholder="Напишіть ваше повідомлення"><!-- Тут потрібно було забрати відступ знизу -->
    </div>
    <button class="form__btn" type="submit">Відправити</button>
</form>
/* Last form__group form block, before submit button */

.form__group:last-of-type input {
  margin-bottom: 0;
}
до змісту ↑

Вибір атрибуту placeholder у формі

input[type="text"]::-webkit-input-placeholder,
input[type="text"]::-ms-input-placeholder,
input[type="text"]::-moz-placeholder,
input[type="text"]::placeholder {
  // щось робимо
}

Вибрати перший дочірній HTML-елемент, незалежно від його типу

<div class="footer__contacts">
  <p>2942 Westheimer Rd. Santa Ana, Illinois 89486 </p>
  <a href="tel:+380957777777">+38 (095) 777 77 77</a>
</div>
/* Для елементу <p> застосується відступ у 34px. */

.footer__contacts > *:first-child {
  margin-right: 34px;
}

Обрати всі дочірні елементи блоку, незалежно від їх типу, і якщо для них не задано окремих класів

<div class="parent-block">
  <li></li>
  <li></li>
  <a></a>
  <div></div>
</div>
/* Всім дочірнім елементам батьківського блоку з класом parent-block буде заданий правий відступ 10px. */

.parent-block > * { /* або parent-block * */
  margin-right: 10px;
}

Як стилізувати посилання без класу

Робочий приклад дивіться в одному із попередніх моїх постів "Як стилізувати лише посилання без класу".

Джерело

Михайло Петров
Михайло Петров

Мене звати Михайло. Я — WordPress-розробник. Створюю візитки, корпоративні сайти, блоги на WordPress.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *