Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[filter-effects] What should happen if filter and background-attachment fixed; applied to the same element? #238

dirkschulze opened this issue Dec 28, 2017 · 13 comments


Copy link

@dirkschulze dirkschulze commented Dec 28, 2017

Reported by Roland Soos (

I have an example where I use background-attachement: fixed; and filter: blur(15px); on the same element. Currently all browser I tested does the same. Applies blur only to the visible area of the fixed image, which I think is bad as filter should apply to the whole element. You can see the result on this example:

When you scroll down, you should see that a box-shadow like effect follows the visible rectangle of the image. I think that effect should stay on the whole div and when you scroll down, it should be visible at the top and at the bottom of the real image only.

Copy link
Contributor Author

@dirkschulze dirkschulze commented Jan 2, 2018

Filter effects apply to the entire visual rendered element. This is defined by SVGs compositing model.

For scrolling this means that the visual result of the current scrolling effect gets filtered once the general rendering is done. The current result of browsers seems to be consistent generally. Firefox seems to have a re-paint problem. Maybe this is a rendering optimization, performance issue or an actual bug. Either way, after waiting some seconds the visual result of the applied filter looks correct.

Copy link

@ghost ghost commented Jan 2, 2018

But when you scroll and the background-attachment is fixed, then the element still moves out of the viewport. Only the image is fixed to the viewport, so there is the empty area above and below the viewport on that element and I think blur should be applied to that empty area, so the top blur area should move out from the viewport when you scroll down.
Like on the right side of this example:

I think this should be the desired behaviour:
(JavaScript changes the background-position on scroll, so it is a little bit laggy, but you can see the blur moving in and out at the top and at the very bottom of the image)

Copy link
Contributor Author

@dirkschulze dirkschulze commented Jan 2, 2018

@rrolandd Ok, so the actual issue you mean is scrolling beyond the viewport bounds and you expect that the filter result should expand beyond those viewport bounds? This doesn't even happen for a background color on the viewport.

Copy link

@ghost ghost commented Jan 2, 2018

Yes, I think filter result on background-attachement:fixed should render beyond the viewport as it does in every other case.

I'm not sure if you have a Mac for testing porpose. Safari has a viewport like every browser does. But the window frame on top is transparent and you can see the page content. That does not belongs to the viewport, but background-attachment:fixed; images are rendered there too.
On load when scrollTop is 0:
When I scroll down you can see that the frame is see through to the background image:

So I still think that this is how it should work when background-attachement:fixed; applied:

Copy link
Contributor Author

@dirkschulze dirkschulze commented Jan 2, 2018

@rrolandd Ok. So your concern is less about scrolling up the page (where the blur gets clipped and just half of the blur is visible) but rather scrolling down and letting the background continue on the top and therefore have no "white" of the backdrop on the top in the vertical direction?

Copy link

@ghost ghost commented Jan 2, 2018

Yes, I think the white backdrop should go out of the viewport in the top direction when you scroll down on the page.

Copy link

@mstange mstange commented Jan 4, 2018

Firefox seems to have a re-paint problem.

FWIW, this was fixed in bug 1300864..

Copy link

@css-meeting-bot css-meeting-bot commented Jan 17, 2018

The Working Group just discussed end.

The full IRC log of that discussion <dael> Topic: end
<dael> Rossen_: There's a number ofFXTF. I don't know who has time to review what. krit and AmeliaBR are on the phone, I believe. There's many issues, but if there's 1 or 2 on the top of the list I'd like to know which.
<Chris> github:
<dael> github:
<dael> krit: In certain cases it's possible to fix an object. When you look at the 2nd link in first comment there's an example. You can open in any browser except Safari. Element is fixed, has a filter applied. When you scroll down user expects top line is blurred as well. You can watch that in FF or Chrome to see difference.
<dael> krit: On the top row there is always some white b/c something outside the box is taked for blur. User expects once you scroll you don't take white. Safari you can see that or there's an example ^
<dael> krit: If you try to get this link open in any browser you'll see the difference.
<dael> krit: If you open it you can scroll down a bit, elemebt is still fixed, top row doesn't have white. Scroll up and there's white. That's a very specific issue. User expects there's some indication on the fixed element.
<dael> Rossen_: fwiw I see Edge has same behavior. We have some issue with fixed background that I'm hoping we'll fix, but it seems we're handling the same...uh, sorry. We're same as Chrome and FF. This isn't what spec defines?
<dael> krit: It's what the spec defines. But the author expects what you see in safari.
<dael> krit: You can see that from the jsfiddle, it's an emulation of the correct behavior using JS.
<dael> krit: If you scroll down you don't see white on the top.
<dael> krit: I do think that behavior of Edge/Chrome/FF is as spec intended. but for users it's a better indication if the blue scrolled with doc as the background stays fixed.
<dael> krit: You could argue there's a JS work around. And 'd be in favor of staying with current.
<dael> Rossen_: So you propose no change?
<dael> krit: Right.
<Chris> No-one can hear me, but for me the fiddle is working very oddly in firefox
<dael> AmeliaBR: I haven't looked carefully, but if Safari is different it's prob how the handle edge mode of blurs. I'm pretty sure the other browsers aren't matching spec unless spec was changed. It's about avoiding edges of elements getting errorded when you blur the element and that's what wesee. WE're first clipping and then blur errodes.
<dael> krit: Spec states that what you draw on the screen gets filtered after. Therefore what you should see is what you get from FF. THere's nothing beyond doc top if you want to put it that way.
<AmeliaBR> Spec , blur() function is supposed to use edgeMode="duplicate", but last I checked Safari was the only one that does that.
<dael> smfr: I'm not sure spec says what happens outside doc bounds. For me safari makes more sense. OTher browsers are pullin in white from beyond doc bounds which doesn't seem right.
<dael> krit: Does background get clipped to viewport? If it's beyond you're probably right.
<dael> smfr: I don't think we ever spec that. Maybe filter should spec what happens when you can potentioally get pixels from outside the viewport.
<dael> Rossen_: Is this viewport or any scrollport?
<dael> smfr: Anywhere with clipping I guess.
<dael> Rossen_: From that PoV I wouldn't want special casing for viewport.
<dael> Rossen_: It's general for all scroll port.
<dael> smfr: If this was inside overflow hidden you'd expect pixel from the outside content maybe? So maybe experiment with blurred things inside and see what the pixel effects are. That's a more general.
<dael> smfr: THis specific problem is pretty irrelevent I haven't seen a page to do this, but It would be good to spec carefully.
<dael> krit: If an object is clipped with clip path it's clear, but here clipping is implicit by the browser itself.
<dael> smfr: You have to think about order. If there's clipping abd blurring We clip and then blur. If the ancestor clips and blur is descendant that's more similar.
<dael> Rossen_: Right.
<dael> smfr: I don't know if we have a good desc of the ordering these effects occur in. I don't think it's written you clip then filter.
<dbaron> I think there are some open github issues about specifying the ordering...
<dael> AmeliaBR: General is clip after filter. No body has written in any spec how that applies to something like background attachment, but generally clip after filter.
<dael> smfr: Not sure that's what we impl
<AmeliaBR> Correction to my previous post/link: No that's the spec for filter(<image>, blur()) function. Nevermind.
<dael> fantasai: Clip to a whole element, I think you filter to the whole element and then clip. Backgrounds are different, you draw it and then filter then clip it.
<dael> fantasai: Background is clipped to the boundries already because it's only drawn to the element bounderies. You draw background into the area and then we filter the whole thing that results.
<dael> AmeliaBR: Good point.
<dael> fantasai: WE need abackground filter property, but we don't have one.
<dael> AmeliaBR: That's different effects. What fantasai is saying is that the background is acting like a child to the element where it gets clipper earlier in the rendering. Overflow on the element is a clip after filter, but background attachment is at a different place.
<dael> Rossen_: WE're nearing the end of the call. WE have some fairly basic order of operations and based on this discussion we don't have a clear explination of what happens when in the combo of backgrounds, no backgrounds, clip, clip-path etc. I would be curious to see if we can agree on the order and from that we should be able to extrrapolate what this should do in terms of clip and blur
<dael> Rossen_: Would you be interested in putting that inside this issue krit ?
<dael> krit: Yes, I think we should.
<dael> Rossen_: We're at the end of the call. I don't think we can resolve. I suggest going back to the issue and continuing.
<dael> Rossen_: I also want to invite anyone in the CSSWG participating in FXTF to look at all the items in the agenda and participate before next week. We'll continue discussing open items as time permits.
<dael> Rossen_: Thanks for calling and we'll chat next week.
<Rossen_> trackbot, end meeting
Copy link
Contributor Author

@dirkschulze dirkschulze commented Jan 17, 2018

Including @fantasai @AmeliaBR and @smfr for this discussion.

The spec states already that a filter applies to the element and its ascendants. The spec does specifically take reference of the different paint phases of an filtered element where background is one of them.

Spec text:

The compositing model follows the SVG compositing model [SVG11]: first any filter effect is applied, then any clipping, masking and opacity [CSS3COLOR]. These effects all apply after any other CSS effects such as border [CSS3BG].

"any CSS effect" is meant to include all paint phases as it references the border property specifically. It likely should point this out more clear.

With that I think it is clear that the element gets filtered as a whole including all CSS paint phases. However, I am unsure if it does clarify the issue mentioned here. @fantasai Is the background clipped to any boundaries, like scroll area, viewport or anything else?

Copy link
Contributor Author

@dirkschulze dirkschulze commented Jan 17, 2018

After reading (and slowly recollecting) the background spec there are 2 aspects.

  • The background painting area specifies the area that needs to get filled with the background. The area gets determined by the background-clip property (border-box, padding-box, content-box). It does not clipped or affected by scroll areas or viewports. At least I couldn't find anything in the spec that would say otherwise.
  • The fixed background-attached CSS property. From what I understand of the spec, it only defines the "origin" of the background but itself has no affect on the background painting area.

@fantasai Please correct me if I am wrong, but taking all this into account, the behavior of Safari seems to be correct while the behavior of Firefox, Chrome and Edge is incorrect. The painting area might be outside of the viewport when scrolling a document with an attached background, but there is nothing in the spec that implies that it should be cropped.

Therefore, the expectation of @rrolandd seems to be correct and is following current specification texts.

Copy link

@ghost ghost commented Jan 17, 2018

@dirkschulze I have updated my test code with an image which does not contain white area to prevent misunderstandings:

Safari 11.0.2 does the same like other browsers in an iframe. Probably they just have an exception to render outside of the viewport at the top of the window.

Copy link

@fantasai fantasai commented Jan 24, 2018

@dirkschulze I'm not entirely following the details of what's going on here but, yes, the background and border should be painted and then filter applied to the resulting box. If the box itself is scrolled partially out of view then the filter is applied to the whole box including the parts that are out of view. If its contents are scrolled out of view within the element (i.e. the element itself has overflow: scroll), then such overflow is not part of the filter since it is clipped by the element and then the filter is applied to the element as a unit.

The compositing model follows the SVG compositing model [SVG11]: first any filter effect is applied, then any clipping, masking and opacity [CSS3COLOR]. These effects all apply after any other CSS effects such as border [CSS3BG].

Wrt spec edits, I think there is some confusion as to what “clipping” means in the first quoted sentence--we have multiple operations that involve some sort of clipping-like thing: for example, overflow and background-clip have clip-like implications. So I think you should specify more clearly: “clipping via clip or clip-path [[!CSS-MASKING]], masking, and opacity”. And also in the second sentence, include things besides border, e.g. “backgrounds, borders, overflow, transforms, etc.”.

Copy link

@AmeliaBR AmeliaBR commented Jan 24, 2018

For SVG, I had always assumed that overflow: hidden was included in the "clipping" step of the rendering model. But based on tests, neither Edge nor Firefox implement it that way. Chrome treats it that way for SVG layout, but not for CSS box layout. For nested SVG, Safari clips after filtering, same as Chrome. But for inline SVG (aka, an <svg> with CSS box layout), it looks like Safari is clipping overflow twice, once before and once after applying the filter (but I haven't explored the results carefully).

Test case:

The SVG layout behavior could be spec'd separately from CSS box layout (which has the complication ofbackgrounds and overflow: scroll), but given that current behavior is inconsistent, it might be useful to converge on a universal rule.

Either way, some clearer language is required here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
6 participants
You can’t perform that action at this time.