CSS:不向某些元素添加内容后


100

我在理解CSS :after属性的行为时遇到了麻烦。根据规格(在这里此处):

顾名思义,:before:after伪元素指定内容在元素文档树内容之前和之后的位置。

这似乎并未限制哪些元素可以具有:after(或:before)属性。但是,它似乎仅适用于特定元素 ... <p>有效,<img>无效,<input>无效<table>。我可以测试更多,但重点是。请注意,这在各浏览器之间似乎非常一致。是什么决定对象是否可以接受:before:after属性?

Answers:


156

imginput都是被替换的元素

替换的元素是其外观和尺寸由外部资源定义的任何元素。实例包括图像(<img>标记),插件(<object>标签),和形式的元件(<button><textarea><input>,和<select>标签)。所有其他元素类型都可以称为非替换元素。

:before并且:after仅适用于不可替换的元素。

规格

注意。本规范不完全定义的互动 :before:after替换元素(例如HTML中的IMG)与替换元素。这将在以后的规范中更详细地定义。

使用span:before, span:after,DOM如下所示:

<span><before></before>Content of span<after></after></span>

显然,这不适用于<img src="" />


2
“生成的内容不会更改文档树。” 因此,如果您能<before></before>在源代码中找到类似“ ”的东西,我会感到惊讶。
2011年

4
@Knu:你是对的,我解释得很糟。你将永远找不到<before></before>。我应该说“假装DOM”之类的话。重点是要显示:before:after处于元素内部,而不是元素外部。
2011年

不,它们不存储在影子DOM中。
工具

3
所引用的规范没有这样说明,:before并且:after不适用于替换的元素;它只是说它没有“完全定义”如何以及将来如何定义(到目前为止尚未发生)。DOM中发生的事情与此处无关。尽管浏览器不支持某些元素支持这些伪元素,但规范并不在其中,而是实现方式。
Jukka K. Korpela 2014年

我曾经认为逻辑上的解释是::before::after不适用于从来没有实际内容的void(空)元素,在此之前/之后它们都可以适用。但是令人惊讶的是,它们hr在几乎所有浏览器中都适用于element。
Ilya Streltsyn 2014年

9

:before并且:after要求工作的替换元素,和CSS规范没有指定他们将如何为他们工作,并替换元素的概念有些模糊。

CSS 2.1规范明确建议它们可以为替换的元素工作,只是说它没有“完全定义”操作方式。这涉及到一个问题,一个被替换的元素应该具有自己的视觉呈现,这不受CSS的控制,而伪元素应该在元素的内容中添加一些内容。规范补充说,这将在将来的规范中“更详细地”定义,但是到目前为止还没有发生。

浏览器供应商只是决定通过根本不对某些元素实现这些伪元素来避免问题。

完全不清楚“替换的元素”是什么意思,其含义似乎有所改变。它通常被解释为与空元素(具有EMPTY声明内容的元素,即元素不能具有任何内容)相同,但是CSS 2.1本身显示了带有选择器的示例样式表br:before(尽管浏览器忽略了这一点,实现了br它们自己的方式)。可以说,越来越多的元素至少部分进入了CSS渲染的范围。例如,input在现代浏览器中,可以使用CSS在很大程度上控制元素(包括其字体,颜色等)。

当前的浏览器(Firefox,IE,Chrome)似乎不支持空元素的:after:before伪元素hr。对于hr,IE和Chrome将生成的内容放在带边框的框内,该框是的实现hr;内容使盒子更高。Firefox将两个(!)伪元素的内容放在作为其实现的水平规则之后hr。此变体说明了CSS 2.1中提到的“交互”问题的种类。

通常要求这些伪元素不能用于空元素,因为它们的HTML定义不允许任何内容。这是一个类别错误。标记语言的语法规则不限制您可以在CSS中执行的操作

总而言之,:after并且:before当前不适用于空元素(除了略有限制hr),但这主要是由于实现,并且将来可能会发生变化。


-1

没有结束标记的元素是空元素,它们不能在其中显示内容:

https://www.w3.org/TR/html5/syntax.html#void-elements

所有Blink,Webkit和Quantum浏览器都仅允许您在复选框上创建伪元素,但这是有争议的,因为没有任何规范允许这种行为。

这是一个例子:https : //codepen.io/equinusocio/pen/BOBaEM/

input[type="checkbox"] {
  appearance: none;
  color: #000;
  width: 42px;
  height: 24px;
  border: 1px solid currentColor;
  border-radius: 100px;
  cursor: pointer;
  transition: all 100ms;
  background-size: 30%;
  outline: none;
  position: relative;
  box-sizing: border-box;
  background-color: #eee;
  transition: background-color 200ms;

  &::before {
    content: '';
    position: absolute;
    left: 2px;
    top: 2px;
    bottom: 2px;
    height: 18px;
    width: 18px;
    border-radius: 50%;
    background-color: currentColor;
    will-change: transform;
    transition: transform 200ms cubic-bezier(.01,.65,.23,1);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  }

  &:checked {
    background-color: aquamarine;

    &::before {
      transform: translateX(100%);
    }
  }
}

它不会在所有浏览器中都起作用...并且没有规范说现在我们可以 ..如果您有一个,请与我们分享,因为考虑输入的伪元素并不安全
Temani Afif

它适用于除IE之外的所有浏览器。IE 9不支持flexbox,所以问题出在哪里。该解决方案可在所有Blink,Webkit和Quantum浏览器上使用,并且对于在像Electron这样仅使用Webkit的环境中工作的人们非常有用。
Mattia Astorino

就像您在回答中说的那样,它没有规范,因此有一天它可能会停止工作。在没有定义任何规范的情况下,这并不是唯一的行为和工作方式,但我们绝对不应依赖它们并说它们有效。就像过时的标签一样,它们仍然可以工作,但是我们应该停止使用它们,因为有一天它们将无法使用。是的,这对人们有用,我的评论也对警告人们他们应该意识到这不是官方的有用。
Temani Afif
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.