После… или нет, перед… что-то я запутался

css

Когда старенький JS-разработчик копается в CSS чтобы написать статью вроде этой, это наверное выглядит странно? :)

Я здесь немного поразглагольствую, с вашего позволения. И думаю, многие со мной согласятся в том, что та ситуация, к которой мы пришли, ведет в тупик.

Псевдо-CSS

Доводилось ли вам слышать о псевдоэлементах CSS ::before и ::after? Если вы по какой то причине еще не знакомы с ними, или вообще не слышали, тогда давайте рассмотрим их поближе.

Для начала, «псевдо» первым делом говорит нам о том, что этот часть CSS скорее более «виртуальная», нежели «реальная». Псевдоэлементы разработаны для того, чтобы позволить нам с помощью CSS стилизовать особый тип элементов, который на самом деле непосредственно в разметке отсутствует. Эти столь особенные элементы являются виртуальной частью страницы, хотя напрямую в ее структуре они и не представлены.

С помощью ::after и ::before мы обращаемся к «последнему дочернему элементу» или «первому дочернему элементу» контейнера, для которого применено соответствующее стилевое правило. Но, не к настоящему первому или последнему дочернему элементу, а, скорее, к вымышленному, который существует только если вы прописываете для него стилевые свойства, в противном случае это всего лишь фантом.

Пример:

<style>
#container { background-color:yellow; }
#container::before { content:"!!!!! "; font-style:italic; }
#container::after { content:"!!!!!"; font-weight:bold; }
</style>

<div id="container">В этом контейнере есть не только этот текст</div>

В контейнере есть не только этот текст

Забавно, да?

Правило content в псевдоэлементах используется, в основном, для декоративного оформления разметки с помощью CSS, с целью избегания ее загромождения различным презентационным мусором. Например, данное правило позволяет добавить после ссылок иконки, обозначающие, что эти ссылки являются внешними, или же стилизованные кавычки вокруг блочной цитаты blockquote, ну и так далее.

Примечание: Вы можете встретить два вида записи: ::after или :after. С технической точки зрения, для псевдо-элементов и псевдо-селекторов вместо : нужно использовать ::. В большинстве браузеров оба варианта работают. Далее по тексту я буду использовать запись ::, ведь за ней будущее!

После чего «after» то?

Если приглядеться повнимательней, то вы заметите, что у ::before и ::after довольно странная семантика. Если вы следите за моими заметками по теме CSS, тогда, думаю, вы в курсе, что я довольно серьёзно воспринимаю вопрос семантики в CSS.

Видя слова «before» (перед) и «after» (после), большинство людей понимают их буквально, они ожидают, что добавленный контент будет отображаться чётко перед или после элемента с соответствующим стилевым правилом. То есть, стилизованные элементы должны быть на одном уровне с контейнером-родителем.

Однако, на самом деле мы прописываем стилевые правила для дочерних элементов контейнера, а если точнее, для элементов, которые «виртуально» расположены в нём в самом начале и в конце.

Вот именно, в этом случае «after» не значит «после родителя», это значит «в самом конце в родительском контейнере». Глубокий вздох. Еще одна семантическая ошибка. Они не такая уж большая редкость.

В мире JavaScript уже есть устоявшийся прецедент добавления дочерних элементов в начало элемента-контейнера, перед остальными дочерними элементами, или в конец, после всех остальных. И я говорю не только о фреймворках вроде jQuery и прочих, подобное есть даже во встроенном нативном DOM API. Мы вызываем нечто вроде parent.appendChild(child) для обновления списка дочерних элементов в родительском контейнере. Возможно, что с точки зрения семантики было бы лучше, если бы в CSS вместо ::after использовалось ::append или ::append-child.

А что насчёт ::before? Ну что ж, в самом DOM API нет такого метода, как prependChild(), так что нам придётся найти обходной путь, и использовать parent.insertBefore(child,parent.firstChild). Ух. К счастью, в различных JS фреймворках для таких случаев реализован метод prepend(). Я думаю, что и в CSS лучшим решением было бы использовать псевдо-элемент ::prepend или ::prepend-child.

::повторению-ошибок:нет

Все эти семантические недоразумения в CSS по настоящему удручают, даже не столько каждый отдельный случай, сколько в общем тот факт, что они встречаются сплошь и рядом. Видимо, такова участь веб-разработчика.

Тем не менее, я считаю, что если мы будем постоянно обращать внимание на подобные ошибки, может быть, со временем, нам удастся уменьшить их количество. Я очень надеюсь на это.

А что думаете об этом вы? Было ли правильным решение назвать этот псевдо-элемент ::after? Или, гораздо лучше было бы использовать более семантически верное обозначение ::append, и отнести раскритикованный вариант в список устаревших? Или же, мне просто стоит ::смириться-и-жить-дальше?