w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.48k stars 661 forks source link

[css-content] Description about <content-replacement> doesn't match what implementations do for pseudo-elements #2657

Open upsuper opened 6 years ago

upsuper commented 6 years ago

The spec currently says that <content-replacement> value should:

Makes the element or pseudo-element a replaced element, filled with the specified <image>. Its normal contents are suppressed and do not generate boxes, as if they were display: none.

And there is a note in <content-list> value mentioning:

If the value of <content-list> is a single <image>, it must instead be interpreted as a <content-replacement>.

This doesn't match what content with a single url means in CSS 2, nor how it is implemented in browsers.

Given #2656, I would suggest that we make the single url mean <content-list> for pseudo-element, and <content-replacement> only for elements.

[ Edited by @dbaron to add some missing backticks in the second quoted section. ]

faceless2 commented 6 years ago

I suspect the reason there is a distinction between content-list and content-replacement is for this situation:

p::before {
    content: url(image.svg);
    height: 1em;
}

If this is treated as a content-replacement, the image is given a height. If it's treated as a content-list, then it isn't. Given this is the only way to set a height on an image used in a pseudo-element. I think the distinction is important and must remain as defined, applying to both elements and pseudo-elements.

Although none of the browsers currently support this, this approach is used quite heavily in the Antenna House demo document available for download at https://www.antennahouse.com/antenna1/css/

SelenIT commented 6 years ago

2889 seems also to be relevant here.

timdream commented 5 years ago

The note here states:

Note: Replaced elements use different layout rules than normal elements. (In effect, it becomes equivalent to an HTML <img> element.)

However the size of SVG can be different if I do this:

<style>

.container {
    width: 200px;
    height: 200px;
    border: 1px solid red;
}

#first::after {
    content: url(image.svg);
}

#first::after,
.container > img {
    display: block;
    width: 50px;
    height: 50px;
}

</style>

<div class="container" id="first">
</div>

<div class="container">
    <img src="image.svg">
</div>

when image.svg comes with width and height:

<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
  <circle cx="50" cy="50" r="50"/>
</svg>
image
faceless2 commented 5 years ago

It's a good example of this issue. Safari, Chrome and Firefox all show the first circle as larger, which doesn't match the spec. Prince, our renderer and (I believe based on analysis, although I don't have it here to test with) Antenna House renderer will all render both circles the same size.

This is going to become more of an issue once ::marker pseudo-elements become widely supported - at present the only browser that does support them is Firefox. Converting your example to this...

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
#mylist li::marker {
    content: url(image.svg);
    height: 1em;
}
</style>
</head>
<body>
<ol id="mylist">
 <li>Item 1</li>
 <li>Item 2</li>
</ol>
</body>
</html>

... and testing in Firefox shows the circles are not resized to 1em, as you'd expect. I think the browsers need to change to match the specified behaviour, not the other way around.

(live example demonstrating the above at https://jsbin.com/jozeveg/1/edit?html,output)