Чем :: first-letter отличается от: first-child (псевдокласс против псевдоэлемента) - PullRequest
0 голосов
/ 26 февраля 2019

Из определения псевдоэлементов в стандарте W3C https://www.w3.org/TR/selectors-3/#pseudo-elements:

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

(Мой акцент.)

Почему язык документа позволяет обнаруживать первый дочерний элемент (так что :first-child является псевдо- классом css *)1014 *) но не первой буквы (так что ::first-letter является псевдо- элементом css )?Как следует понимать этот « язык документа »?

По сути, вопрос заключается в следующем: почему существует разница в выборе первого элемента в отличие от первой буквы?Почему язык документа может извлекать одно, а не другое?

Я не спрашиваю об общей разнице между псевдоклассами и псевдоэлементами, а скорее спрашиваю конкретно о том, почему первая буква концептуально отличается от первойдочерний элемент.Другие псевдоэлементы менее запутанны: то, что ::after и ::before, например, являются псевдоэлементами, довольно очевидно, поскольку они относятся к «пробелу», который не определен в структуре html.Но первая буква - это , поэтому вопрос о том, почему такая первая буква по-прежнему трактуется по-разному.

1 Ответ

0 голосов
/ 26 февраля 2019

Язык документа в наиболее типичном случае использования CSS относится к HTML.Дерево документа (как упоминается во всем Селекторах) относится к дереву DOM, построенному из разметки.

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

Вы заметите, что псевдоэлемент ::first-letter применяется, например, только к блочным контейнерам.Нет никакого способа узнать, будет ли элемент (или его потомок) иметь псевдоэлемент ::first-letter, пока он не будет определен как блок контейнера блока (единственный вид блока, который может непосредственно содержать поток встроенного содержимого), и чтоопределяется CSS, а не HTML.В качестве более конкретного примера:

<p>Hello world!

По умолчанию элемент p равен display: block.Это приводит к блоку блока, который является своего рода блоком контейнера контейнера.Но даже в этом случае это значение по умолчанию реализовано с использованием CSS.И если вам нужно переопределить это значение по умолчанию с помощью следующего правила CSS:

p {
  display: inline;
}

, этот элемент становится встроенным блоком, и p::first-letter больше не будет влиять на него.

Интуитивно понятно, что по-прежнему тривиально определить первую букву встроенного блока по сравнению с блок-блоком (или любым другим типом блока), но все становится довольно сложно, если у вас есть несколько встроенных блоков в одном контексте встроенного форматирования, все взаимодействующие с однимдругой.

::first-line гораздо более четкий: не только невозможно узнать, какова длина первой отформатированной строки текста элемента, пока вы не отформатируете строку, но исодержимое и длина этой строки также могут изменять при изменении размера и / или перекомпоновки элемента и его содержимого.

В отличие от этого, древовидный структурный псевдокласс, такой как :first-child, соответствуетэлементы в DOM независимо от макета.Без необходимости что-либо визуализировать, браузер может сразу сказать, какой из элементов является первым дочерним элементом своего родителя.Все, что вам нужно, это дерево элементов DOM, что означает, что всю необходимую вам информацию можно извлечь из языка документа, разметки.Например, первый дочерний элемент ol в следующем фрагменте всегда один и тот же независимо от того, какой CSS вы к нему применяете :

<ol>
  <li>First
  <li>Second
  <li>Third
</ol>
...