什么时候允许在选项元素上设置伪元素的样式?

When is it allowed to style pseudo elements on an option element?

我正在尝试将伪元素与 <option> 元素一起使用。但是,我观察到使用不同浏览器进行渲染时存在一些差异。

所以我的问题是,什么时候允许将伪元素(例如 ::before::after::first-letter<option> 元素一起使用?


上下文

假设我有三个选项元素,

<select>
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
</select>

我想使用 ::before::after 选择器在某些元素前后添加一些内容。因此,我将向其中一个元素添加 CSS class "special" 并像这样添加 CSS 规则,

.special::before {
  content: " Before - ";
}

.special::after {
  content: " - After ";
}
<select>
  <option value="1" class="special">One</option>
  <option value="2">Two</option>
  <option value="3">Three</option>
</select>

它在任何浏览器中都不起作用。但是,现在如果我简单地修改 select 元素以允许多选,伪元素将在 Chrome、Firefox 和 Edge 中工作,但 仍然不能在 IE 11.

.special::before {
  content: " Before - ";
}

.special::after {
  content: " - After ";
}
<select multiple>
  <option value="1" class="special">One</option>
  <option value="2">Two</option>
  <option value="3">Three</option>
</select>

我可以在这些伪元素上应用不同的样式,例如颜色、字体系列、字体大小,甚至显示!

.special::before {
  content: " Before - ";
  color: red;
  font-size: 15px;
}

.special::after {
  content: " - After ";
  font-family: Consolas, Arial, Verdana;
  display: block;
  color: blue;
}
<select multiple>
  <option value="1" class="special">One</option>
  <option value="2">Two</option>
  <option value="3">Three</option>
</select>


但是,发现该行为与Chrome、Firefox 和Edge 也不完全一致。

例如,在 Chrome 中,如果我使用 ::first-letter 伪元素,它适用于 select 元素下的选项元素,但不适用于 optgroup 下的选项元素元素。但是它在 Firefox 和 Edge 上都能正常工作。

.special::first-letter {
  color: red;
  font-size: 20px;
}

select {
  height: 100px;
}
<select multiple>
  <option value="1" class="special">One</option>
  <option value="2">Two</option>
  <option value="3">Three</option>
</select>

<select multiple>
  <optgroup label="Item 1">
    <option value="1" class="special">One</option>
  </optgroup>
  <optgroup label="Other items">
    <option value="2">Two</option>
    <option value="3">Three</option>
  </optgroup>
</select>

注意:当在 datalist 元素中使用选项元素时,此方法的 None 有效。但我现在不关心那个。如果你想看,我有 some examples here


经过搜索,我发现 <option> element is considered a replaced element only in certain cases。但是,我无法在网上找到任何关于 何时 允许使用伪元素的文档。

如果您正在寻找 standards-based 答案,简短的回答是 CSS 当前不支持将 pseudo-elements 与表单元素一起使用,无论是 ::before/::after,或其他 pseudo-elements,例如 ::first-letter。结果,每个浏览器都做自己的事情,几乎没有互操作性。

如前所述,对于大多数 pseudo-elements 和表单元素 and/or 替换内容之间的交互没有规范任何规范中对此的唯一声明是在 css-content-3 中,它说:

Note: Replaced elements do not have ::before or ::after pseudo-elements; the content property replaces their entire contents.

但情况变得更糟:严格来说,表单元素 与替换内容 不是一回事(尽管包括我在内的很多人经常说相反),尽管他们的行为非常相似。表单元素恰好有 platform-specific 布局规则,阻止它们完全可以使用 CSS 设置样式。它们可能支持一些常见的 CSS 属性并在某种程度上遵守盒子模型,但它们有一些限制,使您无法将它们完全视为常规 non-replaced 元素。这确实是他们与替换内容唯一的共同点。

最重要的是,任何当前的 CSS 规范都没有涵盖表单元素的呈现。正在努力 尝试 并在 css-ui-4 中控制这一切,但我不会屏住呼吸。