Почему ::before не работает?
почему псевдоэлемент ::before может быть неэффективен для полей ввода и изображений
Псевдоэлементы CSS ::before
и ::after
могу быть неприменимы для полей ввода и изображений, так как HTML-элементы <input>
и <img>
являются замещаемыми элементами (replaced elements). Для таких элементов отведена целая категория в rendering section описания HTML-стандартов.
Следующие элементы могут быть замещаемыми: audio, canvas, embed, iframe, img, input, object, и video.
Fantasai - представитель рабочей группы CSS так же дает объяснения этой особенности замещаемых элементов на GitHub:
Замещаемые элементы заменяют весть контент элемента, в том числе содержимое псевдоэлементов ::before и ::after. Именно поэтому такие псевдоэлементы для замещаемых элементов работать не будут.
Например, невозможно отобразить альтернативный текст элемента <img>
с помощью ::before
, хотя такой подход эффективен в отношении многих других HTML-элементов (в том числе <p>
).
/* Такой пример работать не будет! */
img::before {
content: attr(alt);
}
Внимание: Элемент <img>
не всегда является замещаемым - это зависит от используемого в данный момент браузера и ряда других факторов. Например, если нет возможности загрузить изображение, псевдоэлементы ::before
и ::after
будут доступны к использованию в браузерах Chrome и Firefox.
Но и это не все. Когда заходит речь об использовании элементов формы, ситуация становится еще менее понятной. Так элементы <input>
и <textarea>
можно назвать частично замещаемыми (semi-replaced). Этот термин предложил Таб Аткинс - редактор спецификаций CSS в обсуждениях рабочей группы на Github:
Все типы полей ввода, как минимум “частично замещаемые”. Мы до сих пор не можем быть полностью уверены в том, как такое состояние работает. Но это не “замещаемые элементы” в их полном представлении, так как они имеют определенные неизменяемые внутренние размеры, которым подчиняются (в отличие от обычных элементов).
Возможность добавить контент к элементам формы с помощью CSS-псевдоэлементов ::before
и ::after
зависит как от типа самого элемента, так и от используемого браузера. Например, Chrome и Safari поддерживают содержимое псевдоэлементов ::before
и ::after
для чекбоксов и радиокнопок:
/* Такой пример будет работать в Chrome и Safari! */
input::before {
content: '💔';
line-height: 1;
vertical-align: top;
position: relative;
left: -1.5em;
}
input:checked::before {
content: '❤️';
}
Итак, если у Вас возниакают проблемы с использованием контента псевдоэлементов ::before
или ::after
, не забывайте проверить, с каким элементом Вы работаете - возможно он являетмся замещаемым полностью или частично.
Спасибо за внимание.
Написано по материалам статьи “Why CSS ::before doesn’t work on inputs and images”.