How did CSS `content` property work for `img` elem

2020-02-27 10:35发布

问题:

Long time ago there was a draft of CSS3 Generated Content spec which allowed the content property for any HTML element (not only ::before/::after pseudo-elements), without any formal restriction for empty or replaced elements. It was once supported by Opera Presto (1, 2) and, at least to some extent, by WebKit (3). By the end of 2011, WebKit's implementation of content for img element seemed to effectively convert it from an empty replaced element to non-replaced element like span (even its context menu changed, removing options like 'Save image as...'). It also made it possible to apply pseudo elements like img::before.

In the current Blink (Chrome etc.) implementation, seeting content property to img element has no visible effect. But the img element clearly has different structure depending on whether it loaded properly or is broken: if loaded, it is shown by the DOM Inspector as a simple empty element, but if broken, it exposes the internal Shadow DOM structure like this:

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

Probably because the broken img is displayed with the help of the shadow divs, it's possible to apply pseudo elements to it in this case only (4).

Current WebKit doesn't support pseudo elements for img. But, interestingly, at least iOS 9.2.1 Safari starts to support them after setting the content property for that img (5).

Why does this property make such change? I guess that if an empty element gets any content (even generated), the browser has to provide something to display this content in, effectively replacing the empty element with some sort of a container (like Blink's shadow div id="alttext-container"), and this container can have pseudos. Am I wrong? And wasn't this behavior removed from the latest WebKit versions?

回答1:

I just recently noticed this. I was really frustrated with it. Glad to see somebody already mentioned it.

You guys seem much more knowledgeable on the topic than me. So, probably you already know these methods, but I will write my solution anyway, for juniors who will find this topic like myself.

I needed a method for broken image placeholders. I thought I could check files and give ".brokenimg" class names to tag in Back-end and change the image with CSS "content:". But It didn't work. (Tested in Chrome, Firefox, Opera, Edge, Samsung's Android Web Browser. All same.)

Then, I tried to change my script and use s instead of s. And tried this in CSS;

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

It almost worked but, But this is really limited and It wasn't what I needed.

So, solved my problem with JavaScript event;

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

I know it is not the same thing. But in my case, it did exactly what I needed.

I guess we have to find ways like these for now.