-
Notifications
You must be signed in to change notification settings - Fork 49
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] make the behavior of an invalid mask be consistent with clip-path and filter #130
Comments
A hearty +1 to treating an invalid mask as no mask at all. |
Error handling on filterTest case for filter: https://codepen.io/krit/pen/pVYabE?editors=1000
Error handling on clippingTest case for clipping: https://codepen.io/krit/pen/NMJyXr?editors=1000
Error handling on maskingTest case for masking: https://codepen.io/krit/pen/derdaE?editors=1000
Summary
Interesting for #17: Blink and WebKit do not take |
Any decision on this? See this example: |
The Working Group just discussed The full IRC log of that discussion<AmeliaBR> Topic: Issue Make the behavior of an invalid mask be consistent with clip-path and filter<AmeliaBR> GitHub: https://github.com//issues/130 <AmeliaBR> Eric: I don't know much about it, but it's been put on the CSS WG agenda, and is also marked as needing SVG WG input. <AmeliaBR> ... don't need to discuss now, but people should take a look. <AmeliaBR> Dirk: Will need to review, but as I recall there were a few related issues. <AmeliaBR> Amelia: Based on the testing you reported in May, behavior was inconsistent between browsers. Which I think means we should spec a sensible behavior. <AmeliaBR> Dirk: It really depends on the specific cases, HTML elements having different behavior than SVG elements. <AmeliaBR> Amelia: Ah, so the inconsistencies are not between browsers, but between use cases. That is less useful. <AmeliaBR> Dirk: Yes, worried about breaking content if we change things. <AmeliaBR> ... If I look again, maybe we can discuss next week. <AmeliaBR> Eric: Sure. |
The SVG Working Group just discussed
The full IRC log of that discussion<heycam> Topic: make the behavior of an invalid mask be consistent with clip-path and filter<heycam> github: https://github.com//issues/130 <heycam> krit: the issue is what happens if a filter, mask, clip-path is invalid <heycam> ... for filters, what happens if there's no content <heycam> krit: so if you have a rect, apply a clip-path, but the referenced <clipPath> has no children <heycam> mstange: looking at the table in the issue, does one of the rows describe if you have a filter in an external SVG that's still loading? <heycam> AmeliaBR: no, but good question <heycam> mstange: I ran into this before CSS filters existed. I wanted to darken on mousedown. I only set the filter on :active, which is when the external resource started loading <heycam> ... so it would become blank <heycam> AmeliaBR: I was thinking of the basic case of when you're first loading. but in the interactive case, sometihng disappearing would be bad <heycam> myles: we have a similar situation with async image decoding <heycam> ... where if oyu're on the first load of a webpage, we will not show the image until it's fully decoded <heycam> ... but if you're in the middle of a page, and you change the src, you won't show nothing until the new image is decoded. you show the old image until the new one is ready <heycam> AmeliaBR: first we need to make the basic case of what do you do when you know the reference is invalid, either it's a bad URL, or there's an error in the content you're referencing <heycam> ... we have different rules for different elements, and different implementations <heycam> ... my general preference is to try to harmonize as much as possible <heycam> krit: I can go through the clip path examples <heycam> krit: [reads from the table] <heycam> myles: the no content case, I remember implementing this <heycam> ... there was an SVG 1.1 test suite test for this <heycam> myles: our fonts implementation doesn't match Gecko, it matches others. [it skips invalid child content of the clipPath] <heycam> krit: Firefox is the odd one out here mostly, would they be willing to change? <heycam> mstange: there's cases are all handled explicitly, should be simple to change <heycam> ... not sure on jwatt's or longsonr's opinion <heycam> RESOLVED: For clipping and masking, we follow the behavior of Edge, WebKit, and Blink in the https://github.com//issues/130#issuecomment-390981529 table <heycam> AmeliaBR: what's different between filters and clip/mask, is missing references <heycam> ... if you have a url() reference to a missing element, clip/mask just applies no clip/mask <heycam> ... for filter, the filtered element disappears <heycam> ... which is usually not helpful <heycam> krit: not sure if I did change this, but I would like to align with mask and clip <heycam> ... the Filters spec has a special rule, if the url() reference is to a different file, then you treat it as a no-op <heycam> krit: [reads spec text] <heycam> ... so we already have changed the spec to not make the filtered element disappear <heycam> myles: putting a filter on an element causing a stacking context, so we can't treat it as 'filter:none' <heycam> AmeliaBR: as a no-op filter item <heycam> krit: so a stacking context still gets created <heycam> AmeliaBR: if your filter is invalid, that would be something to clarify in the spec <heycam> krit: didn't find anything about external references. think it should behave in the same way <heycam> mstange: I would be in agreement. I suppose we don't know how much content it would break <heycam> ... but from an authoring perspective, I much prefer this behavior <heycam> myles: if an author was trying to get a filter, and make a typo, their element would disappear <heycam> ... it's hard to believe that there's content out there that relies on it disappearing <heycam> AmeliaBR: when the url() is to another filter, and you get a network error <heycam> ... the other issue is just debugging SVG filters is a pain, if your content keeps disappearing <heycam> ... and the inconsistency with clipping/masking <heycam> mstange: these are arguments for it being a pass through, not for there being no broken content <heycam> myles: inside a filter you create a graph of nodes. do they also need this analysis performed on them? <heycam> mstange: if you have in="" that refers to something non-existent <heycam> AmeliaBR: each primitive has its own rules <heycam> krit: if the filter reference is invalid, the filter is not applied, but the stacking context is still created <heycam> heycam: you might have a filter property with multiple filters in it <heycam> AmeliaBR: this would make the entire filter chain a no-op <heycam> RESOLVED: If a referenced filter is missing or invalid, the side effects like stacking context are still preserved. <AmeliaBR> Resolution was at https://github.com/w3c/svgwg/issues/631#issuecomment-505164786 <AmeliaBR> and at https://github.com/w3c/svgwg/issues/537#issuecomment-452092266 |
Dirk asked for an async resolution on the public mailing list: https://lists.w3.org/Archives/Public/www-style/2019Sep/0013.html I agree that we can use async resolution for this. Unless I hear here or on the mailing list that someone wants to go over this issue on a call, or objects to the resolution, the rules above will be resolved by the CSS WG on October 14th. |
Chiming in with one remark about mask-border vs mask discrepancy seen in current spec, one amusing remark about real-world outcome of it, and simple testcase/exhibit of this phenomenon. Mask vs Border mask discrepancy
|
A mask reference that is an empty image (zero width or zero height), that fails to download, is not a reference to an <a element>mask</a> 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. |
mask-border-source
: An image that […] fails to download […] still counts as an mask border image but does not mask the element.
fxtf-drafts/css-masking-1/Overview.bs
Line 975 in 43e4e69
An image that is an empty image (zero width or zero height), that fails to download, is non-existent, or that cannot be displayed (e.g. because it is not in a supported image format) is ignored. It still counts as an <a>mask border image</a> but does not mask the element. |
Emphasis mine {*1}. That "but does not mask the element" postscript for the border would definitely make sense for the regular mask as well.
Real world example for general amusement
Google Fonts include "Font Effects" beta feature (apparently from it's beginning) that adds some class along font declaration with some extra styling and some of them use masks (when their browser sniffing decides there is a chance UA that made the request could support them).
Currently they are serving CSS from fonts.googleapis.com
, font files from fonts.gstatic.com
and mask images from themes.googleusercontent.com
. For example https://fonts.googleapis.com/css?family=Rancho&effect=brick-sign
currently responds to Chromium-based browsers with:
/* latin */
@font-face {
font-family: 'Rancho';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/rancho/v17/46kulbzmXjLaqZRVam_h.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
.font-effect-brick-sign {
-webkit-mask-image: url(//themes.googleusercontent.com/static/patterns/brick-sign.png);
color: #600;
}
Thing is, the last domain serving mask (raster) images currently does not sent permissive CORS headers, preventing them to load in (any) cross-domain context, so the result is present even at their own API docs (https://developers.google.com/fonts/docs/getting_started#enabling_font_effects_beta):
This is how it looks when it works, thanks Internet Archive WayBack Machine snapshot of that page from the year 2019 that contains all mirrored resources and servers them from single origin:
Simple sample test
data:text/html;charset=utf-8,<!doctype html><html lang="en"><title>
mask-image failing and not-failing image test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>b { font: 3rem Impact; text-transform: uppercase}</style>
<p>Hello, <b style="-webkit-mask-image: url()">failing</b> <code>mask-image</code>.
<p>Hello, <b style="-webkit-mask-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns=%2527http://www.w3.org/2000/svg%2527 viewBox=%25273,-15,16,19%2527><text>🦄</text></svg>');">not-failing</b> <code>mask-image</code>.
in accordance with current spec draft produces:
{*1} Sorry for not using mark
element but as it seems GitHub does not support that.
Since bug 1765202 has landed, Firefox should behave more like Chrome/Safari. |
But does it really make sense for the spec to order that
must render:
not:
just like does with case of bogus (I thought that this was the main issue here(?).) |
I'm also surprised that the effect of a css Maybe we need mask-image: safe url(ERR); |
From @CJKu on February 2, 2017 3:14
According to css-masking spec,[1]:
Transparent black means the masked object disappeared. The way we handle invalid mask is apparently not the same with clip-path and filter. Both clip-path[2] and filter[3] keep the target element visible. I wonder why only masking has different behavior and think it would be better to keep the consistent.
[1] css-masking positioned-mask
https://drafts.fxtf.org/css-masking-1/#the-mask-image
[2] css-masking clip-path
https://drafts.fxtf.org/css-masking-1/#the-clip-path
[3] css filter
https://drafts.fxtf.org/filters/#FilterProperty
Copied from original issue: w3c/csswg-drafts#997
The text was updated successfully, but these errors were encountered: