Популярно о псевдоэлементах :Before и :After

http://www.hongkiat.com/blog/pseudo-element-before-after/
  • Перевод
  • Tutorial
Псевдоэлементы :before и :after позволяют добавлять содержимое (стили) до и после элемента, к которому были применены.



Всего существует несколько типов псевдоэлементов: :first-line, :first-letter, ::selection, :before и :after. В этой статье подробно рассмотрены последние два, как наиболее полезные.

Синтаксис и поддержка браузерами


Псевдоэлементы появились еще в CSS1, но пошли в релиз только в CSS2.1. В самом начале в синтаксисе использовалось одно двоеточие, но в CSS3 используется двойное двоеточие для отличия от псевдоклассов:



Но в любом случае, современные браузеры умеют понимать оба типа синтаксиса псевдоэлементов, кроме Internet Explorer 8, который воспринимает только одно двоеточие. Поэтому надежнее использовать одно.

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


<p>  
<span>:before</span>   
    Это основной контент.
<span>:after</span>  
</p>  


Элементы :before и :after не будут сгенерированы, т.е. не будут видны в коде страницы, поэтому они и называются псевдоэлементами.

Использование


Использовать псевдоэлементы крайне просто: :before добавляется перед нужным элементом, а :after — после.
Для добавление контента внутри псевдоэлементов можно воспользоваться CSS-свойством content.

Простой пример: необходимо добавить кавычки для цитаты:



blockquote:before {  
    content: open-quote;  
}  
blockquote:after {  
    content: close-quote;  
}  


Стилизация псевдоэлементов


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



blockquote:before {  
    content: open-quote;  
    font-size: 24pt;  
    text-align: center;  
    line-height: 42px;  
    color: #fff;  
    background: #ddd;  
    float: left;  
    position: relative;  
    top: 30px;  
  
}  
blockquote:after {  
    content: close-quote;  
    font-size: 24pt;  
    text-align: center;  
    line-height: 42px;  
    color: #fff;  
    background: #ddd;  
    float: rightright;  
    position: relative;  
    bottombottom: 40px;  
}  



Созданные элементы по умолчанию inline-элементы, поэтому при указании высоты или ширины необходимо установить display: block:



blockquote:before {  
    content: open-quote;  
    font-size: 24pt;  
    text-align: center;  
    line-height: 42px;  
    color: #fff;  
    background: #ddd;  
    float: left;  
    position: relative;  
    top: 30px;  
    border-radius: 25px;  
  
    /** define it as a block element **/  
    display: block;  
    height: 25px;  
    width: 25px;  
}  
blockquote:after {  
    content: close-quote;  
    font-size: 24pt;  
    text-align: center;  
    line-height: 42px;  
    color: #fff;  
    background: #ddd;  
    float: rightright;  
    position: relative;  
    bottombottom: 40px;  
    border-radius: 25px;  
  
    /** define it as a block element **/  
    display: block;  
    height: 25px;  
    width: 25px;  
}  


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



blockquote:before {  
    content: " ";  
    font-size: 24pt;  
    text-align: center;  
    line-height: 42px;  
    color: #fff;  
    float: left;  
    position: relative;  
    top: 30px;  
    border-radius: 25px;  
  
    background: url(images/quotationmark.png) -3px -3px #ddd;  
  
    display: block;  
    height: 25px;  
    width: 25px;  
}  
blockquote:after {  
    content: " ";  
    font-size: 24pt;  
    text-align: center;  
    line-height: 42px;  
    color: #fff;  
    float: rightright;  
    position: relative;  
    bottombottom: 40px;  
    border-radius: 25px;  
  
    background: url(images/quotationmark.png) -1px -32px #ddd;  
  
    display: block;  
    height: 25px;  
    width: 25px;  
}  


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

Использование вместе с псевдоклассами


Псевдоэлементы могут быть использованы вместе с псевдоклассами, в нашем примере это поможет добавить hover-эффект кавычкам:



blockquote:hover:after, blockquote:hover:before {  
    background-color: #555;  
}  


Добавление transition-эффекта


Также можно применить свойство transition для плавного изменения цвета кавычек:

transition: all 350ms;  
-o-transition: all 350ms;  
-moz-transition: all 350ms;  
-webkit-transition: all 350ms; 


К сожалению, это нормально работает только в последних версиях Firefox.

Посмотреть демонстрацию примера из этой статьи.

Немного вдохновения


Три примера использования псевдоэлементов :before и :afte:

Fascinating Shadows




3D Button




Stacked Image Effect


Поделиться публикацией

Комментарии 60

    +9
    В этом примере свойство content содержит пустую строку, это необходимо, иначе псевдоэлемент не будет правильно отображаться.

    Он вообще не будет отображаться.

    Пробел в content: " "; совсем не обязателен.
      +11
      Псевдоэлементы :before и :after позволяют добавлять содержимое (стили) до и после элемента, к которому были применены.

      Не согласен. Псевдоэлементы генерируют inline-сущности (можно сказать строчные элементы), которые добавляются в начало и конец содержимого элемента, к которому применяются! А не До и После самого элемента.
        +3
        Можно сказать До и После содержимого…
          +5
          Использовать псевдоэлементы крайне просто: :before добавляется перед нужным элементом, а :after — после.

          Здесь та же ошибка(
          0
          При это, в оригинале сказано правильно, но в здесь ошибка, статья хороша, а перевод вольного качества :-(
          +2
          К сожалению, это нормально работает только в последних версиях Firefox.

          Проблему с транзишенами уже решил Роман Комаров: kizu.ru/en/pseudos/
            +1
            Вот прям таки решил? Сей костыль !== панацея, то бишь нормально это работает только в Firefox.

            Ошибка в Chromium, ошибка в Webkit.
              +2
              Расскажите это тем кто вот такие вещи делает: codepen.io/iamvdo/pen/GsIxk
              +2
              Ну да, не решил, а обошёл, и не для всех свойств. Но пока есть баги вне ФФ — этим вполне можно пользоваться, если хочется сделать что-то здесь и сейчас.
                +1
                И в этом вы правы. И, да, спасибо за ваши эксперименты и желание научить эксперементировать других ;).
            +13
            transition: all 350ms; -o-transition: all 350ms; -moz-transition: all 350ms; -webkit-transition: all 350ms;
            Почему свойства с префиксами идут в конце? Чему вы молодёжь учите?
              –8
              А в чём проблема? оО
                  0
                  Посмотрел слайды. Не понял, почему нужно писать иначе. Пример с тенью еще больше запутал — почему так?
                  Если не трудно, поясните, пожалуйста.
                    +2
                    Потому что, в случае, если свойство уже реализовано во всех браузерах и работает без префикса, но при этом в коде префикс идёт последним, то браузер сделает примерно так:

                    1) Сначала увидит свойство без префикса (оно же у вас вверху)
                    2) Далее дойдя до свойства с префиксом браузер может применить его! А последнее может быть недоделанным или тем, которое использовалось для старых версий.

                    В итоге вы получите совершенно не ту реализацию свойства, которую хотели. А то и вообще, сломанную напрочь.
                      0
                      Немного понятней, но не совсем — откуда гарантия, что свойство без префикса будет нормально работать? Нет ведь 100% гарантии, если только не протестировать все-все свойства во всех браузерах в прямом и обратном порядке?

                      (Я немного далек от верстки, больше серверная часть, но HTML мне всегда был интересен, отсюда глупые вопросы)
                      • НЛО прилетело и опубликовало эту надпись здесь
                        • НЛО прилетело и опубликовало эту надпись здесь
                    +3
                    Доклад Вадима Макеева об использовании префиксов pepelsbey.net/pres/pre-fixes/
                    0
                    + про "::" вообще ни слова не сказано. А в CSS3 именно так и нужно писать, то бишь "::before" и "::after".
                    • НЛО прилетело и опубликовало эту надпись здесь
                        0
                        Да я вроде как прочел, но в тексте-то по сути только про "::selection" сказано, а про остальное самим додумывать нужно. +, исходя из текста, нужно использовать только вариант с одним двоеточием, а реально же имеет смысл использовать два там, где это возможно и дописывать старый вариант там, где это нужно.
                          +1
                          А мне вот не нравится два двоеточия, ящитаю это лишний мусор исключительно ради религиозных убеждений. Все браузеры еще лет 20-30 будут поддерживать одно двоеточие ради совместимости; и я не верю, что вообще когда-нибудь введут в стандарт :before с одним двоеточием, которое будет иметь какой-то другой смысл.
                          • НЛО прилетело и опубликовало эту надпись здесь
                      +2
                      Лучше давать ссылку на видео, презентация без него менее ценна: vimeo.com/channels/wstdays/47210831
                        0
                        Спасибо за ссылку, в презентации нет мякотки на 39й минуте!
                      +4
                      Очень не люблю вот такой эффект:
                      image
                      Мой мозг не понимает, как может стол под листочком так изгибаться, особенно если рядом ещё такой же листок с такой же тенью.
                        +19
                        А мой мозг это воспринимает как немного приподнимающуюся бумажку.
                          0
                          Если бы бумажка приподнималась, верхний горизонтальный край и нижний горизонтальный край были бы изогнутыми.
                            +8
                            Они и КАЖУТСЯ визуально изогнутыми. Оптический обман конечно, но цель достигает.
                              +1
                              или
                              достигает цели
                              или
                              цель достигается
                              или
                              цель достигнута
                              +2
                              Просто некоторые дизайнеры перебарщивают и рисуют слишком массивные тени, имитируя сильный изгиб. Тогда да, мозг немного спотыкается. А с легенькими теньками «только чтобы подчеркнуть» вполне нормально.
                              Вот в примере, имхо, тень тоже немножко избыточна — если говорить о реальном проекте. Для демки преувеличение полезно.
                              +1
                              Мне тоже это кажется крайне низкосортным эффектом.
                            +6
                            Стоит также отметить, что для одиночных тегов, не содержащих в себе контент, псевдоэлементы особо не поюзаешь. Т.е. всякого рода img, input, br пролетают
                              0
                              Разве? В браузерах на основе Webkit это уже вроде как не новость…
                              • НЛО прилетело и опубликовало эту надпись здесь
                                  0
                                  Ну оно-то ясно, что многие штуки будут работать в последних вебкитах и опере, возможно в ФФ, но это на уровне прототипов. На коммерческих и клиентских проектах все равно не получится использовать.
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                      0
                                      Можно, но с костылями для ИЕ, потому что ряд примеров даже девятка неадекватно отображает :\

                                +2
                                bottombottom: 40px;
                                впервые вижу такое…
                                Или лыжи не едут или я…!
                                  0
                                  Сорри за оффтоп, а что за шрифт на рисунках?
                                    0
                                    похоже на PF Din
                                    +4
                                    Кстати, картинки можно вставлять не только как background, но и напрямую:
                                    content: url('image.png');
                                    
                                      +1
                                      Так же стоит упомянуть, что на псевдоэлементы нельзя вешать события, т.к. они не являются частью DOM.
                                        +1
                                        Важное замечание: если указать для :before или :after ширину/высоту в процентах (и не забыть display:block), то за 100% принимается размер блока, к которому этот псеводэлемент относится. Таким образом например можно например накладывать хитрые рамки и т.п.
                                          0
                                          Если блок вложить в блок, то точно так и будет. Чем же псевдоблоки (в данном случае) должны отличаться?
                                            0
                                            Ничем, но вообще штука неочевидная. При этом очень полезная при наложении всяких рамок, кромок, подписей (right: 20%; bottom: 15%) и т.п.
                                              +1
                                              Если понимать как все это дело устроенно, то вполне очивидная сия шука, ибо данные псевдоэлементы добавляются внутрь элемента, следовательно, они ведут себя так же, как и обычные элементы, вставленные внутрь блока, за исключением всяких ошибок браузров (к примеру, у браузеров на основе движка Webkit не работает анимация указанных псевдоэлементов по средством CSS).

                                              Пример
                                              <html xmlns="http://www.w3.org/1999/xhtml">
                                              	<head>
                                              		<title>Example</title>
                                              		<style>
                                              			#d1{
                                              				width:300px;
                                              				height:300px;
                                              				background-color:red;
                                              			}
                                              			#d2{
                                              				width:100%;
                                              				height:100%;
                                              				background-color:green;
                                              			}
                                              		</style>
                                              	</head>
                                              	<body>
                                              		<div id="d1">
                                              			<div id="d2"></div>
                                              		</div>
                                              	</body>
                                              </html>
                                              

                                              и
                                              <html xmlns="http://www.w3.org/1999/xhtml">
                                              	<head>
                                              		<title>Example</title>
                                              		<style>
                                              			#d1{
                                              				width:300px;
                                              				height:300px;
                                              				background-color:red;
                                              			}
                                              			#d1::before{
                                              				content:'';
                                              				display:block;
                                              				width:100%;
                                              				height:100%;
                                              				background-color:green;
                                              			}
                                              		</style>
                                              	</head>
                                              	<body>
                                              		<div id="d1">
                                              		</div>
                                              	</body>
                                              </html>
                                              

                                              Визуальной разницы нет.
                                                0
                                                Ну это именно что нужно знать, что это вложенные элементы, а не предшествующие/последующие. Во втором случае 100% относилось бы к родителю.
                                                Более того, нужно знать, что это не просто «написано в стандарте», а действительно выполняется во всех браузерах.
                                                При том что 90% комментируемой статьи — это «вода водянистая состоит в-основном из воды», упомянуть о таком поведении как минимум не мешало бы.
                                                  +1
                                                  Дык, давно уже есть статья с CSS-Tricks. Просто автору посчастливилось перевести не ту статью… Ну а если без иронии, то спецификация + фантази решает все и вся ;).
                                          +3
                                          Автор смотрю все замечания проигнорил. Молодец!
                                            0
                                            Если указан float, то display:block не нужен
                                              0
                                              для обычных span тоже? это где-то в спецификации?
                                                +1
                                                А «необычное» это что? Div или p? Ну им display:block тем более не нужен. Float делает элемент блочным.
                                                http://docs.webplatform.org/wiki/css/properties/float
                                                With a value of left or right, the object is treated as block-level—that is, the display property is ignored.
                                                  0
                                                  Да, спасибо, это интересно. Обычный — в плане реально созданный span, а не созданный как псевдоэлемент
                                              0
                                              Редко где пишут, но ::before и ::after не работает с «открытыми» тэгами, типа img.
                                              • НЛО прилетело и опубликовало эту надпись здесь

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

                                              Самое читаемое