Зачем использовать * селектор в сочетании с *:: before и *:: after
Я смотрел фреймворк Twitter-бутстрапа, и у меня есть очень маленький вопрос.
Ниже я расскажу, как установить коробку-модель в border-box
.
*, *::after, *::before { box-sizing: border-box; }
Но если вы посмотрите на спецификации CSS *
для всех элементов, то почему на самом деле используется селектор *::after
и *::before
?
Для меня это кажется устаревшим, потому что селектор *
уже будет отмечать все элементы.
Ответы
Ответ 1
Смотрите эти два JSFiddles:
http://jsfiddle.net/86gc1w6f/
http://jsfiddle.net/gwbp2vpL/1/
Или попробуйте эти фрагменты:
CSS
* {
box-sizing: content-box;
}
p {
position: relative;
width: 200px;
border: 10px solid rgba(255, 0, 0, 0.5);
}
p::after {
position: absolute;
right: -100px;
top: -10px;
width: 100px;
height: 30px;
border: 10px solid rgba(0, 0, 255, 0.5);
content: '';
}
HTML:
<p>
A paragraph
</p>
Изменение размера окна между content-box
и border-box
изменяет только размер абзаца, не его ::after
. Как отмечали другие, это происходит потому, что они называются псевдо и должны быть нацелены отдельно.
Похоже, что * не нацелено на псевэ-элементы (которые, как указывает @Harry, соответствует спецификации CSS)
Ответ 2
Выделяет ли * все элементы?
Нет, *
не распространяется на псевдоэлементы. Они охватывают только реальные элементы, которые присутствуют в DOM.
В Спецификация W3C:
Универсальный селектор, написанный как квалифицированное имя CSS [CSS3NAMESPACE] со звездочкой ( * U + 002A) в качестве локального имени, представляет собой квалифицированное имя любого типа элемента. Он представляет любой единственный элемент в дереве документов в любом пространстве имен (в том числе без пространства имен), если для селекторов не задано пространство имен по умолчанию.
акцент мой
Почему свойство, указанное в * селекторе, работает для некоторых, но не для других?
Для некоторых свойств, таких как color
, вы получите иллюзию *
применительно ко всем элементам, включая псевдо, потому что они являются свойствами, которые ребенок может наследовать от своего родителя.
box-sizing
, с другой стороны, не является наследуемым свойством и поэтому также должно быть явно упомянуто и на псевдоэлементах.
Примечание: Хотя псевдоэлементы называются before
и after
, они фактически являются дочерними элементами элемента, к которому он присоединен).
Пример для иллюстрации наследования:
Посмотрите нижеприведенный фрагмент и посмотрите, как черный border
применяется только для реальных элементов. Среди псевдоэлементов только p:after
получает border
, потому что он непосредственно указан в самом псевдоэлементе. div:after
не получает границы.
* { /* selects all real elements */
border: 1px solid black; /* not an inheritable property and so pseudos don't get it */
padding: 10px;
color: red; /* inheritable property and so pseudos which are children inherit it */
}
div::after {
content: 'abcd';
margin: 4px;
}
p::after {
content: 'abcd';
margin: 4px;
border: 1px solid red;
}
<div>abcd</div>
<p>abcd</p>
Ответ 3
Вы в основном ответили на свой вопрос. ::before
и ::after
являются псевдоэлементами. Имя даже подразумевает, что они не представляют истинные элементы.
Селектор *, *::before, *::after
предназначен для соответствия:
-
*
Все элементы, присутствующие в DOM
-
*::before
Псевдоэлемент ::before
относительно всех элементов, присутствующих в DOM
-
*::after
Псевдоэлемент ::after
относительно всех элементов, присутствующих в DOM
Поскольку псевдоэлементы не квалифицируются как полные элементы (<html>
, <head>
, <body>
и т.д.) и не являются частью DOM, они не соответствуют символу звездочки. Они сопоставляются только при выборе по отношению к другому элементу. Они не могут быть выбраны в JavaScript по той же причине. JavaScript только выбирает элементы, которые он может найти в DOM, что неверно в отношении псевдоэлементов.
Для цитаты из MDN:
В селекторе можно использовать только один псевдоэлемент. Он должен появиться после простых селекторов в инструкции.
Простой селектор определяется W3C, используя следующее определение:
A простой селектор является либо селектором типов, универсальный селектор, селектор атрибутов, селектор классов, идентификатор селектора или pseudo-class.
Простые селектора предназначены для соответствия элементам, присутствующим в DOM. Псевдоэлемент должен следовать за простым селектором, поскольку он не является частью самого DOM и, следовательно, не может быть классифицирован как элемент. Поскольку *
- простой селектор, в частности универсальный селектор псевдоэлементы в CSS могут быть привязаны к нему, чтобы соответствовать всему этому конкретному псевдоэлементу тип. Без селектора псевдоэлементов останется только простой селектор (*
).
Ответ 4
:: after и:: before псевдоэлементы, и они вставляют стиль после или перед элементом соответственно.
Для вашего вопроса с *:: after и *:: before используется для управления появляющимися пробелами. Если вы этого не сделаете, размер окна - это контент-бокс, и вы увидите разницу (даже не увидеть на наших глазах) в промежутке.
Вы можете получить дополнительную информацию об размеру окна здесь.
Для меня это кажется устаревшим, потому что селектор * уже будет отмечать все элементы.
Нет. * селектор будет выбирать только реальный селектор, который находится в DOM-Tree.
Здесь изображение, которое я сделал для вас, используя до и после псевдоэлемента, может вставить элемент следующим образом:
![enter image description here]()
Псевдоэлементы находятся за пределами DOM-дерева. Таким образом, использование *
не будет их выбирать:
![enter image description here]()
Ответ 5
*
target все элементы.
::before
и ::after
являются псевдоэлементами, поэтому они не нацелены на *
, поэтому для их нацеливания используйте код, который вы использовали в OP.
Вы можете сделать сайт, не используя псевдоэлементы, на всех, что есть там, для людей, которые их используют, поэтому они имеют согласованную коробчатую модель и не начинают царапать их головы, когда они идут использовать ::before
или ::after
и он вычисляется по-разному.
Ответ 6
Ниже представлена структура псевдоэлемента из CSS-Tricks
![Pseudo elements structure]()
*
будет нацелен только на элемент.
*::after
и *::before
являются псевдоэлементами, а не действительными, то есть они не являются частью DOM. Они лежат между содержимым и элементом, поэтому вы можете вставить любой дополнительный контент, который вы хотите, без изменения разметки.
Ответ 7
Причина *::before and *::after
равна pseudo-elements
. Они действительно не являются элементами, поэтому они называются pseudo
.
Они не выбраны *
, потому что он выбирает только элементы. Вот почему вы не можете выбрать их