Номер телефона

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

Псевдоэлементы позиционируются не всеми браузерами корректно

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

Что такое псевдоэлемент в html? Это – аналог обычного элемента, но с некоторыми отличиями:

  1. Во-первых, к нему невозможно получить доступ при помощи javascript «обычными» способами. Придется делать доступ через стили.
  2. Во-вторых, его невозможно выделить на вебстранице «обычным образом» (т.е.при помощи мыши или клавиш).
  3. В третьих, псевдоэлементы задаются также особенным образом, не в виде тегов, а через стили (см. ниже).

В целях достижения кроссбраузерности, позиционирование псевдоэлементов НЕ СТОИТ делать относительно строк таблиц!

В общем, псевдоэлемент - он и есть псевдоэлемент. Интересно, что такая вот их особенность находит отражение и в том, как они реализованы в разных браузерах. В частности, мы рассмотрим здесь, как осуществляется позиционирование псевдоэлементов (на примере :before) в разных браузерах. Как увидим, существуют некоторые отличия.

Вот тестовый html-код:

  1. <style>
  2. .parent {display: inline-block; }
  3. .sup_parent {border: dashed}
  4. .child:before {position: absolute; top: 30px; left: 20px; color: red; content: "Hello!";}
  5. .child-table:before {position: absolute; top: 30px; left: 20px; content: "Table!!";}
  6. </style>

  1. <body style="font-family: Arial">

  1. <div style="width: 150px; display: inline-block">
  2.  <div class="sup_parent">
  3.   <div class="parent" style="position: relative">
  4.     <div class="child" style="border: solid green">123</div>
  5.   </div>
  6.  </div>

  1. <div class="sup_parent" style="">
  2.  <div class="parent" style="">
  3.    <div class="child" style="border: solid blue; position: relative">123</div>
  4.  </div>
  5. </div>

  1. <div class="sup_parent" style="position: relative">
  2.  <div class="parent" style="position: relative">
  3.    <div class="child" style="border: solid yellow">123</div>
  4.  </div>
  5. </div>
  6. </div>

  1. <div style="width: 220px; display: inline-block; border: dotted; vertical-align: top">
  2.  <div style="display: table; border: dashed blue">
  3.    <div style="display: table-row">
  4.       <div class="child-table" style="display: table-cell; border: solid green; color: green; position: relative">table-cell: {position: relative}
  5.       </div>
  6.    </div>
  7.  </div>

  1. <div style="display: table; border: dashed blue">
  2.  <div style="display: table-row;  position: relative">
  3.    <div class="child-table" style="display: table-cell; border: solid purple; color: purple" >table-row:  {position: relative}
  4.    </div>
  5.  </div>
  6. </div>

  1. <div style="display: table; border: dashed blue;  position: relative">
  2.  <div style="display: table-row; ">
  3.    <div class="child-table" style="display: table-cell; border: solid green; color: ">{table: position: relative}
  4.    </div>
  5.  </div>
  6. </div>

  1. </div>

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

  1. Firefox 24 (Windows 7)
  2. Firefox 36 (Windows 7)
  3. Firefox 45 (Windows 7)
  4. Firefox 70 (Linux Ubuntu)
  5. Internet Explorer 11 (Windows 7)
  6. Edge 85 (Windows 7)
Конечно, было бы крайне интересно, каковы будут результаты в других браузерах, например, а GH, Opera, Safari и т.д.

Строчки 9….17 кода содержат три блока <div> типа display: block. Каждый из них, в свою очередь, содержит вложенные блоки. Самый внутренний вложенный блок имеет свойство position: absolute, а один из его родителей – свойство position: relative. Т.е. самый внутренний блок (это строчки 11, 16, 21) является абсолютно позиционированным относительно ближайшего родителя, который позиционирован относительно.

При этом самый внутренний блок содержит еще и псевдоэлемент :before, в котором указан контент «Hello!».

Позиционирования псевдоэлемента с блочными и табличными родителями в браузере Firefox 36
Позиционирования псевдоэлемента с блочными и табличными родителями в браузере Firefox 24

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

Позиционирования псевдоэлемента с блочными и табличными родителями в браузере Firefox 70
Позиционирования псевдоэлемента с блочными и табличными родителями в браузере Firefox 45

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

Позиционирования псевдоэлемента с блочными и табличными родителями в браузере Edge 85
Позиционирования псевдоэлемента с блочными и табличными родителями в браузере Internet Explorer 11

А вот с табличным позиционированием псевдоэлементов результаты немного иные

Имеются в виду не «типичные» таблицы типа <table><tr><td>…, а блоки <div>, имеющие свойства position, равные table, table-row, table-cell соответственно.

Кстати, комбинация табличного позиционирования с «обычным» позиционированием (т.е. display: block или display: inline-block) в ряде случаев – крайне полезная вещь для адаптивной верстки. Почему (по какой же странной причине?... ) это редко используется разработчиками на практике, почему же вместо этого применяются то Bootstrap, то Grid разные – вопрос риторический. Видимо, потому, что разного рода Yii, React и иже с ними это не используют(?). Ну, а полностью выбросить фреймворки, бутстрапы и пр., и делать качественную верстку самостоятельно… видимо, мешают религиозные убеждения, что ли... Ну, да ладно, впрочем.

Так вот, посмотрим, что будет, насколько правильно будет позиционирован псевдоэлемент :before (который, напомним, везде позиционирован абсолютно) разными браузерами в зависимости от того, какой из родителей позиционирован относительно. Иными словами – есть ли разница, какой именно из родителей, т.е. сама таблица, ее строка или ячейка позиционированы относительно?

На примере с «обычными» блоками <div>, как оказалось выше, разницы нет. А вот что с таблицами?

Как видно, здесь мнения браузеров разделились.

Браузеры Firefox 36/45/70 отображают псевдоэлементы практически одинаково и на отлично: надпись "Table!!", порожденная псевдоэлементом :before, находится чуть ниже и правее элемента, являющегося для него родительским. Вне зависимости от того, кто именно из родителей содержит относительное позиционирование.

Насколько известно, абсолютно позиционированный блок позиционируется относительно, якобы, "ближайшего родителя", имеющего позиционирование absolute, relative или fixed. Ну, по крайней мере, именно так пишут в этих, в мануалах-стандартах. Или относительно тега body, если нет ни одного родителя, позиционированного таким образом. Понятно, что стандарты - это одно, а соблюдение их разработчиками браузеров - это уже другое.

А вот браузеры производства Microsoft (что старый, что новый), а также (что любопытно!) Firefox 24 корректно отображают псевдоэлемент :before лишь в случаях, если относительно позиционированным родителем этого псевдоэлемента НЕ является строка таблицы, т.е. не тег, имеющий свойство display: table-row. То ли разработчики этих браузеров решили, что, мол, табличная верстка нечасто будет использоваться, то ли уж непонятно что. Интересно, что все три этих браузера (E85, IE11, FF24) в случае, если относительно позиционированной является только строка таблицы - игнорируют это позиционирование практически одинаково и позиционируют псевдоэлемент относительно тега body (слово "Table!!", окрашенное пурпурным цветом).

Так что стоит принять к сведению этот момент. Ладно, кто-то может утверждать (видимо, от нечего делать), что браузер FF24, равно как и IE11, якобы, является "устаревшим". Ну, да, мол, выпущен уже давно - вот поэтому, типа того. И тем более, что касается Internet Explorer, так компания Micrisoft вообще прекратила выпуск браузеров этой линейки. Однако, взамен она сделала браузер Edge, который, по крайней мере, по отношению к позиционированию псевдоэлементов, работает точно так же.

Вывод

Вывод может быть таким:

в целях достижения кроссбраузерности, позиционирование псевдоэлементов НЕ СТОИТ делать относительно строк таблиц.

Скорее всего, так обстоит дело не только с псевдоэлементами, но и с обычными элементами. Мы пока не проверяли.



Комментарии:
Олег26.10.2020 12:53
Современный Edge работает на хромовском движке. Еще с прошлого года.
Научный Консалтинг28.10.2020 15:35РедактироватьУдалить
Что касается обычных элементов, позиционированных абсолютно и находящимися внутри ячеек таблиц (т.е. внутри тегов, имеющих свойства display:table-cell; position:relative), то подобная проблема наблюдается только в Firefox 24 (среди анализируемых в статье браузеров). Все остальные браузеры корректно отображают такие элементы. Чтобы снять проблему также и в Firefox 24 (также, возможно, и в более ранних браузерах линейки FF - как минимум, вплоть до 36 версии), то следует внутрь ячейки таблицы вставить блок div и задавать position:relative уже для него. При этом абсолютно позиционированные элементы, находящиеся внутри такого блока, и в этом браузере будут отображаться корректно. Конечно, это приведет к необходимости вставлять дополнительный тег - в каждую ячейку таблицы, относительно которой необходимо будет выполнить (абсолютное) позиционирование. Но, зато так будет кроссбраузерно. Ну, а где кроссбраузерность и корректность отображения верстки - там и правда.
Научный Консалтинг28.10.2020 15:40РедактироватьУдалить
Что же касается хромовского движка - стало быть, там имеется такой вот баг. При этом любопытно, однако, что современные браузеры Firefox, тоже, вроде бы, использующие хромовский движок, тем не менее отображают и псевдоэлементы (которые абсолютно позиционированы относительно ячеек или строк таблицы), и обычные элементы вполне корректно.
Всего комментариев: 3
Пожалуйста, не забудьте ознакомиться с правилами оставления комментариев.



Подписаться на комментарии на этой странице

Мы можем выполнить

Другие услуги
Интересная и полезная
информация
НАПИШИТЕ НАМ
Яндекс.Метрика
Номер телефона
© Copyright Все права защищены 2013-