Последнее обновление:
Псевдоэлементы позиционируются не всеми браузерами корректно
О Позиционировании псевдоэлементов
Что такое псевдоэлемент в html? Это – аналог обычного элемента, но с некоторыми отличиями:
- Во-первых, к нему невозможно получить доступ при помощи javascript «обычными» способами. Придется делать доступ через стили.
- Во-вторых, его невозможно выделить на вебстранице «обычным образом» (т.е.при помощи мыши или клавиш).
- В третьих, псевдоэлементы задаются также особенным образом, не в виде тегов, а через стили (см. ниже).
В целях достижения кроссбраузерности, позиционирование псевдоэлементов НЕ СТОИТ делать относительно строк таблиц!
В общем, псевдоэлемент - он и есть псевдоэлемент. Интересно, что такая вот их особенность находит отражение и в том, как они реализованы в разных браузерах. В частности, мы рассмотрим здесь, как осуществляется позиционирование псевдоэлементов (на примере :before) в разных браузерах. Как увидим, существуют некоторые отличия.
Вот тестовый html-код:
- <style>
- .parent {display: inline-block; }
- .sup_parent {border: dashed}
- .child:before {position: absolute; top: 30px; left: 20px; color: red; content: "Hello!";}
- .child-table:before {position: absolute; top: 30px; left: 20px; content: "Table!!";}
- </style>
- <body style="font-family: Arial">
- <div style="width: 150px; display: inline-block">
- <div class="sup_parent">
- <div class="parent" style="position: relative">
- <div class="child" style="border: solid green">123</div>
- </div>
- </div>
- <div class="sup_parent" style="">
- <div class="parent" style="">
- <div class="child" style="border: solid blue; position: relative">123</div>
- </div>
- </div>
- <div class="sup_parent" style="position: relative">
- <div class="parent" style="position: relative">
- <div class="child" style="border: solid yellow">123</div>
- </div>
- </div>
- </div>
- <div style="width: 220px; display: inline-block; border: dotted; vertical-align: top">
- <div style="display: table; border: dashed blue">
- <div style="display: table-row">
- <div class="child-table" style="display: table-cell; border: solid green; color: green; position: relative">table-cell: {position: relative}
- </div>
- </div>
- </div>
- <div style="display: table; border: dashed blue">
- <div style="display: table-row; position: relative">
- <div class="child-table" style="display: table-cell; border: solid purple; color: purple" >table-row: {position: relative}
- </div>
- </div>
- </div>
- <div style="display: table; border: dashed blue; position: relative">
- <div style="display: table-row; ">
- <div class="child-table" style="display: table-cell; border: solid green; color: ">{table: position: relative}
- </div>
- </div>
- </div>
- </div>
Мы опустим здесь DOCTYPE, метатеги и т.д. На рисунках показано, как отображается этот код в разных браузерах. Мы для экспериментов использовали следующие браузеры:
- Firefox 24 (Windows 7)
- Firefox 36 (Windows 7)
- Firefox 45 (Windows 7)
- Firefox 70 (Linux Ubuntu)
- Internet Explorer 11 (Windows 7)
- Edge 85 (Windows 7)
Строчки 9….17 кода содержат три блока <div> типа display: block. Каждый из них, в свою очередь, содержит вложенные блоки. Самый внутренний вложенный блок имеет свойство position: absolute, а один из его родителей – свойство position: relative. Т.е. самый внутренний блок (это строчки 11, 16, 21) является абсолютно позиционированным относительно ближайшего родителя, который позиционирован относительно.
При этом самый внутренний блок содержит еще и псевдоэлемент :before, в котором указан контент «Hello!».


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


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


А вот с табличным позиционированием псевдоэлементов результаты немного иные
Имеются в виду не «типичные» таблицы типа <table><tr><td>…, а блоки <div>, имеющие свойства position, равные table, table-row, table-cell соответственно.
Так вот, посмотрим, что будет, насколько правильно будет позиционирован псевдоэлемент :before (который, напомним, везде позиционирован абсолютно) разными браузерами в зависимости от того, какой из родителей позиционирован относительно. Иными словами – есть ли разница, какой именно из родителей, т.е. сама таблица, ее строка или ячейка позиционированы относительно?
На примере с «обычными» блоками <div>, как оказалось выше, разницы нет. А вот что с таблицами?
Как видно, здесь мнения браузеров разделились.
Браузеры Firefox 36/45/70 отображают псевдоэлементы практически одинаково и на отлично: надпись "Table!!", порожденная псевдоэлементом :before, находится чуть ниже и правее элемента, являющегося для него родительским. Вне зависимости от того, кто именно из родителей содержит относительное позиционирование.
А вот браузеры производства Microsoft (что старый, что новый), а также (что любопытно!) Firefox 24 корректно отображают псевдоэлемент :before лишь в случаях, если относительно позиционированным родителем этого псевдоэлемента НЕ является строка таблицы, т.е. не тег, имеющий свойство display: table-row. То ли разработчики этих браузеров решили, что, мол, табличная верстка нечасто будет использоваться, то ли уж непонятно что. Интересно, что все три этих браузера (E85, IE11, FF24) в случае, если относительно позиционированной является только строка таблицы - игнорируют это позиционирование практически одинаково и позиционируют псевдоэлемент относительно тега body (слово "Table!!", окрашенное пурпурным цветом).
Так что стоит принять к сведению этот момент. Ладно, кто-то может утверждать (видимо, от нечего делать), что браузер FF24, равно как и IE11, якобы, является "устаревшим". Ну, да, мол, выпущен уже давно - вот поэтому, типа того. И тем более, что касается Internet Explorer, так компания Micrisoft вообще прекратила выпуск браузеров этой линейки. Однако, взамен она сделала браузер Edge, который, по крайней мере, по отношению к позиционированию псевдоэлементов, работает точно так же.
Вывод
Вывод может быть таким:
в целях достижения кроссбраузерности, позиционирование псевдоэлементов НЕ СТОИТ делать относительно строк таблиц.
Скорее всего, так обстоит дело не только с псевдоэлементами, но и с обычными элементами. Мы пока не проверяли.