同一个元素可以有多个:before伪元素吗?

166

一个元素是否可以拥有多个相同的 :before 伪元素?

.circle:before {
    content: "\25CF";
    font-size: 19px;
}
.now:before{
    content: "Now";
    font-size: 19px;
    color: black;
}

我正在尝试使用jQuery将上述样式应用于同一元素,但只有最近的一个被应用,从未同时应用两个。


从技术上讲,做类似于.my_element::after {content: "main";} 和 .my_element::after::before {content: "sub";} 这样的事情是可能的。但遗憾的是这并不起作用。这个想法是在主伪元素(main)之上添加另一个伪元素(sub)。 - Jawad
5个回答

132
在CSS2.1中,每个元素在任何时候最多只能有一种伪元素。这意味着一个元素可以同时拥有:before:after伪元素,但是不能超过每种类型的一个。因此,当您有多个匹配同一元素的:before规则时,它们都会级联应用到单个:before伪元素上,就像普通元素一样。在您的例子中,最终结果如下所示:
.circle.now:before {
    content: "Now";
    font-size: 19px;
    color: black;
}

如你所见,只有最高优先级的content声明(即最后出现的那个)将生效,其他声明将被丢弃,就像任何其他 CSS 属性一样。

这种行为在 CSS2.1 的选择器部分中有描述:

伪元素在 CSS 中的行为与实际元素完全相同,但有以下例外和其他情况

这意味着带有伪元素的选择器与普通元素的选择器工作方式相同。这也意味着级联应该以相同的方式生效。奇怪的是,CSS2.1似乎是唯一的参考文献; css3-selectorscss3-cascade 都没有提到这一点,尚不清楚它是否会在未来的规范中得到澄清。

如果一个元素可以与同一伪元素的多个选择器匹配,而且您希望所有这些选择器都能以某种方式应用,则需要创建附加的 CSS 规则,其中包含组合选择器,以便您可以准确指定浏览器在这些情况下应该执行的操作。我无法在此提供包括content属性的完整示例,因为例如不清楚符号或文本应该先出现。但是,您需要使用的此组合规则的选择器是.circle.now:before.now.circle:before - 选择哪个选择器是个人喜好,因为两个选择器是等效的,只有content属性的值需要自己定义。

如果您仍需要具体示例,请参见我的回答这个类似的问题

旧版 css3-content 规范包含一个关于使用与 CSS2.1 级联兼容的表示法插入多个 ::before::after 伪元素的部分,但请注意,该特定文档已经过时-自 2003 年以来未更新,并且在过去的十年中没有人实现了该功能。好消息是,被抛弃的文档正在以css-content-3css-pseudo-4的形式进行重写。坏消息是,多个伪元素功能在任何规范中都找不到,这可能是由于缺乏实现者的兴趣所致。


12
在这种情况下,如果一个元素同时属于 circlenow 两个类别,则两个规则都适用于该元素的 :before 伪元素,但是普通的 CSS 规则意味着只有一个 content 设置会生效(按照正常的级联规则)。关键在于 content 不会累加。 - Jukka K. Korpela
原来我数月前回答的这个问题是一个重复的问题。由于这个问题获得了更多的关注并且排在前面,我已经将另一个回答中的大部分信息(基本上扩展了@Jukka所说的一切)合并到了这个问题中。 - BoltClock
3
经过13年的时间,css-content-3草案终于有了更新。伪元素部分已被移除,取而代之的是css-pseudo-4,它不允许多个::before::after伪元素。 - Oriol
@Oriol:实际上是12年了。css-pseudo-4的FPWD是去年引入的,当时css-content-3已经更新指向新规范。 - BoltClock
@BoltClock 风格表内容3的编辑器草案在drafts.csswg.org网站上已经更新了一段时间,但是在w3.org网站上的工作草案直到最近仍然是2003年的版本。我仍然抱有一些希望... - Oriol

46

如果你的主要元素有一些子元素或文本,你可以利用它。

将你的主要元素定位为相对定位(或绝对/固定定位),并使用两个绝对定位的伪元素:before和:after(在我的情况下必须是绝对定位,关于你的情况我不清楚)。

现在,如果你想要一个额外的伪元素,在主要元素的一个子元素上附加一个绝对定位的:before(如果只有文本,请将其放在一个span中,现在你有一个元素),这个元素将开始像它的所有者是你的主要元素。

这个元素将开始像它的所有者是你的主要元素。

HTML

<div class="circle">
    <span>Some text</span>
</div>

CSS

.circle {
    position: relative; /* or absolute/fixed */
}

.circle:before {
    position: absolute;
    content: "";
    /* more styles: width, height, etc */
}

.circle:after {
    position: absolute;
    content: "";
    /* more styles: width, height, etc */
}

.circle span {
    /* not relative/absolute/fixed */
}

.circle span:before {
    position: absolute;
    content: "";
    /* more styles: width, height, etc */
}

4
虽然所选答案准确,但对于我的情况,这是一个可行的解决方法。我能够模拟具有多个伪元素而无需向DOM添加更多节点! - matt.kauffman23
@matt.kauffman23,你能告诉我你是如何模拟的吗? - BbIKTOP
4
@BbIKTOP 抱歉刚看到你的评论。在我的情况下,我正在处理一个始终有子元素的模态框,所以最终得到了这样的代码:.modal:first-child:before { … - matt.kauffman23
1
@matt.kauffman23 能够在6年后还记得这样的细节,你的记忆力真是太好了! - ChrisOdney
2
@ChrisOdney,如果Matt一直在尝试使其兼容IE5.5,那么他可能一直在开发同一个应用程序/网站 ;) - OXiGEN

7
我使用以下方法解决了这个问题:
.element:before {
    font-family: "Font Awesome 5 Free" , "CircularStd";
    content: "\f017" " Date";
}

使用字体家族“font awesome 5 free”来显示图标,之后,我们需要再次指定所使用的字体,因为如果我们不这样做,浏览器将使用默认字体(如新罗马字体或类似字体)。


太完美了,这正是我需要的!不过这是标准语法还是一种技巧呢? - Prid

0

您还可以在内容字段中使用图像/图标加文本

例如:

p.album-title::after {
  content: url('https://...camera-icon-blue.png') ' View >';
  display: block;
  ...;
}

0
在 ::after css 中设置 content:'任何文本' 并添加带有来自外部 svg 文件的 svg 文本的 background-image url(anySvgText.svg) 或内联 svg 代码 url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="30" width="200"><text x="0" y="15" fill="black" style="font-family: tahoma;">任何第二个文本</text></svg>') 此外,您也可以仅使用 svg 替代 content 值。但是,您必须将空字符串 (content: '') 设置为显示 ::after 样式。

.circle:before {
    content: "\25CF";
    font-size: 19px;
    color: red;
    width: 200px;
    display: block;
    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="30" width="200"><text x="0" y="15" fill="black" style="font-family: tahoma;">Now</text></svg>');
    background-position-x: 15px;
}
<div class="circle"></div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接