不要为伪类:before/:after设置样式

4
有没有办法仅样式化基本元素而不是它的:before或:after伪类?
<div id="main">bar</div>

#main:before {
  content:'foo'
}
#main {
  background:red;
}

我只想让“bar”以红色为底色,而不是“foo”的部分。当然,我可以在另一个CSS选择器#main:before{background:white}中否定它,但我希望能以一条语句完成。我尝试了以下代码:

#main:not(:before) {
  background:red;
}

编辑:我需要将它不仅用于背景颜色,还要用于字体大小等。


问题的一部分在于错误地称呼这些伪类。它们是伪元素,与伪类不同,它们不允许在 :not() 伪类中使用。(这也使得使用 :not() 不正确。) - BoltClock
4个回答

4

不需要像:not(:before)这样的东西。选择器#main已经包含了这个功能。为了验证这一点,可以设置一个非继承属性,比如border

#main { border: 1px solid; }

这将在主要内容周围绘制一个边框。它不会在生成的内容周围绘制另一个边框。因此,选择器只针对#main。您生成的内容具有透明背景(默认)。
问题在于生成的内容存在于#main内部的一个匿名框中:
+-------------+
| +-----+     |
| | foo | bar |
| +-----+     |
+-------------+

基本上,这种情况与之前相同。

<div id="main">
    <span class="before">foo</span>
    bar
</div>

你可以很容易地看出,仅对单词bar添加背景是不可能的,因为#main的背景会透过元素。如果使用#main:not(.before)作为选择器,则不会发生任何变化。

你唯一能做的就是通过将白色背景添加到.before来覆盖它。或者像另一个答案中建议的那样,在bar周围插入元素。

其他属性如font会继承,因此问题的原因在技术上是不同的,但解决方法相同。


3
没有办法在不使用伪元素:before:after的情况下引用元素内容,除非将该内容包装在内部元素中。没有任何选择器可以实现这一目的。但请注意,对元素设置的任何内容仅适用于整个元素;只有通过继承(对于可继承属性)才会影响伪元素的渲染。背景属性是特例,因为它们不被继承,但由于初始值为background: transparent,它们几乎像继承一样工作。

1
如果您检查DOM,您会看到::before伪元素在#main内呈现。这就是为什么您的#main:before继承了#main的背景色的原因。
我认为唯一的解决办法是在“bar”周围添加一个span标签。
<div id="main"><span>bar</span></div>

#main:before {
  content:'foo';
}
#main>span {
  background:red;
}

谢谢,这已经是我正在寻找的解决方案的一半了 :) 不过我仍然更喜欢使用:not()选择器 :) - Lukáš Řádek
即使你有一个:not,你也不能说“这个元素而不是它的:before”。伪元素在它们的父元素内部。 - Eevee
1
:not存在的问题是它不能包含伪元素,这正是你所需要的。规范根本不支持它,这就是你尝试的 CSS 无法工作的原因。请参阅mdn文档:https://developer.mozilla.org/en-US/docs/Web/CSS/:not。 - Gaute Løken

0
我想根据情况,你可以这样做:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>

#main {
  background:red;
  position: relative;
  margin-left: 2em;
}

#main:before {
  content:'foo';
  position: absolute;
  margin-left: -2em;
}

</style>
</head>
<body>

<div id="main">bar</div>

</body>
</html>

那个方法有点可行,但我没有表达清楚。我需要能够单独为它们设置所有样式(不仅仅是颜色,还包括字体大小等)。只是针对主要元素和之前的元素进行定位。 - Lukáš Řádek

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