Open Bug 1832901 Opened 1 years ago Updated 1 day ago

`content: linear-gradient(...)` doesn't paint on ::before/::after pseudo elements

Categories

(Core :: CSS Parsing and Computation, defect)

defect

Tracking

()

People

(Reporter: dholbert, Unassigned)

References

Details

Attachments

(4 files)

Attached file testcase 1

[Spinning off from bug 1684958 comment 11. Original testcase on codepen: https://codepen.io/CodeRedDigital/pen/poxVmyq )

STR:

  1. Load attached testcase.

EXPECTED RESULTS:
A gradient in each square.

ACTUAL RESULTS:
No gradient in the last two squares (the ones using ::before { content: linear-gradient(...);})

Chrome gives EXPECTED RESULTS.
Firefox gives ACTUAL RESULTS.

(ni=emilio since I suspect he'll be interested to take a look, as a followup from work in bug 1684958.)

Flags: needinfo?(emilio)

So the image is there but gradients don't have an aspect ratio nor an intrinsic size, so the image ends up zero-sized... The spec isn't super clear on what to do here tbh. I'm not sure how chrome ends up with that size, I guess they give the gradient an aspect-ratio of 1?

Flags: needinfo?(emilio)
Flags: needinfo?(emilio)

Yeah, in the 3rd box in the attached testcase, where the ::before has no size properties, I would imagine it might be correct for that pseudo-element to be zero-sized. There's a case to be made for that, at least. (Arguably, for consistency, it should behave the same as an SVG image with no viewBox or size attributes on its SVG element -- I wonder how that behaves.)

In the testcase's 4th box where there's an explicit size, though, it seems pretty clear that it should behave as it does in the 1st and 2nd boxes (albeit with a slightly smaller box to fill, 35px rather than 40px).

(In reply to Daniel Holbert [:dholbert] from comment #3)

Yeah, in the 3rd box in the attached testcase, where the ::before has no size properties, I would imagine it might be correct for that pseudo-element to be zero-sized. There's a case to be made for that, at least. (Arguably, for consistency, it should behave the same as an SVG image with no viewBox or size attributes on its SVG element -- I wonder how that behaves.)

I agree it should behave as an svg with no ratio or intrinsic size.

In the testcase's 4th box where there's an explicit size, though, it seems pretty clear that it should behave as it does in the 1st and 2nd boxes (albeit with a slightly smaller box to fill, 35px rather than 40px).

content: linear-gradient() really wraps stuff in another box, so there's an extra layer of indirection fwiw.

Hmm, so my expectations about how dimensionless-SVG would behave don't quite match reality.

Gecko (Firefox Nightly), Blink (Chrome dev), and WebKit (epiphany) all render the 3rd and 4th boxes in this "testcase 2" with the image sized to 300x150 (the fallback size, which is the same size that you get for an unsized img element:

data:text/html,<img src="https://bug1832901.bmoattachments.org/attachment.cgi?id=9333430">

That's probably not a great reference for how linear-gradient should behave. But it is at least an indication that painting something is better than painting nothing.

(In reply to Emilio Cobos Álvarez (:emilio) from comment #5)

I agree it should behave as an svg with no ratio or intrinsic size.

I'm not so sure now. :) See testcase 2.

In the testcase's 4th box where there's an explicit size, though, it seems pretty clear that it should behave as it does in the 1st and 2nd boxes (albeit with a slightly smaller box to fill, 35px rather than 40px).

content: linear-gradient() really wraps stuff in another box, so there's an extra layer of indirection fwiw.

That helps explain the behaviors here. I'm not sure I understand why that's behaving differently between boxes 2 and 4 in testcase 1 (both of them have content: linear-gradient() and an explicit size set on the same thing (in box 2 it's an element, in box 4 it's a pseudo-element). But I imagine there may be some historical reason that it works differently, and maybe there's another secret wrapper in box 4, maybe?

Attachment #9333432 - Attachment description: testcase 2 (no bug, just for comparison) → testcase 2: now with a dimensionless SVG image instead of a linear-gradient (no bug, just for comparison)

I attached a patch that adds some intrinsic size / ratio to these images just for demonstration purposes, but I'm not sure what the right behavior should be here. Might be worth raising an issue in the CSSWG repo.

Flags: needinfo?(emilio)

I found my way here via the bug links for Firefox in https://developer.mozilla.org/en-US/docs/Web/CSS/content#browser_compatibility, as part of trying to determine the right status for the overall image-set() feature in https://github.com/web-platform-dx/web-features. One of those notes claim that "content: image-set(…); doesn't paint on ::before/::after pseudo elements" but that's not what this bug says and it seems to work just fine in this test case:
https://software.hixie.ch/utilities/js/live-dom-viewer/?saved=12629

For content: linear-gradient(...) it wasn't easy to find the case that would work in Chrome but not in Firefox, but I think this is one:
https://software.hixie.ch/utilities/js/live-dom-viewer/?saved=12630

In that case I've set the width and height of the boxes explicitly, is that case still unclear per spec?

(In reply to Philip Jägenstedt [:foolip] from comment #10)

For content: linear-gradient(...) it wasn't easy to find the case that would work in Chrome but not in Firefox, but I think this is one:
https://software.hixie.ch/utilities/js/live-dom-viewer/?saved=12630

Yup, I think that's similar to the final part of testcase 1 here.

In that case I've set the width and height of the boxes explicitly, is that case still unclear per spec?

I suspect your testcase and testcase 1 are well-defined per spec, but I think that's because the spec is a bit simpler than the reality of what browsers implement.

The extra box / extra-level-of-indirection that emilio referenced at the end of comment 5 might be the key issue here -- the spec doesn't mention that extra box, I think, and it probably needs to (which then would creates ambiguity about how gradients should behave, which the spec then needs to resolve).

Right now, the spec says that content: <image> "Makes the element or pseudo-element a replaced element, filled with the specified <image>." (spec link). If browsers literally did that (filling the pseudo-element with the specified image), then the SVG image should fill (not overflow) the 35x35 gray & lime borders in the bottom part of my testcase 2. But in fact, all browsers do show the SVG image overflowing the gray and lime borders there, which is an indication that the replaced element really ends up being a child of the pseudo-element, and so it's not as straightforward as the spec makes it out to be.

emilio, does comment 11 sound accurate to you? If so, I can file a spec issue on getting that extra box retconned into the spec.

(Or do you know if the extra box from comment 5 is already defined somewhere, in a way that harmonizes properly with the "Makes the element or pseudo-element a replaced element, filled with the specified <image>." spec-text?)

Flags: needinfo?(emilio)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: