Псевдоэлементы и псевдоклассы css – Как работают псевдоклассы в CSS. Подробное объяснение с примерами и диаграммами

Псевдоклассы и псевдоэлементы в CSS и примеры их использования

Цель урока:Рассмотрение понятия «медиа-запросы» для создания отзывчивой верстки. Знакомство с псевдоклассами и псевдоэлементами в CSS. Рассмотрены примеры создания стилей

Медиа-запросы в CSS

Медиа-запросы — логическое выражение, которое может быть равно истине (true) или лжи (false)

Условием является либо параметры устройства, на котором отображается веб-страница, либо размеры экрана пользователя.

Медиа-запрос записывается либо в стилевом файле, либо во вложенном стиле и имеет следующую структуру:

all — все устройста. Может быть screen | print | tv

max-widthмедиа функция, которая может задавать параметры указанного устройства или разрешение экрана

В примере устройство с максимальным разрешением экрана — 480px и с минимальным — 320px:

Из примера видно, что функции могут содержать логические условия: AND — И, NOT — НЕ и ONLY — только

Медиа-запросы логично размещать после всех описанных стилей

Псевдоклассы в CSS

Псевдоклассы определяют динамическое состояние элементов, которое изменяется с помощью действий пользователя.

Важно: На псевдокласс указывает наличие двоеточия (:)

  • Три псевдокласса определены именно для гиперссылки (для тега a):
  • a:link{...} /* для ссылки непосещенной */
    a:visited{...} /* для посещенной ссылки */
    a:active{...} /* для активной ссылки, в момент щелчка */

    a:link{...} /* для ссылки непосещенной */ a:visited{...} /* для посещенной ссылки */ a:active{...} /* для активной ссылки, в момент щелчка */

    * active — псевдокласс не только для гиперссылки

  • Псевдоклассы для всех элементов:
  • элемент:hover{...} /* по наведению курсора на элемент */

    элемент:hover{...} /* по наведению курсора на элемент */

  • Псевдоклассы для всех элементов управления:
  • input:focus{...} /* в тот момент, когда элемент получает фокус */
    input:active{...}/* в момент активации элемента */

    input:focus{...} /* в тот момент, когда элемент получает фокус */ input:active{...}/* в момент активации элемента */

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


    Выполнение:
    .el1:focus { outline: thick solid black } 
    .el1:active { outline: thick solid red }

    .el1:focus { outline: thick solid black } .el1:active { outline: thick solid red }

    </style> 
    </head>
    <body> 
    <input type="text" value="щелкни по мне">

    </style> </head> <body> <input type="text" value="щелкни по мне">

    Результат:

    Псевдоэлементы CSS

    Псевдоэлементы позволяют, во-первых, задать стиль некоторых частей элементов, которые не определены в дереве элементов документа, а, во-вторых, генерировать содержимое, которого нет в исходном коде текста.

    Псевоэлементы, определяющие новые элементы:

    элемент:first-letter {...}/* первая буква или символ элемента */
    элемент:first-line {...}/* первая строка элемента */

    элемент:first-letter {...}/* первая буква или символ элемента */ элемент:first-line {...}/* первая строка элемента */

    Пример: Для первой строки параграфа применить курсивный стиль шрифта, первую букву абзаца сделать красным цветом


    Выполнение:
    .f1:first-letter {color: red}
    .f1:first-line {font-style: italic}

    .f1:first-letter {color: red} .f1:first-line {font-style: italic}

    </style> 
    </head> 
    <body> 
    <p>К этому тексту применен стиль. К этому тексту применен стиль. К этому тексту применен стиль. 
    К этому тексту применен стиль. К этому тексту применен стиль.
    </p>

    </style> </head> <body> <p>К этому тексту применен стиль. К этому тексту применен стиль. К этому тексту применен стиль. К этому тексту применен стиль. К этому тексту применен стиль. </p>

    Результат:

    Псевоэлементы, генерирующие содержимое:

    элемент:before {content:""}/* генерирует текст перед элементом */
    элемент:after {content:""} /* генерирует текст после элемента */

    элемент:before {content:""}/* генерирует текст перед элементом */ элемент:after {content:""} /* генерирует текст после элемента */

    Пример: К содержимому абзаца с классом new добавить дополнительное слово — Ого!.


    Выполнение:
    p.new:after{
    	content: "- Ого!"
    	}

    p.new:after{ content: "- Ого!" }

    </style> 
    </head>
    <body> 
    <p>Ловля льва в пустыне с помощью метода золотого сечения.</p>
    <p>Метод ловли льва простым перебором.</p>

    </style> </head> <body> <p>Ловля льва в пустыне с помощью метода золотого сечения.</p> <p>Метод ловли льва простым перебором.</p>

    Результат:

    Пример: Для маркированного списка убрать маркер и установить вместо него какой-либо символ


    Выполнение:
    ul { 
        list-style-type: none; /* Прячем маркеры списка */ 
    } 
    li:before { 
    content: "\20aa  "; /* Добавляем перед элементом списка символ в юникоде */ 
    }

    ul { list-style-type: none; /* Прячем маркеры списка */ } li:before { content: "\20aa "; /* Добавляем перед элементом списка символ в юникоде */ }

    </style>
    </head> 
    <body> 
    <ul>
    <li>Чебурашка</li>
    <li>Крокодил Гена</li>
    <li>Шапокляк</li>
    <li>Крыса Лариса</li>
    </ul>

    </style> </head> <body> <ul> <li>Чебурашка</li> <li>Крокодил Гена</li> <li>Шапокляк</li> <li>Крыса Лариса</li> </ul>

    Результат:

    Задание: Скопируйте текст, расположенный ниже, и вставьте в веб-страницу. Используя вложенный стиль css либо отдельный файл css, создайте следующие правила, чтобы достигнуть эффекта как на итоговом изображении.

    Текст:

    <body> 
    <h2>Стих 1</h2>
    <p>
    Вопрос такой: зачем все это мне?<br/>
    Но, не найдя ответа на подходе,<br/>
    Я понял, что пришедшее извне<br/>
    Стремительно вовне же и уходит.
    </p><p>
    Другой вопрос — как быть? Но тут<br/>
    Ответ просился сам: бездействуй!<br/>
    (Угли недолго проживут<br/>
    В костре, где все без происшествий.)
    </p><p>
    Вот так и жду, не шевелясь,<br/>
    Когда уйдут из сердца лица,<br/>
    Ушедшие однажды с глаз,<br/>
    Чтоб никогда не возвратиться.
    </p>
    <hr>
    <h2>Стих 2</h2>
    <p>
    Обещай, что вернешься Домой.<br/>
    Эти зимы меня одолеют.<br/>
    Я смотрю на тебя и не смею<br/>
    Прикоснуться холодной рукой.
    </p><p>
    Обещай, что не будешь скучать.<br/>
    Нам обоим запомнятся годы<br/>
    Нашей странной и глупой свободы,<br/>
    Научившей любить и прощать.
    </p><p>
    Обещай, что в далеком краю,<br/>
    Если станет тебе одиноко,<br/>
    Ты прочтешь эти добрые строки<br/>
    Про бескрайнюю Нежность мою.
    </p><p>
    И поселится в сердце покой.<br/>
    Нет тебя мне на свете дороже.<br/>
    Обещай,<br/>
    что когда-нибудь все же<br/>
    ты конечно вернешься Домой.
    </p>
    <hr>
    </body>

    <body> <h2>Стих 1</h2> <p> Вопрос такой: зачем все это мне?<br/> Но, не найдя ответа на подходе,<br/> Я понял, что пришедшее извне<br/> Стремительно вовне же и уходит. </p><p> Другой вопрос — как быть? Но тут<br/> Ответ просился сам: бездействуй!<br/> (Угли недолго проживут<br/> В костре, где все без происшествий.) </p><p> Вот так и жду, не шевелясь,<br/> Когда уйдут из сердца лица,<br/> Ушедшие однажды с глаз,<br/> Чтоб никогда не возвратиться. </p> <hr> <h2>Стих 2</h2> <p> Обещай, что вернешься Домой.<br/> Эти зимы меня одолеют.<br/> Я смотрю на тебя и не смею<br/> Прикоснуться холодной рукой. </p><p> Обещай, что не будешь скучать.<br/> Нам обоим запомнятся годы<br/> Нашей странной и глупой свободы,<br/> Научившей любить и прощать. </p><p> Обещай, что в далеком краю,<br/> Если станет тебе одиноко,<br/> Ты прочтешь эти добрые строки<br/> Про бескрайнюю Нежность мою. </p><p> И поселится в сердце покой.<br/> Нет тебя мне на свете дороже.<br/> Обещай,<br/> что когда-нибудь все же<br/> ты конечно вернешься Домой. </p> <hr> </body>

    Необходимые правила:

    p:first-line{…}
    p:first-letter{…}
    p {…}
    h2{
    	text-transform:…;
    	border-bottom-style:...;
    	border-bottom-color:...;
        }
    hr {…}

    p:first-line{…} p:first-letter{…} p {…} h2{ text-transform:…; border-bottom-style:...; border-bottom-color:...; } hr {…}

    Свойства:
    text-transform
    border-bottom-style
    border-bottom-color

    Оформление шрифта

    Итоговое изображение:

    Урок 3. Псевдоклассы и псевдоэлементы

    1. Псевдоклассы
    2. Псевдоэлементы

    Важную роль в изучении CSS составляют псевдоклассы и псевдоэлементы. Они используются при проработке дизайна практически всех сайтов, исключение могут составить только старые сайты. Псевдоклассы и псевдоэлементы очень нужны при составлении красивого оформления.

    Синтаксис у них простой и одинаковый: псевдоклассы и псевдоэлементы указываются уже после объявления селектора, затем двоеточие : и название псевдокласса / псевдоэлемента.

    Вы, наверное, обращали внимание на то, что на некоторых сайтах при наведении курсора на ссылку она, например, меняет цвет. Это возможно благодаря псевдоклассам и псевдоэлементам. Рассмотрим пример.

    /* селектор двоеточие псевдокласс */
    a:hover {
      color: #000; /* текст ссылки при наведении становится чёрным */
    }

    Вышеуказанный код обозначает, что при наведении (hover) на ссылку, то есть элемент
    a
    (<a>) цвет текста ссылки (color) будет чёрным.

    Псевдоклассы


    Псевдоклассы - это элементы, которые указывают определённый набор стилей, в случае различных событий и изменений состояния элемента. Например, как изменятся стили в случае наведения, клика и тд на элемент.

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

    Список самых используемых псевдоклассов, которые обязательно пригодятся в работе:

    hover - при наведении курсора на элемент
    focus - при клике на элемент, например поле для ввода данных
    active - при активации элемента пользователем, то есть в момент клика
    link - стиль для не посещённых ссылок
    visited - стилевое оформление к посещенным ссылкам
    target - переход к выбранному фрагменту документа, в адресе после # указывается имя идентификатора

    root - определение корневого элемента документа
    indeterminate - стиль для флажков (radio) и переключателей (checkbox) в неопределенном состоянии
    checked - стиль для radio и checkbox в выбранном положении: input:checked
    firstchild - стиль для первого дочернего элемента селектора
    lastchild - изменения в последнем элементе родителя
    onlychild - для дочерних элементов, единственных у родителя
    lang (en) - определение языка элемента, где en выбранный язык

    Код CSS Примеры

    a:hover {
      color: #000; /* текст ссылки при наведении становится чёрным */
    }

    a:active {
      top: -1px; /* элемент при клике опускается чуть ниже, эффект нажатия */
    }

    Псевдоэлементы


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

    Список основных используемых псевдоэлементов, которые пригодятся в работе:

    after - добавление контента ПОСЛЕ указанного элемента
    before - добавление контента ДО указанного элемента
    firstletter - стили для первой буквы в контенте элемента
    firstline - стилевое оформление первой строки текста в элементе
    selection - применение стилей при выделении текста в элементе

    Одной из самых распространённых задач является добавление фразы до или после элемента. Рассмотрим на примере цитат. Допустим для определённого эелемента нужно добавить текст перед ним.

    .quote:before {
      content: "Цитата "; /* Перед классом .quote будет добавлено слово Цитата и пробел */
    }

    Также при помощи уже after можно добавить слова после указанного класса. Например, слово Далее или Авторскую подпись.

    Обязательно проверьте работу псевдоклассов и псевдоэлементов! Это увлекательно)
    Спасибо за внимание!

    Псевдоэлементы | WebReference

    Позволяет задать стиль кнопки «Обзор» при загрузке файлов.

    Задаёт стиль переключателей и флажков в Internet Explorer.

    Задаёт стиль кнопки для очистки текстового поля. Исходно эта кнопка не видна, она появляется в правой части поля только при вводе текста.

    Задаёт стиль кнопки раскрытия списка формы в браузерах Internet Explorer и Edge.

    Задаёт стиль индикатора прогресса в браузерах Internet Explorer и Edge. Само значение индикатора и его положение меняется динамически посредством скриптов.

    Задаёт стилевые параметры слайдера в браузерах Internet Explorer и Edge.

    Задаёт стилевые параметры слайдера в Internet Explorer и Edge.

    Задаёт стиль кнопки для просмотра пароля в поле формы. Кнопка исходно не видна и появляется в правой части поля при вводе пароля.

    Задаёт стиль ползунка для слайдера в Internet Explorer и Edge.

    Применяет стилевые параметры к делениям ниже дорожки слайдера в Internet Explorer и Edge.

    Применяет стилевые параметры к делениям выше дорожки слайдера в Internet Explorer и Edge.

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

    Задаёт стиль дорожки ползунка для слайдера в Internet Explorer и Edge.

    Позволяет изменять стиль элементов формы в браузерах Internet Explorer и Edge.

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

    Псевдоэлемент отображается ниже самого верхнего элемента в стеке по оси Z, но выше всех остальных элементов на странице, если они имеются. Обычно применяется для затемнения страницы, чтобы акцентировать внимание на фотографии или диалоговом окне, которые выводятся поверх такого затемнения.

    Применяется для отображения контента до содержимого элемента, к которому он добавляется.

    Определяет стиль первого символа в тексте элемента, к которому добавляется.

    Задаёт стиль первой строки форматированного текста.

    Псевдоэлемент, с помощью которого задаётся стилевое оформление подсказывающего текста, созданного атрибутом placeholder.

    Применяет стиль к выделенному пользователем фрагменту текста.

    Псевдоэлементы, которых не может быть — CSS-LIVE

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

    Псевдоклассы и псевдоэлементы

    И псевдоклассы, и псевдоэлементы были с самого начала CSS, с CSS1 (в этом году их 20-летие!). И там же было такое пояснение различия между ними:

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

    Потом пришел CSS2, а за ним и CSS2.1. В июне 2011-го он с горем пополам стал стандартом, а в сентябре того же 2011-го стандартом стал модуль селекторов 3 уровня (и формально по сей день стандарт). Именно в нем у псевдоэлементов появилось двойное двоеточие. За это время приходили и уходили другие спецификации, от «вечного кандидата в рекомендации» базового UI 3 уровня до совсем чернового предложения от Adobe, и все они норовили прибавить что-то своё. А еще HTML5 со своими интерактивными новинками…

    Но то отличие в главном по-прежнему актуально.

    Любой псевдокласс соответствует какому-то элементу. Или в каком-то определенном состоянии, после каких-то действий пользователя (под фокусом, при наведении), или в каком-то определенном месте DOM-дерева (пятый в ряду, третий с конца…), или отвечает каким-то дополнительным условиям (напр. не является заголовком) — если некий элемент вдруг оказался в этом состоянии/в этом месте/с такими параметрами, к нему применится соответствующий псевдокласс. Само название указывает, что они — некое подобие классов. Как и классы, псевдоклассы можно комбинировать в каких угодно сочетаниях. У одного элемента их может быть сколько угодно (например, a:first-of-type:target:focus:hover), причем в любом порядке.

    Действующий стандарт выделяет 6 категорий псевдоклассов, по не всегда понятной логике (чем :target не динамический?). В идущем ему на смену черновике CSS Selectors 4 классификацию чуть обновили:

    • языковые (:dir, :lang)
    • псевдоклассы места (все ссылочные и :target)
    • действия пользователя (:hover, :focus, :drop…)
    • временные (в теории, помогут подсветить элементы по мере озвучки их скринридером, показать субтитры для видео в нужный для них момент и т.п.)
    • состояния ввода (:disabled, :in-range…)
    • структурные (:root, :empty, :nth-*…)
    • новые псевдоклассы для выбора элементов по колонке таблицы или грида.
    • функциональные псевдоклассы для комбинации других селекторов (:not(), :matches() и — только б не спугнуть! — долгожданный :has()).

    А вот псевдоэлементы — судя по названию же, лишь отдаленное подобие элементов. Они выбирают что угодно: букву, фрагмент текста с другими элементами внутри, кнопку в составном поле ввода или вообще что-то, чего и близко не было в исходном документе — только не реальный DOM-элемент. Но это непонятное что-то получит визуальное представление и займет достойное место в дереве отображения, а затем и на экране, наравне с настоящими элементами.

    У элемента, которого нет, по идее, не может быть и соседей, тем более потомков. Поэтому в действующем стандарте про них сказано так (в вольном переводе):

    На один селектор может приходиться только один псевдоэлемент, и в этом случае он должен находиться после той цепочки селекторов, которая фактически выбирает элемент (т.е., грубо говоря, в самом конце селектора — прим. перев.).

    Именно поэтому мы привыкли видеть псевдоэлементы в селекторах последними. Правда, в том же стандарте прячется осторожная оговорка, что это, возможно, не навсегда… но не будем забегать вперед.

    Какие есть псевдоэлементы? Само собой, ::before и ::after. Чуть менее известны (хотя еще старше и работали даже в IE5!) ::first-line и ::first-letter. Эти 4 псевдоэлемента были в CSS2 (что дает им почетное право писаться с одним двоеточием). Удивительно, но в действующем стандарте только они и описаны! Лишь ::selection еще вскользь упомянут. Всё пёстрое богатство разнобраузерной «псевдофауны», что мы знаем по подборкам наподобие этой, стандарт словно игнорирует.

    Относительно недавно обновился черновик нового отдельного модуля псевдоэлементов 4 уровня, в котором их чуть больше и вдобавок они логически сгруппированы:

    • текстовые эффекты (::first-*)
    • генерируемый контент (::before::after, ::placeholder и ::marker)
    • средства для выделения и подсветки — ::selection и его друзья.

    Но здесь самое время остановиться и перейти от истории и теории к практике главной темы этой статьи — отношений псевдоэлементов с псевдоклассами и друг с другом:). Начнем с самого простого!

    Псевдоэлементы для псевдоклассов

    Почему-то некоторые до сих пор этому удивляются. Но раз псевдокласс выбирает элемент — почему бы этому элементу не обзавестись еще и псевдоэлементом?

    Простейший случай, пожалуй — особое оформление для первого/последнего элементов в ряду. Например, дорисовать стрелки для крайних пунктов подобного меню. А заодно и перекрасить эти стрелки при наведении: псевдокласс для этого взят уже другой (:hover), но элементы-то выбираются те же самые (ссылки, в т.ч. крайние), а значит, мы фактически перекрашиваем те же самые псевдоэлементы. Что и требовалось.

    Ситуаций, где псевдоэлемент нужен только при определенном динамическом состоянии, немало. Давний пример — подсветка столбцов таблицы при наведении. Или всевозможные «выкрутасы» при валидации форм. Например, вариант, когда форма не отвлекает пользователя во время добавления, но «поздравляет» его, когда всё заполнено корректно (пример). Кстати, присмотритесь к этому примеру повнимательнее: ::before и ::after могут быть не только с краю! Увы, этот пример не работает в IE (он не понимает form:valid).

    Псевдоэлементы в псевдоэлементах

    Итак, в нынешнем стандарте на один селектор может приходиться только один псевдоэлемент. Так ли уж это мало? Взгляните на пример:

    See the Pen XdmYwm by Ilya Streltsyn (@SelenIT) on CodePen.

    С виду в этом блоке 3 разностилевых блока контента — заголовок, подзаголовок и текст. Но в разметке блок пуст, и весь его контент сгенерирован стилями. Два блока, в начале и конце элемента — понятно, ::before и ::after. Откуда взялся третий?

    А его и нет! Есть лишь первая строка содержимого ::before. Она же — первая видимая строка самого элемента. То есть его ::first-line! Это стандартное поведение: ::first-line оформляет именно первую видимую строку текста, неважно, настоящего или сгенерированного. Этим можно пользоваться, чтобы разнообразить вид чисто оформительских подписей. А чтобы первая строка кончалась строго там, где нужно, используем маленький хак с символом \A (перенос строки) в тексте в сочетании с white-space:wrap-line (идея, которую давно предложила Лиа Веру, а недавно напомнил Крис Койер).

    Как всегда, не обошлось без ложки дёгтя: Chrome не хотел применять text-transform:uppercase к тексту ::first-line. Хотя по спецификации должен. Это был давний его баг (добавлено 20.12.2017: недавно его исправили, в стабильном 63-м его уже нет), видимо, унаследованный от совсем древнего бага Вебкита. Cамое занятное там происходит при наведении мышкой: у элемента появляются… сразу две «первых строки»! Если display:block задан и для ::before, и для ::after, первая строка подсвечивается у обоих. Это тоже явный баг: по спецификации первая строка выделяется только у одного блочного потомка, на то она и первая. Если нужно блочное (снаружи) поведение для ::after, но не нужна такая хромья самодеятельность, можно поменять ему display:block на flex — для флекс-контейнеров, по спецификации же, ::first-line не применяется. Именно это сделано в примере в обычном состоянии, без наведения.

    Но Firefox и сам не ангел: он вообще не применяет стиль ::first-line, если у ::before стоит display:block (можно увидеть это, наведя на блок мышкой). У него свои «счеты» с псевдоэлементами, не менее давние.

    На следующей картинке видно, как разные браузеры по-разному путаются в пересечении ::first-line и ::before в зависимости от display последнего, в этом примере. Для сравнения там такая же ситуация со span, полным аналогом которого, в теории, должен выступать ::before:

    Пересечение псевдоэлементов ::before и ::first-line в браузерах

    Только IE11 и Edge справился с ситуацией. Напоминаю, что речь о псевдоэлементах из CSS1-2, без малого 20-летней выдержки! Кто там еще ждет, когда все браузеры начнут одинаково поддерживать флексбоксы?

    Впрочем, иногда, когда по каким-то причинам нельзя влиять на разметку, а кроссбраузерность не критична, это сочетание псевдоэлементов может оказаться весьма кстати. Предельный случай — примеры чего-нибудь интересного на чистом CSS. Вроде нашей прошлогодней мини-игры. Таким нехитрым приемом можно придать ей более эффектную заставку. И даже по-разному анимировать «заголовок» и «текст» (см. чуть обновленный пример, и не забудьте заглянуть в исходник в Firefox).

    Псевдоэлементы с псевдоклассами

    Несколько минут назад мы выяснили, что псевдоклассы применяются к элементам, а псевдоэлементы — не элементы. Значит, псевдоэлементов со своими псевдоклассами быть не может?

    Я был уверен в этом до прошлого года, когда увидел этот твит Шиме Видаса, ведущего ежедневного дайджеста webplatformdaily.org. Но пример c ::selection:window-inactive действительно работает в «хромоподобных» браузерах — при активации другого окна цвет выделения меняется!

    Я предположил, что такой синтаксис — нововведение CSS Selectors 4, поэтому и работает только в браузерах с его поддержкой. На что Шиме указал мне на удивительную вещь: оказывается, формальной грамматике из CSS Selectors 3 он не противоречит! Действительно, формальное определение «последовательности простых селекторов» не ограничивает числа как псевдоклассов, так и псевдоэлементов, ограничение в один псевдоэлемент на цепочку есть только в текстовом пояснении, а формального запрета на псевдоклассы после псевдоэлементов нет вообще. Практической пользы от этого знания мало, разве что лишнее напоминание о разнице между «валидностью» и «соответствием стандарту» и о том, что не стоит слепо полагаться на валидаторы (хотя сам валидатор CSS на подобную запись как раз ругается). Но приятно чувствовать себя «почти знатоком». А заодно еще большим уважением проникаешься к создателям парсеров и анализаторов CSS, которые вынуждены постоянно это всё распутывать.

    Впрочем, 3-й уровень селекторов вполне можно уже считать устаревшим (помните, что статус рекомендации у W3C означает не «готово, используйте», а скорее «используется так давно, что мы сами уже почти разобрались, как это работает»?:). Давайте снова заглянем в ближайшее будущее:

    Сразу после псевдоэлемента может идти любая комбинация псевдоклассов действий пользователя, в этом случае псевдоэлемент представлен [селектором], только когда он в соответствующем состоянии. Соответствуют ли эти псевдоклассы конкретному псевдоэлементу, зависит от определений данного псевдокласса и псевдоэлемента: если не указано иное, ни один из этих псевдоклассов не  соответствует псевдоэлементу.

    То есть не для всех и не всегда… но в принципе можно! Но как же правило, что псевдоклассы применяются только к элементам? Можно сказать, что оно осталось в силе, только элементы теперь учитываются не в DOM, а в дереве отрисовки (или «дереве боксов», в терминах спецификации CSS Display 3 уровня).

    Обратите внимание: навешивать на псевдоэлементы можно псевдоклассы только одного типа — для действий пользователя. Варианты вроде ::before:first-child стандарт пока прямо запрещает. С одной стороны, это логично (nth-* считают элементы в DOM, а псевдоэлементы туда не попадают), с другой — обидно, как от любого ограничения. Зато чуть понятнее, для чего вообще нужна их классификация.

    Впрочем, именно для выделения в неактивном окне спецификация псевдоэлементов недавно предложила отдельный псевдоэлемент (::selection-inactive). Видимо, даже для авторов спецификации псевдокласс для псевдоэлемента — слишком уж радикальное новшество. Зато в браузерах (как минимум, Chrome, Firefox и Edge) успешно поддерживаются состояния для многих псевдоэлементов форм, типа ::-moz-range-track:hover.

    Псевдоэлементы с классами

    Из «незначительного» изменения грамматики CSS, что псевдоэлементы могут быть не только на конце цепочки селекторов, есть и менее очевидные следствия. Как вы думаете, какого цвета будет <div> в результате такого кода?

    div, div::after {
      width: 200px;
      height: 200px;
      background: red;
    }
    div.test, div::after.test{
      background: green;
    }
    

    Такой код может случайно получиться на выходе препроцессора, как в этом примере. Должно ли примениться правило с зеленым фоном?

    Современные браузеры считают, что нет. За исключением Safari 9+ (и iOS 9.3+ Safari) — те радостно красят квадрат зеленым. В браузерах на основе Chromium, где-то в районе 48-й версии, он тоже был зеленым, но с 49-й версии квадрат снова «покраснел». Баг исправили?

    Не всё так однозначно.

    По всем предыдущим стандартам — до действующего модуля селекторов 3 уровня включительно — этот селектор был недопустимым. Даже если запрет выражался лишь в текстовом примечании к формальной грамматике, браузеры вынуждены были его соблюдать. По правилам обработки ошибок в CSS, невалидность селекторов «заразна»: если в списке селекторов затесался хоть один невалидный — отбрасывается всё правило целиком. Именно на этом держатся хаки с дописыванием перед селектором через запятую чего-то вроде x:-moz-any-link или _:-ms-fullscreen, чтобы правило отработало только в каком-то одном браузере.

    Но что, если это текстовое примечание уберут и псевдоэлементу разрешат быть не последним в цепочке?

    Конечно, селектор ::after.test не начнет что-либо выбирать, он останется таким же бессмысленным. Но бессмысленный — не значит недопустимый. Селектор a:not(a), например, явно бессмысленный и ничего не выбирает — но зато и не нарушает никаких формальных правил, а значит, и не «заражает» невалидностью целое правило. Т.е. правило a:not(a),b{color:red} полностью работоспособно. А значит, и наше странное правило может стать таким же.

    То, что поведение Safari 9 — не баг, косвенно подтвержается тем, что именно Safari 9 поддерживает больше всего нововведений черновика селекторов 4 уровня. А значит, живет уже по новому стандарту. Опять же — стандарт еще не утвержден, так что всё может измениться. Но полезно знать, что такие перемены в принципе бывают. Особенно при использовании хаков с неочевидным принципом действия: вчерашний баг вполне может обернуться завтрашней фичей, и хак перестанет работать!

    Добавлено 2.01.2018: буквально в новогоднюю ночь Элика Этемад (fantasai) уточнила грамматику CSS-селекторов, и классы для псевдоэлементов однозначно стали недопустимыми. По новой грамматике поведение Safari будет считаться багом, и вскоре его могут пофиксить. Но пока старые версии еще в ходу, стоит быть в курсе этого разночтения!

    ::before и ::after пустых и замещаемых элементов

    Еще одна загадка CSS, над которой давно ломают головы даже знатоки. Казалось бы, раз ::before и ::after добавляются перед и после контента элемента, то для всех пустых элементов (у которых по стандарту не может быть контента) они работать не должны: нет контента — нет и мест для вставки. Но практика часто показывает иное. Может, верна догадка Луиса Лазариса, что псевдоэлементы не работают только для замещаемых элементов? Но почему тогда во многих браузерах работают псевдоэлементы для <img> — уж он-то однозначно замещаемый?

    Кстати, что такое эти замещаемые элементы, которые даже визуально форматируются по-особому? Удивительно, но однозначного определения в CSS до сих пор нет! 

    Изначально (в CSS1) их определяли как «элемент, заменяемый контентом, на который из него указывается». Затем (в CSS2) — как «элемент, для которого движок CSS-форматирования знает лишь внутренние размеры» (именно тогда к замещаемым элементам стали относить поля форм). Наконец, в CSS2.1 — который до последнего времени был актуальным стандартом — как «элемент, чей контент не рассматривается моделью форматирования CSS» (рассматривает ли она контент тех же <button> и <textarea>, который, вроде бы, вполне слушается как минимум CSS для шрифта — спецификация не уточняла).

    Так что, видимо, искать глубокую закономерность тут незачем. Всё определяется тем, как эти элементы реализованы в браузерах — т.е. «как исторически сложилось». А сложилось так, что большинство браузеров всё равно замещает такие элементы… вопрос лишь, чем именно:)

    Возьмем для примера пару картинок из вышеупомянутой статьи и рассмотрим их в отладчике Хрома, включив галочку «Показывать теневую DOM браузера»:

    Теневая DOM для незагруженной и загруженной картинки в Хроме

    Как видно, загруженная картинка — вещь самодостаточная. А вот у незагруженной внутри «выросло» целое теневое DOM-дерево содержимого — со своей иконкой и отдельным текстовым блоком. А раз есть содержимое — есть и куда вставить псевдоэлементы! Что-то подобное, надо полагать, происходит и в других браузерах (хоть напрямую проверить это там труднее). Если у вас есть другие сведения — прошу поделиться ими в комментариях!

    Но в модуле генерируемого и замещаемого контента CSS3 (2003 г.) было еще одно определение замещаемого: «элемент или псевдоэлемент, у которого вычисленное значение используемой части свойства content оказывается отдельным URI». А это свойство можно было задавать всем элементам. Т.е. силами самого CSS по сути можно было сделать любой элемент замещаемым или незамещаемым! И там же впервые явно утверждалось, что у замещаемых элементов нет ::before и ::after (в других спецификациях их поведение было лишь «не определено»).

    Похоже, когда-то давно в некоторых браузерах (Opera Presto и WebKit) это даже частично поддерживалось. Потом браузеры стали от этого избавляться. Если в iOS 9.2 Safari указание свойства content для <img> еще влияло на отображение псевдоэлементов для картинки, то уже в iOS 9.3 — перестало. И вот недавно этот модуль спецификации обновился — с той же самой формулировкой! Правда, возможности самого свойства content урезали: если сделать незамещаемый элемент замещаемым (заменить картинкой) можно, то наоборот — уже нельзя. Так что возвращать убранное браузерам не придется.

    И еще курьезный факт — собственные запреты не мешают самому W3C в собственных спецификациях стилизовать «отбивку» <hr> вот так:

    See the Pen LZVvmy by Ilya Streltsyn (@SelenIT) on CodePen.

    Это работает во всех актуальных браузерах.

    Псевдоэлементы для псевдоэлементов?

    В одном из примеров Аны Тюдор (о котором она не так давно подробно рассказывала) в скомпилированном CSS встречается такой селектор:

    input[type='range']::-webkit-slider-thumb:before { // стили...

    Как? Ладно, псевдоэлементы могут быть не в конце селектора. Ладно, у них могут быть состояния. Но свои псевдоэлементы?

    К сожалению, увидеть именно этот селектор в работе мне так и не удалось. Но в модуле селекторов 4 уровня есть намеки, что псевдоэлементы могут оказываться весьма непростыми:

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

    Примером такого псевдоэлемента с внутренней структурой текущая версия спецификации приводит ::shadow. Больше нигде в этом модуле такой псевдоэлемент не упоминается. В модуле псевдоэлементов — тоже. Упоминается он только в модуле CSS Scoping 1 уровня — причем только в позапрошлогоднем публичном черновике, из свежего редакторского черновика он пропал. За эти два года сама теневая DOM изрядно изменилась, ну и связанный с ней CSS заодно.

    Так что, похоже, единственный пока псевдоэлемент, у которого могут быть настоящие полноценные потомки (!), остается нестандартным. Хотя по-прежнему работает в Chrome. По логике, раз у чего-то есть контент, то могут быть и генерируемые псевдоэлементы перед и после этого контента… но нет: никакой ::shadow::before у меня так и не заработал, да и по спецификации ::shadow не генерирует никаких боксов, отображаются только сами его потомки. По новой спецификации, правда, специальные места для вставки теневых ветвей — «слоты» — должны вести себя как элементы с display:contents, а псевдоэлементы у таких элементов (там, где он поддерживается, т.е. в Firefox) вполне отображаются. Ведь визуально они — полные аналоги настоящих потомков. Но на старую хромовскую реализацию это, разумеется, уже повлиять не может.

    Так что, как бы ни хотелось мне закончить статью работающим примером псевдоэлемента для псевдоэлемента, на сегодняшний день мне пришлось в этом признать поражение. Но, как мы видели, новые черновики готовят нам массу сюрпризов, и кое-что из того, что прежде казалось немыслимым, уже работает в каком-то из браузеров (пусть за флагом и т.п.). Возможно, найти такой (или еще более невозможный) пример удастся вам? Добро пожаловать в комментарии!

    P.S. Это тоже может быть интересно:

    CSS3 | Псевдоэлементы

    Псевдоэлементы

    Последнее обновление: 21.04.2016

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

    • ::first-letter: позволяет выбрать первую букву из текста

    • ::first-line: стилизует первую строку текста

    • ::before: добавляет сообщение до определенного элемента

    • ::after: добавляет сообщение после определенного элемента

    • ::selection: выбирает выбранные пользователем элементы

    В CSS2 перед псевдоэлементами, как и перед псевдоклассами, ставилось одно двоеточие. В CSS3 для отличия их от псевдоклассов псевдоэлементы стали предваряться двумя двоеточиями. Однако для совместимости с более старыми браузерами, которые не поддерживают CSS3, допустимо использование одного двоеточия: :before.

    Стилизуем текст, используя псевдоэлементы first-letter и first-line:

    
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>Псевдоклассы в CSS3</title>
            <style>
                ::first-letter { color:red; font-size: 25px; }
                ::first-line { font-size: 20px; }
            </style>
        </head>
        <body>
            <p>Но он ничего не видал. Над ним не было ничего уже, кроме неба, — высокого неба, не ясного, но все-таки неизмеримо высокого, с тихо ползущими по нем серыми облаками.</p>
        </body>
    </html>
    

    Используем псевдоэлементы before и after:

    
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>Псевдоклассы в CSS3</title>
            <style>
                .warning::before{ content: "Важно! "; font-weight: bold; }
                .warning::after { content: " Будьте осторожны!"; font-weight: bold;}
            </style>
        </head>
        <body>
            <p><span>Не пытайтесь засунуть язык в электрическую розетку.</span></p>
        </body>
    </html>
    

    Здесь псевдоэлеметы применяются к элементу с классом warning. Оба псевдоэлемента принимают свойство content, которое хранит вставляемый текст. И также для повышения внимания псевдоэлементы используют выделение текста жирным с помощью свойства font-weight: bold;.

    Используем псевдоэлемент selection для стилизации выбранных элементов:

    
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>Псевдоэлементы в CSS3</title>
            <style>
    			::selection {
    				color: white;
    				background-color: black;
    			}
            </style>
        </head>
        <body>
            <p>Пседвоэлементы в CSS3 позволяют форматировать текст.</p>
        </body>
    </html>
    

    Псевдоэлементы CSS

    У Вас в браузере заблокирован JavaScript. Разрешите JavaScript для работы сайта!

    Псевдоэлементы позволяют задать стиль для части элемента (например, для первой буквы или первой строки абзаца), а также генерировать содержимое, которого нет в HTML-коде документа.

    Псевдоэлемент состоит из двух двоеточий ( :: ) и имени. Двойное двоеточие было введено в CSS3 для того, чтобы отделить псевдоэлементы от псевдоклассов. Однако для совместимости с прежними таблицами стилей допускается использовать одинарное двоеточие( : ).

    ::first-line первая строка текстового блока.
    Пример
    <style type="text/css">
        p::first-line {
            font-weight: bold;
        }
    </style>
    <p>
        При редактировании CSS-файла возникает противоречивая задача. С одной стороны код должен быть удобным для восприятия и редактирования, быстрого отыскания нужного селектора, для чего активно применяются отбивки, комментарии, пробелы и символы табуляции. С другой стороны, объем кода должен быть компактным и не содержать в себе ничего лишнего. Компактность позволяет несколько ускорить загрузку сайта и повысить его производительность.
    </p>
    <p>
        Данное противоречие решается наличием двух версий CSS-файла: один для редактирования, а второй для загрузки на сервер. Сам же процесс сокращения кода называется минимизацией и вполне автоматизирован с помощью специализированных программ или сетевых сервисов. Но если приходится часто вносить изменения в CSS-файл, то процесс минимизации становится неудобным. Сами посудите, вначале надо отредактировать файл, затем его минимизировать и полученный код сохранить в файл, который нужно залить на сервер. Слишком много действий приходится совершать ради одного изменения. Логичнее было бы возложить задачу минимизации на сайт. Загрузили файл на сервер, и вот он уже в компактном виде отдается посетителям. Одно из таких универсальных решений называется minify, это библиотека на PHP5. Она минимизирует, объединяет и кэширует CSS-файлы, а также JavaScript.
    </p>

    РЕЗУЛЬТАТ:

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

    Данное противоречие решается наличием двух версий CSS-файла: один для редактирования, а второй для загрузки на сервер. Сам же процесс сокращения кода называется минимизацией и вполне автоматизирован с помощью специализированных программ или сетевых сервисов. Но если приходится часто вносить изменения в CSS-файл, то процесс минимизации становится неудобным. Сами посудите, вначале надо отредактировать файл, затем его минимизировать и полученный код сохранить в файл, который нужно залить на сервер. Слишком много действий приходится совершать ради одного изменения. Логичнее было бы возложить задачу минимизации на сайт. Загрузили файл на сервер, и вот он уже в компактном виде отдается посетителям. Одно из таких универсальных решений называется minify, это библиотека на PHP5. Она минимизирует, объединяет и кэширует CSS-файлы, а также JavaScript.

    Псевдоэлемент ::first-letter дает возможность оформить текст "буквицами".

    ::first-letter первая буква текстового блока.
    Пример
    <style type="text/css">
        p::first-letter {
            font: italic 40px Georgia, serif;
        }
    </style>
    <p>
        За горами, за лесами,<br>
        За широкими морями,<br>
        Не на небе – на земле<br>
        Жил старик в одном селе...
    </p>

    РЕЗУЛЬТАТ:

    За горами, за лесами,
    За широкими морями,
    Не на небе – на земле
    Жил старик в одном селе...

    ::before генерируемое содержимое, расположенное до содержимого элемента;
    ::after генерируемое содержимое, расположенное после содержимого элемента.

    Псевдоэлементы ::before и ::after используются вместе со свойством content и наследуют стиль от элемента, к которому добавляются.

    При добавлении ::before или ::after к блочному элементу их свойство display может принимать значения block, inline, none, list-item. Все остальные будут восприниматься как block.

    При добавлении ::before или ::after к строчному элементу их свойство display может принимать значения inline и none. Все остальные будут восприниматься как inline.

    Псевдоэлементы ::before и ::after нельзя добавить ни к элементу img, ни к элементу input, так как эти элементы не имеют содержимого.

    Пример
    <style type="text/css">
        li {
            list-style: none;
        }
        li::before {
            content: "\25BA";
            padding-right: 5px;
        }
    </style>
    <ul>
        <li>&alpha; – альфа</li>
        <li>&beta;  – бета</li>
        <li>&gamma; – гамма</li>
    </ul>

    РЕЗУЛЬТАТ:

    • α – альфа
    • β – бета
    • γ – гамма
    ::selection текст, выделенный пользователем.

    К выделенному тексту можно применять свойства color, background и background-color.

    Firefox понимает этот псевдоэлемент только с префиксом, т.е. ::-moz-selection

    Пример
    <style type="text/css">
        p::selection {
            background-color: #ff0;
        }
        p::-moz-selection {
            background-color: #ff0;
        }
    </style>
    <p>Выделите левой кнопкой мыши текст этого абзаца, и он будет на желтом фоне.</p>

    РЕЗУЛЬТАТ:

    Выделите левой кнопкой мыши текст этого абзаца, и он будет на желтом фоне.

    Смотрите также:

    Псевдоэлементы в CSS

    Вы здесь: Главная - CSS - CSS Основы - Псевдоэлементы в CSS

    Псевдоэлементы в CSS

    Очень важной особенностью CSS являются псевдоэлементы. Псевдоэлемент - это некая характеристика состояния объекта или его особенность. Например, первая буква в абзаце (особенность), наведённый курсор мыши на объект (состояние). И вот таких псевдоэлементов в CSS достаточно много. О них мы и поговорим подробно в данной статье.

    Псевдоэлементы в CSS позволяют задавать особый стиль для "необычных" элементов. Давайте с Вами разберём простой пример:

    img:hover {
      border: 2px solid #f00; // Устанавливаем красную рамку
    }

    Данный код означает, что вокруг изображения при наведении на него курсора мыши будет появляться красная рамка толщиной 2 пикселя. Когда же курсор мыши будет уходить с элемента, то рамка будет исчезать. Благодаря псевдоэлементам, казалось бы непростую задачу, мы решили очень легко и без использования JavaScript, что вообще прекрасно.

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

    Привожу таблицу с различными псевдоэлементами в CSS и их описанием.

    Псевдоэлемент Описание
    active Состояние "активной ссылки", то есть ссылка, на которую нажимают.
    firstchild Можно применить стиль к первому дочернему элементу.
    first-letter Первый символ в тексте элемента.
    first-line Первая строка в тексте элемента.
    focus Для элемента в состоянии "фокус". Например, текстовое поле, в котором сейчас набирают текст.
    hover Наведение на элемент курсора мыши.
    link Определяет состояние непосещённой ссылки.
    visited Определяет состояние посещённой ссылки.

    Это не все псевдоэлементы, а лишь те, которые, во-первых, во всех браузерах работают (за исключением IE6, где не всё это работает), а также постоянно используются верстальщиками. Поэтому все данные псевдоэлементы Вы должны знать прекрасно.

    Надеюсь, теперь некоторые элементы Вы будете верстать с меньшим количеством тегов и свойств, а также без использования JavaScript. Успехов в освоении псевдоэлементов в CSS!

    • Псевдоэлементы в CSS Создано 06.06.2012 13:34:27
    • Псевдоэлементы в CSS Михаил Русаков
    Предыдущая статья Следующая статья

    Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

    Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
    Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

    Если Вы не хотите пропустить новые материалы на сайте,
    то Вы можете подписаться на обновления: Подписаться на обновления

    Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

    Порекомендуйте эту статью друзьям:

    Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

    1. Кнопка:
      <a href="https://myrusakov.ru" target="_blank"><img src="https://myrusakov.ru/images/button.gif" alt="Как создать свой сайт" /></a>

      Она выглядит вот так: Как создать свой сайт

    2. Текстовая ссылка:
      <a href="https://myrusakov.ru" target="_blank">Как создать свой сайт</a>

      Она выглядит вот так: Как создать свой сайт

    3. BB-код ссылки для форумов (например, можете поставить её в подписи):
      [URL="https://myrusakov.ru"]Как создать свой сайт[/URL]

    Отправить ответ

    avatar
      Подписаться  
    Уведомление о