Селектори CSS: псевдоелементи

35

Від автора: специфікація CSS Pseudo-elements Module Level 4 проливає світло на поведінку існуючих псевдоелемент і надає нові. Тим не менш, лише кілька з нових псевдоелемент мають хоч якусь підтримку в останніх версіях браузерів.

Сьогодні ми поговоримо про наступні псевдоэлементах:

::before — вставляє генерований контент перед контентом елемента

::after — вставляє контент генерується після контенту елемента

::first-letter — обирає першу букву елемента

::first-line — обирає першу рядок елемента

::selection — стилізує текст, виділений курсором

З них елементи ::first–letter, ::first–line і ::selection впливають на контент, який входить в исходники. Псевдоелементи ::before ::after, навпаки, вставляють контент в документ, якого немає в исходниках. Розберемо детальніше всі псевдоелементи.

Зауваження: синтаксис з одним двокрапкою

Ви могли бачити версії ::first–letter, ::first–line, ::before ::after з одним двокрапкою в старому CSS. В CSS2 ці псевдоелементи задавалися через одноразове двокрапка :. IE8 вимагає синтаксис з одинарним двокрапкою, хоча велика частина інших браузерів підтримує обидва варіанти. Краще використовувати синтаксис з подвійним двокрапкою.

Псевдоелементи ::before ::after

Велика частина псевдоелемент дозволяє вибирати контент, який вже присутній в исходниках документа, але не заданий за допомогою мови (іншими словами, ваш HTML). Однак ::before ::after працюють по-іншому. Ці псевдоелементи додають контент генерується в дерево документа. Створений контент не існує в HTML основи, але він відображається.

Навіщо використовувати генерований контент? Наприклад, можна позначати обов’язкові поля форми, додаючи контент після лейблів:

/* Застосовується до лейблу, ассоциирующемуся з необхідним поля */
.required::after {
content: ‘(Required) ‘;
color: #c00;
font-size: .8em;
}

В потрібному полі форми необхідно використовувати HTML властивість required. Так як дана інформація вже доступна в DOM ::before ::after виступають у ролі помічників. Це не критичний контент, тому його можна і не вносити в исходники.

Зауваження: генерований контент і доступність

Деякі скрін рідери і браузери розпізнають і читають створений контент, однак більша частина цього не вміє. Не використовуйте псевдоелементи ::before ::after для надання генерованого контенту для користувачів з обмеженими можливостями. Більш докладно це питання можна вивчити в статті Leonie Watson «підтримка доступності для генерованого CSS контенту».

Інший спосіб застосування ::before ::after – додавання префікса або суфікса в контент. Вищезгадана форма може використовувати допоміжний текст, як показано нижче:

Change Your Password

Enter a new password

Retype your password

Longer passwords are stronger.

Save changes

Укладемо наш допоміжний текст у парні дужки з допомогою ::before ::after.

.helptext::before {
content: ‘( ‘;
}
.helptext::after {
content: ‘)’;
}

Результат.

CSS селекторы: псевдоэлементы

Можливо, найкорисніший спосіб застосування ::before ::after – очищення обтічних елементів. Nicolas Gallagher представив цю техніку (яка заснована на роботі Thierry Koblentz) у своєму пості «новий мікро clearfix хак»:

/* Для підтримки IE <= 9 використовуйте :before :after */
.clearfix::before,
.clearfix::after {
content: «»; /* Зверніть увагу на пробіл між лапок. */
display: table;
}
.clearfix::after {
clear: both;
}

Додайте клас clearfix до будь-якого елемента, який необхідно очистити після обтікання елемента.

Псевдокласи ::before ::after ведуть себе повністю, як дочірні елементи тега, за яким вони закріплені. Вони успадковують всі можливі властивості батьків і розташовані всередині блоку батьків. Вони також взаємодіють з іншими блоковими елементами, як якщо б вони були справжніми тегами. Властивості display: block або display: table ::before ::after працюють точно так само, як і на інших елементах.

Попередження: один псевдоэлемент на селектор

На даний момент на один селектор дозволяється застосовувати тільки один псевдоэлемент. Тобто запис типу p::first-line::before неправильна.

Створення друкарських ефектів з допомогою :first-letter

Псевдоелементи ::before ::after вставляють контент, а ::first-letter працює з контентом, вже прописаний в исходниках. З його допомогою можна створювати ефект першої літери або буквиці, який ви могли бачити в журналах і книгах.

Зауваження: перша буква і буквиці

Ефект першої літери – це буква у верхньому регістрі на початку тексту, якою встановлено більший розмір шрифту по відношенню до решти тексту. Буквиця схожа на першу букву, однак буквиця вставляється в перший параграф з мінімум двох рядків.

Стилі нижче додають першу, заголовну літеру в усі параграфи p в документі:

p::first-letter {
font-family: serif;
font-weight: bold;
font-size: 3em;
font-style: italic;
color: #3f51b5;
}

CSS селекторы: псевдоэлементы

З скріншота можна помітити, що ::first-letter змінює line-height першого рядка, якщо елементу значення line-height без одиниць вимірювання. В даному випадку всі теги p успадковують значення line-height 1.5 від тега body.

Існує три способи згладити цю проблему:

зменшити значення line-height для псевдоэлемента ::first–letter, майже завжди підійде значення .5;

задати line-height з одиницями вимірювання для псевдоэлемента ::first–letter;

задати line-height з одиницями вимірювання для body або батька ::first–letter.

Перший варіант зберігає вертикальний ритм, як у випадку зі значенням line-height без одиниць вимірювання. Другий варіант обмежує сторонні ефекти фіксованого line-height до самих псевдоелемент. Третій варіант – найгірший, є велика ймовірність того, що ви створите побічний ефект, який потрібно буде переписувати з допомогою додаткового CSS коду.

У нашому випадку давайте зменшимо значення line-height для p::first-letter до .5 (і перепишемо властивості у файлі, будемо використовувати скорочену властивість font):

p::first-letter {
font: bold italic 3em / .5 serif;
color: #3f51b5;
}

Результат можна подивитися нижче. Зауважте, що нам також потрібно було налаштувати нижній margin кожного параграфа p, щоб компенсувати зменшене значення line-height на p::first-letter.

CSS селекторы: псевдоэлементы

Для створення буквиці знадобиться трохи більше рядків CSS. На відміну від перших великих літер, прилеглий текст до буквиці обтікає її. Тобто нам потрібно додати float: left; в наші стилі. Також ми додамо верхній, правий і нижній margin:

p::first-letter {
font: bold italic 3em / .5 serif;
font-style: italic;
color: #607d8b;
float: left;
margin: 0.2 em 0.25 em .01em 0;
}

Плаваючий елемент, або в нашому випадку псевдоэлемент, змушує інший текст обтікає його, як показано нижче.

CSS селекторы: псевдоэлементы

Якщо ви не використовуєте px або rem для установки розмірів, margin) і line-height, буде дуже складно ідеально стилізувати ::first-letter у всіх браузерах.

Іноді в якості першої літери текстового елемента виступає знак пунктуації. Наприклад, новина, що починається з цитати:

«Lorem ipsum dolor sit amet, consectetur adipiscing elit.» Fusce odio leo, sollicitudin vel mattis eget, …

В даному випадку стилі для: first-letter будуть застосовані як до відкриваючої кавычке, так і до першої букві, як показано нижче. Стилі застосовуються однаково у всіх браузерах.

CSS селекторы: псевдоэлементы

Тим не менш, результат буде відрізнятися, коли знак пунктуації генерується елементом. Розглянемо наступну розмітку:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce odio leo, sollicitudin vel mattis eget, iaculis sit …

На даний момент браузери отрисовывают тег q у вигляді лапок, які використовуються в певній мові, які будуть відкриватися і закриватися. Однак не всі браузери однаково розпізнають такі лапки. У Firefox 42 (див. нижче), Safari 8 і більш ранніх версіях ::first-letter змінює тільки відкриває лапки.

CSS селекторы: псевдоэлементы

У Chrome, Opera і Yandex відкриваючі лапки тега q і перша буква параграфа не стилизуются. Нижче показаний скріншот в Chrome.

CSS селекторы: псевдоэлементы

IE застосовує стилі як до відкриваючої кавычке, так і до першої букві параграфа. Дивіться нижче.

CSS селекторы: псевдоэлементы

В специфікації CSS Pseudo-elements Module Level 4 говориться, що знак пунктуації, попередній або наступний відразу після першої букви або символу повинен стилізуватися. Однак у специфікації немає точного роз’яснення щодо застосування стилів до утворюваним знаків пунктуації.

Баги браузерів при використанні ::first-letter

По більшій частині ::first-letter працює у всіх браузерах рівно так, як очікуєш. Як і з усіма CSS властивості, у даного псевдоэлемента є парочка помилок і випадків неправильного використання, про які потрібно знати.

У Firefox 39 і раніше деякі символи змушують Firefox ігнорувати правило ::first–letter: ‑,$,^,_,+,`,~,>,<.

Це відноситься до випадків, коли перший символ задано через ::before і властивість content, а також якщо він прописаний в исходниках документа. Фікса цього бага немає. Якщо використовуєте ::first-letter, вам доведеться уникати цих символів на початку параграфа.

Зауваження: помилки в Blink браузерах

Деякі версії Blink браузерів не застосують правило ::first–letter, якщо у батьків встановлено властивість display зі значенням inline або table. Баг є в Chrome 42, Opera 29 і Yandex 15. Баг пофиксили в Chrome 44, однак реліз побачить світ не раніше, ніж ця книга виявиться у вас в руках. Найпростіший спосіб обійти баг – додати до батьків властивість display: inline-block, display: block або display: table-cell.

Створення друкарських ефектів з допомогою ::first-line

Псевдоклас ::first-line працює майже як:first-letter, тільки ефект поширюється на всю першу рядок елемента. Можна, наприклад, робити перший рядок кожного параграфа більше і змінювати колір тексту:

p::first-line {
font: bold 1.5 em serif;
font-style: italic;
color: #673ab7;
}

Результат можна подивитися нижче. Зауважте, що змінам піддалася перший рядок кожного параграфа, а не перша пропозиція. Кількість символів, вміщається на першої рядку визначається розміром шрифту і шириною елемента.

CSS селекторы: псевдоэлементы

Можна примусово поставити кінець першого рядка з допомогою br або hr, як показано нижче. На жаль, це не завжди працює. Якщо ваш елемент може вмістити лише 72 символу, то тег br після 80-го символу ніяк не вплине на псевдоэлемент ::first-line. Ви просто отримаєте дивний розрив рядка.

CSS селекторы: псевдоэлементы

Точно так само і з нерозривним пробілом ( ), який вставляється, щоб не розривати слова між рядків. Це ніяк не вплине на ::first-line. Слово, яке розташоване перед буде примусово переміщений на рядок, де розташований текст після нерозривного пробілу.

Генерований контент, доданий ::before, буде відображатися на першому рядку, як показано нижче.

CSS селекторы: псевдоэлементы

Якщо створюваний текст досить довгий, він повністю заповнить перший рядок. Однак якщо додати display: block (наприклад, p::before {content: ‘!!!’; display: block;}), то контент займе всю першу рядок.

CSS селекторы: псевдоэлементы

На жаль, цей баг досі є в Firefox 40 і більш ранніх версіях. Firefox повністю ігнорує правило.

Забавні інтерфейси за допомогою ::selection

Псевдоэлемент ::selection відноситься до так званих «подсвечивающим» псевдоелемент, прописаним в специфікації CSS Pseudo-Elements Module Level 4. Даний підсвічує псевдоэлемент раніше входив в специфікацію Selectors Level 3, єдиний, поддерживающийся в браузерах.

З допомогою ::selection можна застосовувати CSS стилі до контенту, виділеного мишкою. За замовчуванням фон і колір тексту виділеного контенту задаються системою. Однак розробники можуть змінювати ці налаштування, як показано нижче.

CSS селекторы: псевдоэлементы

::Selection можна використовувати не всі властивості. У специфікації прописані тільки наступні властивості:

color

background-color

cursor

outline і розширені властивості

text-decoration і асоціюються властивості (такі як text-decoration-style)

text-emphasis-color

text-shadow

На практиці тільки color і background-color реалізовані в браузерах. Розберемо приклад:

::selection {
background: #9f0;
color: #600;
}

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

CSS селекторы: псевдоэлементы

Порада: комбінації кольорів

Пам’ятайте про доступності при виборі кольору переднього тла і заднього фону ::selection. Деякі комбінації кольорів дають поганий контраст для слабо бачать людей. Інші комбінації можуть бути нерозбірливими для дальтоніків. Перед кінцевим вибором кольорів використовуйте інструмент перевірки контрасту і симулятор дальтонізму.

У Pseudo-Elements Module також прописані псевдокласи ::spelling-error ::grammar-error. Коли вони будуть реалізовані, ми зможемо стилізувати текст з помилками, перевіряються за словником браузера.