WebKit 中的 `img` 元素的 CSS `content` 属性是如何工作的?

Posted

技术标签:

【中文标题】WebKit 中的 `img` 元素的 CSS `content` 属性是如何工作的?【英文标题】:How did CSS `content` property work for `img` element in WebKit? 【发布时间】:2016-07-06 11:49:58 【问题描述】:

很久以前有一个 CSS3 生成内容规范草案,它允许 content 属性 for any html element(不仅是 ::before/::after 伪元素),对空元素或替换元素没有任何正式限制。它曾经被 Opera Presto (1, 2) 支持,至少在一定程度上得到了 WebKit (3) 的支持。到 2011 年底,WebKit 对 img 元素的 content 实现似乎有效地将其从一个空的替换元素转换为像 span 这样的非替换元素(甚至它的上下文菜单也发生了变化,删除了像“将图像另存为”这样的选项...')。它还使得应用像img::before 这样的伪元素成为可能。

在当前的 Blink(Chrome 等)实现中,将 content 属性设置为 img 元素没有可见效果。但是 img 元素显然具有不同的结构,具体取决于它是否正确加载或损坏:如果加载,DOM Inspector 会将其显示为简单的空元素,但如果损坏,它会暴露内部 Shadow DOM 结构,如下所示:

<div id="alttext-container" style="overflow: hidden; border: 1px solid silver; display: inline-block; box-sizing: border-box; padding: 1px;">
  <img id="alttext-image"   align="left" style="margin: 0px; float: left; display: inline;">
  <div id="alttext" style="overflow: hidden; display: block;">Alt text</div>
</div>

可能是因为损坏的img 是在阴影divs 的帮助下显示的,所以只能在这种情况下对其应用伪元素(4)。

当前的 WebKit 不支持 img 的伪元素。但是,有趣的是,在为 img (5) 设置 content 属性后,至少 ios 9.2.1 Safari 开始支持它们。

为什么这个属性会做出这样的改变?我猜如果一个空元素获得任何内容(甚至生成),浏览器必须提供一些东西来显示这个内容,有效地用某种容器替换空元素(比如 Blink 的影子div id="alttext-container")和这个容器可以有伪。我错了吗?这种行为不是从最新的 WebKit 版本中删除了吗?

【问题讨论】:

有趣的是.. safari 还显示了 after 元素,即使没有损坏也不显示图像.. 是的,在 Safari 中似乎是 content 属性(未加载/损坏状态)改变了 img 元素的渲染模型。这与 Blink 的行为不同。顺便问一下,你在 OS X Safari 中测试过吗? 令人惊讶,但在任何地方都找不到它的文档.. 在您第一次问这个问题几个月后发布的新版 css-content-3 声明 1)被替换的元素没有 ::before 和 ::after 伪,但是 2)由设置元素的内容属性,您实际上可以更改该元素是被替换还是未被替换。这意味着您可以通过将 img 的内容设置为单个图像值以外的其他内容,从而将其转换为不可替换的元素,从而允许它具有 ::before 和 ::after 伪。但是,如果您将其内容设置为单个图像值,它将保持被替换。 在最新的 ED 中,规范还建议了图像损坏时的处理方式,但没有提及阴影树。 【参考方案1】:

我最近才注意到这一点。我真的很沮丧。很高兴看到有人已经提到它。

你们似乎比我更了解这个话题。所以,可能你已经知道这些方法了,但我还是会写我的解决方案,给像我一样会发现这个话题的后辈。

我需要一种用于损坏图像占位符的方法。 我想我可以检查文件并给出“.brokenimg”类名称以在后端进行标记,并使用 CSS“内容:”更改图像。 但它没有用。 (在 Chrome、Firefox、Opera、Edge、三星的 android 网络浏览器中测试。都一样。)

然后,我尝试更改我的脚本并使用 s 而不是 s。并在 CSS 中尝试过;

.brokenimg::before  content: url(picture.jpg); 

它几乎起作用了,但是这真的很有限,而且这不是我需要的。

所以,用 JavaScript 事件解决了我的问题;

<img onerror="this.src='broken.jpg'" src="image.jpg">

我知道这不是一回事。但就我而言,它完全符合我的需要。

我想我们现在必须找到类似的方法。

【讨论】:

是的,已经有人提议向 CSS 提供一个功能,就像用于损坏图像的 onerror 属性一样。非常有趣的东西,但不知道该提案是否会成为现实!

以上是关于WebKit 中的 `img` 元素的 CSS `content` 属性是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

CSS mask的用法

如何查看-webkit-scrollbar和-webkit-scrollbar-track等的默认CSS样式?

CSS3缩放和移动img上的动画效果

css - 移动端reset汇总与注释

img width 100% in display: box (css flexbox parent)

filter