Статьи

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

cssmasterthumb

Ниже приводится выдержка из нашей книги CSS Master , написанной Тиффани Б. Браун. Копии продаются в магазинах по всему миру, или вы можете купить их в электронном виде здесь .

Спецификация модуля уровня 4 псевдоэлементов CSS проясняет поведение существующих псевдоэлементов и определяет несколько новых. Однако лишь немногие имеют какую-либо степень поддержки в современных браузерах. Вот те, на которых мы сосредоточимся здесь:

::before

вставляет дополнительный сгенерированный контент перед содержимым элемента

::after

вставляет дополнительный сгенерированный контент после содержимого элемента

::first–letter

выбирает первую букву элемента

::first–line

выбирает первую строку элемента

::selection

стили, выбранные курсором

Из них ::first–letter , ::first–line и ::selection влияют на содержимое, являющееся частью источника документа. С другой стороны, псевдоэлементы ::before и ::after внедряют контент в документ, если он не существует в источнике документа. Давайте посмотрим на каждый из этих псевдоэлементов более подробно.

Примечание. Синтаксис с одиночной двоеточием

Вы можете встретить версии с одинарным двоеточием ::first–letter , ::first–line , ::before и ::after в старом CSS. Эти псевдоэлементы были определены в CSS2 с помощью одного : Хотя Internet Explorer 8 требует синтаксиса с одной двоеточием, большинство других браузеров поддерживают обе версии. Рекомендуется использовать синтаксис с двойным двоеточием.

::before и ::after

Большинство псевдоэлементов позволяют нам выбирать контент, который уже является частью источника документа, другими словами, HTML, который вы создали, но не указан языком. Однако с ::before и ::after все работает иначе. Эти псевдоэлементы добавляют сгенерированный контент в дерево документа. Этот контент не существует в источнике HTML, но он доступен визуально.

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

 /* Apply to the label element associated with a required field */ .required::after { content: ' (Required) '; color: #c00; font-size: .8em; } 

Обязательные поля формы используют required свойство HTML. Поскольку эта информация уже доступна для DOM, использование ::before или ::after для добавления вспомогательного текста является дополнительным. Это не критичный контент, поэтому нормально, что он не является частью источника документа.

Примечание. Созданный контент и специальные возможности.

Некоторые комбинации программ чтения с экрана и браузера распознают и читают сгенерированный контент, но большинство этого не делают. Избегайте использования контента, созданного с использованием ::before или ::after того, ::after станет доступным для пользователей вспомогательных технологий. Более подробно об этом можно прочитать в статье Леони Уотсона «Поддержка специальных возможностей для контента, сгенерированного CSS».

Другой вариант использования ::before или ::after — добавление префикса или суффикса к контенту. Возможно, вышеупомянутая форма включает вспомогательный текст, как показано здесь:

 <form method="post" action="/save"> <fieldset> <legend>Change Your Password</legend> <p> <label for="password">Enter a new password</label> <input type="password" id="password" name="password"> </p> <p> <label for="password2">Retype your password</label> <input type="password" id="password2" name="password2"> </p> <p class="helptext">Longer passwords are stronger.</p> <p><button type="submit">Save changes</button></p> </fieldset> </form> 

Давайте заключим наш вспомогательный текст в скобки, используя ::before и ::after :

 .helptext::before { content: '( '; } .helptext::after { content: ')'; } 

Результат показан ниже.

BeforePseudoEl

Возможно, самый полезный способ использовать ::before и ::after — очистить плавающие элементы. Николас Галлахер представил эту технику (которая основана на работе Тьерри Кобленца) в своем посте «Новый взлом микро-ясности»:

 /* Use :before and :after if you need to support IE <= 8 */ .clearfix::before, .clearfix::after { content: " "; /* Note the space between the quotes. */ display: table; } .clearfix::after { clear: both; } того /* Use :before and :after if you need to support IE <= 8 */ .clearfix::before, .clearfix::after { content: " "; /* Note the space between the quotes. */ 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 работает с контентом, который существует как часть источника документа. С его помощью мы можем создавать начальные или буквенные эффекты, как вы можете видеть в журнале или на макете книги.

Примечание: начальная и дроп-заглавная буквы

Начальная заглавная буква — это заглавная буква в начале текста, набранного шрифтом большего размера, чем остальная часть основной копии. Пропущенный капитал аналогичен начальному капиталу, но вставляется в первый абзац как минимум двумя строками.

Этот фрагмент CSS добавляет начальную заглавную букву к каждому элементу p в нашем документе:

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

Результат можно посмотреть ниже.

SelectorsFirstLetterInitial

Как вы, возможно, заметили на этом скриншоте, ::first–letter будет влиять на line-height строки первой строки, если вы установили высоту line-height элемента для элемента. В этом случае каждый элемент p наследует значение line-height 1,5 от элемента body .

Есть три способа смягчить это:

  1. Уменьшите значение line-height для ::first–letter . Значение .5 кажется, работает большую часть времени.

  2. Установите line-height с единицами измерения в ::first–letter .

  3. Установите line-height с единицами измерения в body или родительском элементе ::first–letter .

Первый вариант сохраняет вертикальный ритм, который идет с использованием безлимитной line-height s. [1] Второй вариант ограничивает побочные эффекты использования фиксированной line-height s только этими псевдоэлементами. Третий вариант является худшим из этих вариантов, поскольку существует высокая вероятность того, что вы создадите побочный эффект, для которого требуется больше CSS, чтобы переопределить его.

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

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

Это изменение дает результат, показанный ниже. Обратите внимание, что мы также должны были отрегулировать нижнее поле каждого элемента p чтобы компенсировать уменьшенную line-height p::first-letter .

SelectorsFirstLetterInitial2

Создание капельного капитала требует еще несколько строк CSS. В отличие от начальной заглавной буквы, текст, окружающий букву сбрасываемой заглавной буквы, оборачивается вокруг нее. Это означает, что нам нужно добавить float: left; к нашему набору правил. Мы также добавим верхний, правый и нижний поля:

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

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

SelectorsFirstLetterDrop

Имейте в виду, что ::first-letter может быть сложно стилизовать с точностью до пикселя во всех браузерах, если только вы не используете единицы px или rem для размера, поля и высоты строки.

Иногда первая буква текстового элемента фактически является пунктуацией; например, новость, которая начинается с цитаты:

 <p>&#8220;Lorem ipsum dolor sit amet, consectetur adipiscing elit.&#8221; Fusce odio leo, sollicitudin vel mattis eget, ...</p> 

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

SelectorsFirstLetterAndPunctuation

Однако, это не обязательно, как это работает, когда знак пунктуации генерируется элементом. Рассмотрим следующую разметку:

 <p><q>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</q> Fusce odio leo, sollicitudin vel mattis eget, iaculis sit ...</p> 

Текущие браузеры обычно отображают элемент q с кавычками, соответствующими языку, до и после заключенного текста; однако не все браузеры обрабатывают эти кавычки одинаково. В Firefox 42 (показано ниже), Safari 8 и более ранних версиях ::first-letter влияет только на открывающую кавычку.

SelectorsFirstLetterAndQElement.Firefox

В Chrome, Opera и Яндексе ни начальная кавычка для q ни первая буква абзаца не изменяются. На рисунке ниже показано, как это выглядит в Chrome.

SelectorsFirstLetterAndQElement.Chrome

Однако Internet Explorer применяет стили первой буквы как к открывающей кавычке, так и к первой букве абзаца, как показано ниже.

SelectorsFirstLetterAndQElement.IE

В соответствии со спецификацией модуля уровня 4 псевдоэлементов CSS должна быть включена пунктуация, которая предшествует первой букве или символу или следует за ней; однако в спецификации неясно, относится ли это также к сгенерированной пунктуации. [2]

Ошибки браузера при использовании ::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.5em serif; font-style: italic; color: #673ab7; } 

Вы можете увидеть результат ниже. Обратите внимание, что затрагивается первая строка каждого абзаца, а не первое предложение. Сколько символов умещается в этой первой строке, определяется размером шрифта и шириной элемента.

Первая строка

Можно форсировать конец первой строки, используя элемент br или hr , как показано ниже. К сожалению, это далеко не идеально. Если ваш элемент достаточно широк, чтобы вместить 72 символа, добавление тега <br> после 80-го символа не повлияет на ::first-line . Вы закончите со странно расположенным разрывом строки.

FirstLineForced

Аналогично, использование неразрывного пробела ( &nbsp; ) для предотвращения разрыва строки между словами не повлияет на ::first-line . Вместо этого слово, которое стоит перед &nbsp; будет переведен в ту же строку, что и текст, следующий за ним.

Созданный контент, добавленный с помощью ::before , станет частью первой строки, как показано ниже.

FirstLineWithGeneratedContent

Если сгенерированный текст достаточно длинный, он заполнит всю первую строку. Однако, если мы добавим объявление display: block например, p::before {content: '!!!'; display: block;} p::before {content: '!!!'; display: block;} contentэто содержимое станет первой строкой:

FirstLineWithGeneratedContent2

К сожалению, это еще не работает в Firefox версии 40 или более ранней. Firefox полностью игнорирует набор правил.

Пользовательский интерфейс Fun с ::selection

Псевдоэлемент ::selection является одним из так называемых «выделенных псевдоэлементов», определенных CSS-модулем уровня псевдоэлементов. Уровень 4. Ранее являлся частью спецификации Selectors Level 3, это единственный выделенный псевдоэлемент, реализованный браузерами. [3]

С помощью ::selection мы можем применять стили CSS к контенту, который пользователи выделяют своей мышью. По умолчанию цвет фона и текста выделенного содержимого определяется настройками системы; однако разработчики могут изменить то, как выглядит это выделение, как показано ниже.

Вариант1

Не каждое свойство CSS может использоваться с ::selection . Как указано в спецификации, будут работать только эти свойства:

  • color

  • background-color

  • cursor

  • outline и его расширенные свойства

  • text-decoration и связанные с ним свойства (такие как text-decoration-style )

  • text-emphasis-color

  • text-shadow

С практической точки зрения, только color и color background-color были реализованы в нескольких браузерах. Давайте посмотрим на пример:

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

Этот CSS добавляет светло-зеленый фон к любому элементу, выделенному пользователем, и меняет цвет текста на темно-красный. Пример работает в каждом браузере, который поддерживает ::selection , и вы можете увидеть эффект ниже.

Selectors2

Совет: цветовые комбинации

При выборе цветов переднего плана и фона для использования с ::selection , помните о доступности. Некоторые цветовые комбинации не могут генерировать достаточный контраст, чтобы их могли прочитать пользователи со слабым зрением Другие цветовые комбинации могут быть неразборчивы для дальтоников. Обязательно используйте средство проверки контрастности и симулятор дальтонизма перед выбором окончательных цветов.

Псевдоклассы ::spelling-error и ::grammar-error также определяются модулем псевдоэлементов. Будучи реализованными, эти псевдоклассы позволят нам стилизовать текст с ошибками или неграмотно в соответствии со словарем браузера.


[1] Запись в Mozilla Developer Network для line-height объясняет, почему стоит использовать значения без единиц измерения .

[2] В спецификации фактически используется фраза «типографская буквенная единица». Сюда входят буквы и цифры Юникода, а также символы, используемые в системах письменности Восточной Азии и Ближнего Востока.

[3] В Firefox этот moz- требует префикса ::-moz-selection , например ::-moz-selection .