::before и ::after - это два псевдоэлемента, которые добавляют оформление рядом с содержимым тега, не трогая саму HTML-разметку: ::before вставляет что-то ДО содержимого элемента, ::after - ПОСЛЕ. Оба работают только вместе со свойством content, которое как раз и определяет, что именно вставить.
В этом уроке
Попробуй прямо в этом окне: перед цитатой появляется декоративная кавычка, а сразу после слова "Имя" - красная звёздочка, хотя ни того, ни другого символа в HTML-коде нет вообще. Удали строку с content внутри blockquote::before - кавычка исчезнет полностью, хотя само правило blockquote::before всё ещё будет существовать: без content псевдоэлемент просто не создаётся.
::before - контент перед содержимым
::before добавляет виртуальный элемент прямо перед содержимым выбранного тега - как будто это первый ребёнок внутри него. Чаще всего его используют для декоративных значков, кавычек или маленьких меток перед текстом.
blockquote::before { content: "\201C"; } - добавляет декоративную открывающую кавычку перед текстом цитаты.
img::before { content: "фото: "; } - у "заменяемых" элементов вроде img, input и br псевдоэлементы не работают: браузеру просто некуда вставлять сгенерированное содержимое внутри такого тега.
::after - контент после содержимого
::after работает так же, как ::before, только вставляет виртуальный элемент ПОСЛЕ содержимого - как будто это последний ребёнок внутри тега. Частый пример - звёздочка у обязательных полей формы или декоративная стрелка после ссылки.
.required::after { content: " *"; color: red; } - добавляет красную звёздочку сразу после текста, помеченного как обязательный.
a::after { content: " (внешняя ссылка)"; } без учёта того, что этот текст может быть плохо доступен для скринридеров - для действительно важной по смыслу информации лучше использовать настоящий текст в HTML, а не сгенерированный CSS.
Свойство content - без него ничего не появится
Сам по себе селектор ::before или ::after ничего не создаёт - обязательно нужно свойство content, которое и определяет, что именно вставить: текст в кавычках, пустую строку или даже картинку. Забыть content - самая частая причина, по которой псевдоэлемент "не работает".
.badge::before { content: ""; width: 8px; height: 8px; background: tomato; display: inline-block; } - content: "" (пустая строка) тоже считается заданным content, поэтому вместе с шириной, высотой и фоном получается декоративная фигура без единого символа текста.
.badge::before { width: 8px; height: 8px; background: tomato; } без строки content вообще - без неё браузер даже не создаёт псевдоэлемент, и никакая фигура не появится, сколько бы других свойств ни было указано.
Частые ошибки новичков
| Ошибка | Что происходит | Как исправить |
|---|---|---|
| Забыть свойство content | Без content браузер вообще не создаёт псевдоэлемент - остальные свойства (цвет, фон, размер) просто не на чем показывать | Всегда добавлять content, даже пустую строку content: "", если нужна декоративная фигура без текста |
| Ждать эффекта от ::before/::after на img, input, br | Это "заменяемые" элементы - браузеру некуда вставлять сгенерированное содержимое внутри них, псевдоэлемент просто не появится | Оборачивать такой тег дополнительным контейнером (например span или div) и вешать псевдоэлемент на него |
| Класть в content смыслово важный текст | Поддержка сгенерированного через CSS текста скринридерами непредсказуема - для части пользователей этот текст может быть вообще не озвучен | Важный по смыслу текст писать в самом HTML, а ::before/::after оставлять для чисто декоративного оформления |
| Путать :before (одно двоеточие) и ::before (два двоеточия) | Для :before/:after оба варианта работают одинаково ради обратной совместимости с CSS2, ошибки не будет | Привыкать сразу писать через двойное двоеточие :: - у более новых псевдоэлементов однобуквенной версии уже нет |
Шпаргалка
| Что | Как работает |
|---|---|
| ::before | Вставляет виртуальный элемент перед содержимым тега |
| ::after | Вставляет виртуальный элемент после содержимого тега |
| content: "текст" | Обязательное свойство - без него псевдоэлемент не создаётся вообще |
| content: "" | Пустая строка тоже считается заданным content - подходит для декоративных фигур |
| Заменяемые элементы | img, input, br - ::before/::after на них не работают |
Коротко: отвечаем на вопросы
Почему ::before ничего не показывает, хотя правило написано без ошибок?
Скорее всего, в правиле не хватает свойства content - без него браузер вообще не создаёт псевдоэлемент, даже если остальные свойства оформления указаны верно.
Можно ли сделать content пустой строкой и всё равно что-то увидеть на странице?
Да, content: "" тоже считается заданным content - этого достаточно, чтобы псевдоэлемент появился, а дальше его можно оформить шириной, высотой и фоном как декоративную фигуру без единого символа текста.
Слышат ли текст из content скринридеры?
Поддержка непредсказуема - в зависимости от программы экранного чтения такой текст может быть озвучен, проигнорирован или прочитан неправильно. Поэтому важную по смыслу информацию в content лучше не класть, оставляя его только для декоративного оформления.
В чём разница между :before и ::before?
Это старый и новый синтаксис одного и того же псевдоэлемента: :before пришёл из CSS2 1998 года, ::before - из CSS3 2011 года. Для :before/:after оба варианта работают одинаково, но привычнее писать через двойное двоеточие, потому что у более новых псевдоэлементов однобуквенной версии уже нет.