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

[css-masking] Disabling masks and clipPaths when display is none #245

Open
karip opened this issue Jan 4, 2018 · 8 comments

Comments

Projects
None yet
6 participants
@karip
Copy link

commented Jan 4, 2018

Safari, Firefox, Chrome and Edge allow disabling <mask> and <clipPath> by setting the display property to "none", like this: <mask id="my-mask" display="none">…</mask>

Here’s an example with a mask and a clip path in SVG. They both have display set to "none", which disables them: https://codepen.io/anon/pen/mpBdrx

The paragraph about the display property seems to be about direct rendering, but it doesn’t mention that the display property disables the mask/clipPath:

The opacity, filter and display properties do not apply to the mask element; thus, mask elements are not directly rendered even if the display property is set to a value other than none, and mask elements are available for referencing even when the display property on the mask element or any of its ancestors is set to none.

Could the spec be updated to match the current browser behavior? It should say that if the display property is "none", then the mask or clip path is disabled.

@karip

This comment has been minimized.

Copy link
Author

commented Jan 4, 2018

Interestingly, the results are not as consistent when masks and clip paths are referenced from HTML: https://codepen.io/anon/pen/opGXyx

@dirkschulze

This comment has been minimized.

Copy link
Contributor

commented May 22, 2018

display: none disables resource? Edge Gecko Blink WebKit
<clipPath> on HTML element N/A2 yes yes yes
<mask> on HTML element N/A2 no1 N/A2 N/A2
<clipPath> on SVG element yes yes yes yes
<mask> on SVG element yes yes yes yes
  1. Rendering of element with applied mask gets disabled.
  2. Not supported by the implementation.

Note: "display: none disables resource" means <clipPath> or <mask> gets ignored and do not contribute to the rendering of the clipped/masked element.

SVG 1.1 and CSS Masking state for <clipPath>:

The ‘display’ property does not apply to the ‘clipPath’ element; thus, ‘clipPath’ elements are not directly rendered even if the ‘display’ property is set to a value other than none, and ‘clipPath’ elements are available for referencing even when the ‘display’ property on the ‘clipPath’ element or any of its ancestors is set to none.

and for <mask>:

The ‘opacity’, ‘filter’ and ‘display’ properties do not apply to the ‘mask’ element; thus, ‘mask’ elements are not directly rendered even if the ‘display’ property is set to a value other than none, and ‘mask’ elements are available for referencing even when the ‘display’ property on the ‘mask’ element or any of its ancestors is set to none.

Clearly, none of the implementations follow the spec text where display shouldn't have any affect on <clipPath> or <mask>.

@dirkschulze

This comment has been minimized.

Copy link
Contributor

commented May 22, 2018

@dbaron @longsonr Do you know why there is a difference on <mask> with display: none on HTML element in comparison to SVG elements?

@dirkschulze

This comment has been minimized.

Copy link
Contributor

commented May 22, 2018

I suppose that for HTML, Firefox follows this description (because of display: none):

A mask reference that is an empty image (zero width or zero height), that fails to download, is not a reference to an mask element, is non-existent, or that cannot be displayed (e.g. because it is not in a supported image format) still counts as an image layer of transparent black.

If the <mask> source gets disabled by display: none then this makes sense. However, it is still inconsistent with the behavior on SVG and still different to the spec text.

Edit: Gecko issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1463336

@AmeliaBR

This comment has been minimized.

Copy link

commented Mar 18, 2019

Well, I suppose it could be useful to be able to disable/enable all uses of a mask or clipPath with display — but it would need to be implemented consistently for all use cases!

And it makes the logical model much more difficult: what about display being turned off on a parent element? What about references to clip path and mask in external files (currently only supported consistently in Firefox)?

We'd definitely have to retract the parts of SVG 2 that assign these elements a display: none !important rule in the user agent stylesheet as a way of replacing the prose about never being rendered regardless of display value.

Either way, I do think we should continue to distinguish between mask {display: none} and mask > * { display: none}, where the latter creates a valid mask that is transparent/empty and completely masks everything. (And the same for clipPath.)

@svgeesus

This comment has been minimized.

Copy link
Contributor

commented Mar 25, 2019

Some of this spec wording dates from the time that we defined defs in terms of CSS:

defs {display: none }

to explain why anything inside it is not drawn directly. But things can still be drawn if referenced from outside defs.

@css-meeting-bot

This comment has been minimized.

Copy link
Member

commented Apr 1, 2019

The SVG Working Group just discussed Disabling masks and clipPaths when display is none.

The full IRC log of that discussion <AmeliaBR> Topic: Disabling masks and clipPaths when display is none
<AmeliaBR> GitHub: https://github.com//issues/245
<AmeliaBR> Dirk: Question is what happens when `display: none` on the <mask> or <clipPath> element itself.
<AmeliaBR> ... I uploaded some test results
<AmeliaBR> ... most browers disable the effect (as if you didn't specify a clip-path). But there are discrepancies when the effect is on HTML elements.
<AmeliaBR> ... (for browsers/effects which are supported on HTML element, `display: none` is treated as if the mask was full transparent / clipPath was empty. So the element with the effect disappears.
<AmeliaBR> Dirk: Not sure what to do with that, but for SVG effects on SVG elements, it looks like we have consistency.
<AmeliaBR> Dirk: I'd recommend standardizing that: if clip-path or mask property references an element with `display: none`, treat it the same as if it referenced a non-existant element, so no effect.
<AmeliaBR> Chris: Does this only apply if `display: none` is directly set on the element itself, or does it also imply by inheritance, e.g., from `<defs display="none">`.
<AmeliaBR> ... Because a defs is general defined as the same as display: none.
<krit> https://codepen.io/anon/pen/eomKyj
<AmeliaBR> Amelia: And it also depends on the spec text. Assuming the SVG 1 spec was implemented (display: none has no effect), we rewrote it to define these elements as having a `display: none !important` user agent style so it could be defined with CSS. But that doesn't work if display: none actually has an effect.
<krit> https://codepen.io/anon/pen/qwEKpG
<AmeliaBR> Dirk: After a quick test, it looks like an explicit `display: none` on the defs element does disable the child masks / clipPaths, in Blink and WebKit.
<AmeliaBR> Amelia: Since we have consistency between browsers, there may be content depending on it, we should change the spec to match. But we need to figure out what that is, and how to define it clearly. And whether it applies to other elements, e.g., filter effects.
<AmeliaBR> Dirk: Yes, so we need to do some comparison, e.g., for the defs issue. But I think we should focus on masks / clipPath for now.
<AmeliaBR> Amelia: The same text about display not having an effect is used in many parts of the spec. If we're going to rewrite it, we need to figure out how much need to edit.
<AmeliaBR> Dirk: Can we agree on the `display: none` for the mask and clipPath element?
<AmeliaBR> Amelia: I think we need to do more testing first. Go through all the elements in SVG that have the same rules.
<AmeliaBR> Dirk: But these aren't in the SVG spec anymore, they're in CSS Masking.
<AmeliaBR> Amelia: Are you in a rush to republish?
<AmeliaBR> Dirk: No, but we don't want edits on one spec to wait for the other.
<AmeliaBR> Amelia: But we do want to make sure that the final edits are consistent.
<AmeliaBR> Dirk: OK, so you want to get data for all SVG effects, like gradients and patterns and so on?
<AmeliaBR> Amelia: Yep. Should probably open a dedicated issue on the SVG repo. And filter effects, too.
<AmeliaBR> Dirk: There's already one on Filters (https://github.com//issues/130)
<AmeliaBR> ... it's also on the agenda, but I guess we should also defer until we get full data.
@css-meeting-bot

This comment has been minimized.

Copy link
Member

commented Jun 6, 2019

The CSS Working Group just discussed disabling masks/clip paths when display:none.

The full IRC log of that discussion <TabAtkins> Topic: disabling masks/clip paths when display:none
<astearns> github: https://github.com//issues/245
<TabAtkins> AmeliaBR: I don't expect a resolution here. SVG call discussed it, we decided we needed detailed testing for browser interop
<TabAtkins> AmeliaBR: What browsers are doing doesn't match long-standing SVG text tho
<TabAtkins> AmeliaBR: this is about SVG elements that are never rendered: <*gradient>, <pattern>, <symbol>, etc
<TabAtkins> AmeliaBR: In SVG1, these all had an opaque paragraph that said 'display doesn't apply to these elements, no matter what you say it won't be rendered, and nobody what you say they'll always b eusable"
<TabAtkins> AmeliaBR: For SVG2, I was working on trying to make <use>-element shadow DOM make more sense
<TabAtkins> AmeliaBR: To make <symbol> not work directly, but work if you render it in which case 'display' does apply
<TabAtkins> AmeliaBR: Figured I could replace that prose with a UA stylesheet using !important to mean authors can't change 'display'.
<hober> q+
<TabAtkins> AmeliaBR: So say "display:none; except for <symbol> that is a direct child of a <use> shadow tree"
<TabAtkins> AmeliaBR: But turns out that in browsers, display:none *does* do something
<TabAtkins> AmeliaBR: In most browsers, if you set <mask style=display:none>, it has no effect on elements using it as a mask
<TabAtkins> AmeliaBR: This isn't in specs but happnes i nmultiple browsers.
<astearns> ack dbaron
<Zakim> dbaron, you wanted to comment on ancestors being display:none
<TabAtkins> dbaron: Interesting is whether the element has display:None *and* whether ancestor has it
<TabAtkins> dbaron: Tied to "is the thing that makes these work the presence of their DOM node, or the presence of boxes they create"
<TabAtkins> dbaron: For many browsers, these live in the box tree, and using them links to the box tree, and display:none means no boxes are generated and they fail
<TabAtkins> dbaron: So question is if that's what we want to do
<TabAtkins> dbaron: So in general display:none and ancestor display:none are not distinguishable
<TabAtkins> dbaron: So using a non-none !important value doesn't work, as it doesn't solve the ancestor problem
<astearns> ack hober
<TabAtkins> hober: Do we need to special-case these at all? In HTML <style> defaults to display:none, but you can display:block it to render it.
<TabAtkins> hober: So who cares?
<TabAtkins> dbaron: I think at this point that's not backwards compatible
<TabAtkins> chris: Used to be that you couldn't display <title> no matter what you did. But now you can.
<TabAtkins> AmeliaBR: I don't know how much will break, I didn't know that browsers were doing it anyway.
<TabAtkins> AmeliaBR: I suppose it could be useful sometimes to disable a clip-path by setting one thing on the <clipPath> rather than changing all the uses...
<TabAtkins> AmeliaBR: Practical case it breaks. Lots of inline SVGs using a gradient, so you have an inline SVG somewhere that defines those gradients. You don't want it to draw, so can you tell that SVG display:none?
<TabAtkins> AmeliaBR: Some browsers you can, some you can't, because of what dbaron mentioned earlier.
<TabAtkins> AmeliaBR: So instead you throw a pile of styles at it to make it visually hidden but not display:none
<TabAtkins> emilio: Is part of the reason it depends on the box tree-- we have a special thing for SVG that says "this frame is non-display" that doesn't do anything on its own
<TabAtkins> emilio: What that gets you is that a lot of elements don't generate a box at all when they're invalid markup - not in an SVG parent or whatever.
<TabAtkins> emilio: You need to make all those checks in two places now
<TabAtkins> AmeliaBR: So if anyone wants to help us build up that interop-testing table, that would be very helpful.
<TabAtkins> astearns: So I think you can take that back to the SVGWG with our notion that it's probably not worth special-casing, and maybe impossible.
<dbaron> Is there going to be some attempt to drive towards interop?

@astearns astearns removed the Agenda+ label Jul 2, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.