为什么将*选择器与* :: before和* :: after结合使用

时间:2015-07-09 12:16:26

标签: css twitter-bootstrap css-selectors

我正在查看Twitter引导程序框架,我确实有一个非常小的问题。

我会看到以下部分,以便将盒子模型设置为border-box

*, *::after, *::before { box-sizing: border-box; }

但是,如果您查看CSS规范*会定位所有元素,那么为什么要使用*::after*::before选择器?

对我来说,这似乎已经过时,因为*选择器已经标记了所有元素。

7 个答案:

答案 0 :(得分:18)

请参阅这两个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-boxborder-box之间的大小调整只会改变段落的大小,不是它的::after元素。正如其他人所指出的那样,这是因为它们的名称是元素,必须单独定位。

看起来*不会以psuedo元素为目标(正如@Harry指出的那样,按照the CSS specification

答案 1 :(得分:17)

*选择所有元素吗?

*不包含伪元素。它们仅涵盖DOM中存在的真实元素。

  

来自W3C Spec

     

通用选择器,写为CSS qualified name [CSS3NAMESPACE],带有星号(* U + 002A)作为本地名称,表示任何元素类型的限定名称。如果没有为选择器指定默认命名空间,它表示任何命名空间(包括没有命名空间的那些)中文档树中的任何单个元素。

重点是我的

为什么在*选择器下指定的属性适用于某些但不适用于其他人?

对于像color这样的某些属性,你会得到*应用于包括伪在内的所有元素的错觉,因为它们是孩子可以从其父级继承的属性。

另一方面,

box-sizing不是继承属性,因此必须在伪元素上明确提及。

注意:虽然伪元素被命名为beforeafter,但它们实际上是它所附加元素的子元素。

说明继承的示例:

查看下面的代码段,看看黑色border仅适用于真实元素。在伪元素中,只有p:after获得border,因为它直接在伪元素本身上指定。 div:after没有边框。

&#13;
&#13;
* { /* 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;
}
&#13;
<div>abcd</div>
<p>abcd</p>
&#13;
&#13;
&#13;

可继承属性的列表是什么?

您可以找到有关孩子可以从其父here继承的属性列表的更多详细信息。

答案 2 :(得分:5)

你基本上回答了自己的问题。 ::before::after伪元素。这个名字甚至暗示它们不代表真正的元素。

选择器*, *::before, *::after旨在匹配:

  • * DOM中的所有元素
  • *::before相对于DOM中存在的所有元素的伪元素::before
  • *::after相对于DOM中存在的所有元素的伪元素::after

由于伪元素未被限定为完整元素(<html><head><body>等)并且不属于DOM,因此它们不匹配星号字符。它们仅在参考另一个元素时被选中。出于同样的原因,无法在JavaScript中选择它们。 JavaScript只选择它可以在DOM中找到的元素,这在引用伪元素时是不正确的。

引用MDN

  

您只能在选择器中使用一个伪元素。它必须出现在语句中的简单选择器之后。

简单选择器由W3C使用以下定义定义:

  

simple selector可以是type selectoruniversal selectorattribute selectorclass selectorID selectorpseudo-class。< / p>

简单选择器用于匹配DOM中存在的元素。伪元素必须遵循简单的选择器,因为它不是DOM本身的一部分,因此不能归类为元素。由于*是一个简单的选择器,特别是universal selector,因此CSS中的伪元素可以链接到它以匹配所有特定的伪元素类型。如果没有伪元素选择器,则只保留一个简单的选择器(*)。

答案 3 :(得分:4)

:: after和:: before是pseudo elements,并且它们相应地在元素之后或之前插入样式。

对于你的问题,* :: after和* :: before用于管理出现的空格。如果你没有,那么盒子大小就是内容盒,你会看到间距的差异(甚至我们的眼睛看不到)。

您可以获取有关框大小调整here的更多信息。

  

对我来说,这似乎已经过时,因为*选择器已经标记了所有元素。

没有。 *选择器只会选择DOM-Tree中的真实选择器。

这里是我为你制作的图片,使用伪元素之前和之后可以插入这样的元素:

enter image description here

伪元素在DOM-Tree之外。因此,使用*不会选择它们:

enter image description here

答案 4 :(得分:2)

*定位all elements

::before::afterpseudo elements,因此不会被*定位,因此您也可以使用您在OP中使用的代码来定位这些代码。

你可以在不使用伪元素的情况下创建一个网站,只有那些使用它们的人才能拥有一致的盒子模型,并且当他们去使用{{1}时不要开始摸不着头脑}或::before它的计算方式不同。

答案 5 :(得分:2)

以下是来自CSS-Tricks

的伪元素结构

Pseudo elements structure

*将仅定位元素。

*::after*::before是伪元素,不是真实的,即它们不是DOM的一部分。它们位于内容和元素之间,因此您可以在不修改标记的情况下插入所需的任何额外内容。

答案 6 :(得分:2)

原因是*::before and *::afterpseudo-elements。它们确实不是因为它们被称为pseudo的原因。

*未选择它们,因为它仅选择元素。这就是为什么你不能选择它们