【问题标题】:CSS :after not adding content to certain elementsCSS:在不向某些元素添加内容之后
【发布时间】:2015-04-11 02:06:51
【问题描述】:

我无法理解 CSS :after 属性的行为。根据规范(herehere):

正如其名称所示,:before:after 伪元素指定了元素文档树内容之前和之后的内容位置。

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

【问题讨论】:

    标签: css pseudo-element


    【解决方案1】:

    我花了几个小时拔头发,却发现其他一些 css 覆盖了我的选择器的 content(或 display:none)属性。

    例如,如果以下代码写在其他地方,beforeafter 元素将永远不会显示:

    #id > child:before {
      content: none!important;
    }
    <html>
    <div id="id" class="class">
      <child>
        Before element is not showing
      </child>
    
    </div>
    <style>
      child:before {
        content: 'before';
        color: 'red';
      }
    </style>
    
    </html>

    只需找到覆盖您的样式的 css 和垃圾邮件 stronger 选择器和 !important 以使其工作

    #id>child:before {
      content: none!important;
    }
    <html>
    <div id="id" class="class">
      <child>
        Before element is <strong>showing</strong>
      </child>
    
    </div>
    <style>
      #id.class>child:before {
        content: 'before'!important;
        border: 1px solid red;
      }
    </style>
    
    </html>

    【讨论】:

      【解决方案2】:

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

      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%);
          }
        }
      }
      

      【讨论】:

      • 它不会在所有浏览器中工作......并且没有规范说现在我们可以 ..如果你有一个请分享它,因为它不安全考虑带输入的伪元素
      • 它适用于除 IE 之外的所有浏览器。 IE 9 甚至不支持 flexbox,所以问题出在哪里。该解决方案适用于所有 Blink、Webkit 和 Quantum 浏览器,对于在 Electron 等纯 webkit 环境中工作的人非常有用。
      • 就像你在回答中所说的那样,它没有规范,所以有一天它可能会停止工作。在没有定义任何规范的情况下,它并不是唯一可以运行和工作的东西,但我们永远不应该依赖它们并说它们可以工作。这就像过时的标签,它们仍然有效,但我们应该停止使用它们,因为有一天它们不会了。所以是的,这对人们有用,我的 cmets 也有助于警告人们他们应该意识到这不是官方的。
      【解决方案3】:

      imginput 都是 replaced elements

      替换元素是外观和尺寸符合 由外部资源定义。示例包括图像(&lt;img&gt; 标签), 插件(&lt;object&gt; 标签)和表单元素(&lt;button&gt;&lt;textarea&gt;&lt;input&gt;&lt;select&gt; 标签)。所有其他元素类型都可以参考 作为不可替换的元素。

      :before:after 仅适用于非替换元素。

      来自the spec

      注意。本规范没有完全定义交互 :before:after 带有替换元素(例如 HTML 中的 IMG)。这 将在未来的规范中更详细地定义。

      使用span:before, span:after,DOM 看起来像这样:

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

      显然,这不适用于&lt;img src="" /&gt;

      【讨论】:

      • “生成的内容不会改变文档树。”因此,如果您能够在源代码中找到类似“&lt;before&gt;&lt;/before&gt;”的内容,我会感到惊讶。
      • @Knu:你说得对,我解释得很糟糕。你永远找不到&lt;before&gt;&lt;/before&gt;。我应该说“假装 DOM”之类的。关键是要表明:before:after 在元素内部,而不是在元素外部。
      • 不,它们没有存储在 shadow DOM 中。
      • 引用的规范并没有说:before:after 不适用于替换元素;它只是说它没有“完全定义”如何以及将来会如何定义(到目前为止还没有发生)。 DOM 中发生的事情在这里无关紧要。虽然浏览器不支持某些元素的这些伪元素,但规范中没有,这正是实现所做的。
      • 我曾经认为 ::before::after 不适用于 void (空)元素的解释是合乎逻辑的,该元素之前/之后没有实际内容他们可以申请。但令人惊讶的是,它们几乎适用于所有浏览器中的hr 元素。
      【解决方案4】:

      :before:after 不是必需 为替换元素工作,CSS 规范没有指定它们如何工作,替换元素的概念有些模糊。

      CSS 2.1 规范明确suggests 他们可以为替换元素工作,只是说它没有“完全定义”如何。这涉及到一个被替换的元素应该有自己的视觉渲染,它不受 CSS 控制,而伪元素应该在元素的内容中添加一些东西。该规范补充说,这将在未来的规范中“更详细地”定义,但到目前为止还没有发生。

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

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

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

      通常声称这些伪元素不能用于空元素,因为它们的 HTML 定义不允许任何内容。这是一个类别错误。标记语言的语法规则并不限制你在 CSS 中可以做什么

      总而言之,:after:before 目前不能用于空元素(hr 除外),但这主要是由于实现,未来可能会发生变化。

      【讨论】: