[CSSWG] Minutes Tokyo F2F Fri 2017-04-21 Part I: CSS Images L3, Interpretation of url() [css-images][css-values]
(too old to reply)
2017-05-27 00:56:27 UTC
Raw Message
These are the official CSSWG minutes.
Unless you're correcting the minutes,
Please respond by starting a new thread
with an appropriate subject line.

Update on URL function discussions

[ continued from Wednesday part IV ]
- RESOLVED: For ambiguous cases, UAs SHOULD first see if there's
an appropriate reference, otherwise go back and reload
as an image.

Images 3

- RESOLVED: Deprecate <angle> in image-orientation, make optional,
and add a 'none' value. Note browsers don't need to implement.
- RESOLVED: Do interpolations recursively on each argument for cross-fade(),
but mark it at risk.
- RESOLVED: In the one case where you need layout-time information to
to do fixup, if you don't implement max(), you must do
an abrupt interpolation for gradient stops.
- RESOLVED: Reject this proposal (backporting gradient midpoints
to L3- https://lists.w3.org/Archives/Public/www-style/2014Oct/0504.html)
due to lack of independent implementations
- RESOLVED: Reject the proposal (Special-case 'transparent' as a
color stop and use non-premultiplied RGBA-


Agenda: https://wiki.csswg.org/planning/tokyo-2017#topics

Rachel Andrew, Invited Expert
Rossen Atanassov, Microsoft
Tab Atkins, Google
L. David Baron, Mozilla
Brian Birtles, Mozilla
Bogdan Brinza, Microsoft
Rick Byers, Google
Tantek Çelik, Mozilla
Emil A Eklund, Google
Elika Etemad, Invited Expert
Rob Flack, Google
Simon Fraser, Apple
David Grogan, Google
Jihye Hong, LG Electronics
Dean Jackson, Apple
Toru Kawakubo, Vivliostyle
Ian Kilpatrick, Google
Vladimir Levantovsky, Monotype
Chris Lilley, W3C
Myles Maxfield, Apple
Jack Moffitt, Mozilla
Shinyu Murakami, Vivliostyle
Xidorn Quan, Mozilla
Florian Rivoal, Vivliostyle
Hiroshi Sakakibara, BPS
Simon Sapin, Mozilla
Alan Stearns, Adobe
Shane Stephens, Google
Surma, Google
Lea Verou, Invited Expert
Jet Villegas, Mozilla
Philip Walton, Apple
Johannes Wilm, Vivliostyle

Scribe: myles

Update on URL function discussions
Github issue: https://github.com/w3c/csswg-drafts/issues/383

plinss: url() - do they resolve to images or elements?
plinss: We had 4 options.
<dbaron> https://dbaron.org/css/test/2017/mask-url
plinss: David looked into what Firefox does. But our resolution is
contrary to that. We want to revisit to allow Firefox.
dbaron: Firefox treats mask-image with a URL. If it has a hash, we
will look for a ref in it, whether its local or remote.
dbaron: So, there are some cases where we will try to load it
twice. If there is no hash, we don't attempt to look for a
mask element, and load it as an image. If it's purely a
local ref, we don't attempt to load it as an image - we
will only find a mask URL. But if it has a hash in the
middle, we'll load it both ways.

fantasai: This is an optimization of loading twice in general.
fantasai: A local reference is not going to be an image.
dino: Why not?
dino: It could be an SVG image, or a SVG root, or a canvas.
dbaron: We don't want infinite recursion.
TabAtkins: Pointing to canvases isn't allowed at all anywhere.
dino: Someone might do it.
dino: We could point as an image element in the document and using
it as a mask.
leaverou: That's not allowed.
ChrisL: This is imaginary.
dbaron: The mask property used to point to a mask element but we
extended it to point to image.
dbaron: When we do this, we ignore the other masking properties
like mask-repeat, etc.
ChrisL: This is according to the spec, rights?
dbaron: I think so.
leaverou: So, it's possible to have the Firefox implementation
from the spec?
leaverou: We all agree that this is the most reasonable choice.

Rossen: Can someone summarize what is going on?
<plinss> https://log.csswg.org/irc.w3.org/css/2017-04-19/#e796988
<leaverou> 1. Treat ambiguous cases as url reference into an SVG
document, not treat as image and apply :target
<leaverou> 2. Treat ambiguous cases as url, if it has a fragID
treat as a reference, otherwise treat as an image
<leaverou> 3. Treat ambiguous cases, load it twice -- first see if
there's an appropriate reference, otherwise go back
and reload as an image
<leaverou> 4. Do something different per property

dino: What does "ambiguous" mean?
plinss: If the property can handle both an element and an image,
and the URL could be either.
plinss: Can we resolve to make this decision on whether it's a
local or external URL?
myles: Firefox does 3, right?
leaverou: Basically. With some extra optimizations.
plinss: Architecture says that you can only interpret what a
fragment means until you get a content-type from the
dbaron: The case where Firefox doesn't do the right thing is when
there is a base URL and a url(#foo).
dbaron: This is probably not the only case where this occurs
dbaron: like <a href="#foo"> scrolls within the current document.
TabAtkins: CSS always treats a #url as a reference into the local
plinss: That is a separate issue and an architectural violation.
plinss: At the end of the day, I'm okay with browsers not handling
everything exactly b/c of optimizations. What I'm not okay
with is the spec stating you must violate architectural
principles and Gecko must stop doing what it's doing.

Rossen: Other thoughts?
Rossen: Proposed resolution: a mixture of #2 and #3
fantasai: By choosing to follow Mozilla behavior, you are deciding
that a local reference will always be an element
reference and not an image reference. Which is fine, but
we should be explicit.
fantasai: We always have our image() and element() functions which
can make the distinction.
ChrisL: So you're not losing anything.
TabAtkins: We know the content type of the current resource, so we
can interpret the hash correctly.
TabAtkins: I need confirmation from our loading people that this
is implementable.
TabAtkins: We will try.
plinss: I'm okay with "should" or "must (but we know you won't)"
Rossen: "should" please.

Rossen: Proposed resolution: Option #3 with "should"
TabAtkins: (summarizes proposed resolution)

RESOLVED: For ambiguous cases, UAs SHOULD first see if there's an
appropriate reference, otherwise go back and reload as
an image.

Split sessions

Florian: We found a number of places where we wanted to tweak the
page floats spec
Florian: But then we spoke more, and alternatively to tweaks, we
could do deeper changes, and that might be better.
Florian: So we need a long deep session about page floats.
Florian: Otherwise, we should just take it off the agenda.
Rossen: What about rhythm?
Rossen: We need to break out.

Images 3 Issues

<leaverou> https://drafts.csswg.org/issues?spec=css-images&doc=cr-2012

Deprecating image orientation

leaverou: This isn't about deprecating it. Someone said that
angles in image-orientation are pointless. You'll never
want to the same adjustment to all your images. So this
is to fix the orientation of images which were taken eh
wrong way. Proposal: drop all values except from-image
leaverou: and none
leaverou: which is now called 0deg.
leaverou: The point is that the angles are pointless.

leaverou: We agree but we need a resolution since it's in CR. Any
<tantek> that seems reasonable
fantasai: I'm okay with deprecating or obsoleting, but we need to
keep them in the spec.
<dbaron> I've been in favor of just from-image | none since

fantasai: We have references coming into this from other non-W3C
Florian: Which ones?
fantasai: Printers.
fantasai: They have some idea of HTML & CSS because of their
ChrisL: This is the XHTML print stuff.
<ChrisL> https://www.w3.org/TR/xhtml-print/
fantasai: These printers rely on this stuff.
leaverou: Angles?
fantasai: Yes.
fantasai: I don't know the details. I worked on testing this and
it's used.
<tantek> wait was there a test case for angles?
<tantek> ok with "obsolete"
fantasai: From our perspective, browsers don't need to implement
it. But it can't be removed. We can just say it's
obsolete and not to implement it.
TabAtkins: Sounds good.

leaverou: resolution?????
dbaron: There needs to be a second piece which is to add "none"
TabAtkins: Unless we want to say that it accepts an angle but only

RESOLVED: Deprecate <angle> in image-orientation, make optional,
and add a 'none' value. Note that browsers don't need to implement.

Interpolating nested cross-fade()s

leaverou: Spec says if you do it that only differ by their
percentage, then you just interpolate their percentage.
leaverou: The other cross-fade, the two arguments are not
identical, so this would trigger the default generic
TabAtkins: Theoretically you could detect this condition and fix
it in the browser.
leaverou: But there is arbitrary complexity here.
TabAtkins: We could 1) resolve the current text is right, or 2) a
more generic version where we interpolate the two
argument images as well as the percentages.

dino: This is 1 level or 2 levels but not n levels.
TabAtkins: We interpolate the percentages, and the two first
arguments and the second arguments, and it cascades
down forever.
dino: In the example, if instead of the first case said 1.png and
the second case said 3.png
TabAtkins: Then you would do a generic interpolation.
dino: I don't mind what it is. Definitely 1 level is easier.
TabAtkins: Yes.
TabAtkins: The "interpolate further down" case is more interesting
but is more complicated.
TabAtkins: I can go either way.

dino: How often will authors write nested cross fades.
leaverou: It could come from variables.
leaverou: It's easy to get this with variables.
dino: Yes. This means that the variable itself might be animating,
so you might be animating between two animations.

fantasai: We have other image functions in mind for the future, so
introspection in general will be more useful for these
future things.
fantasai: We have a variety of different ideas for extending this
that it would be useful for.
leaverou: Introspection definitely yields the results the author
wants, but it may be too hard to implement.
fantasai: It depends on your internal representation. If it's
simple, then matching it is easy.

dbaron: You could define the interpolation rules recursively.
TabAtkins: That's the second option.
TabAtkins: We interpolate the percentage, the first arg and the
second arg separately.
leaverou: If you have a filter function and... You interpolate
between a.png and a blur filter on a.png, you can
interpolate between those.
TabAtkins: You could recursively interpolate between the two
linear gradients in the first argument.

TabAtkins: We need to decide which option. All in, or in 1.
dino: "all in" may require checking of many image types.
dino: The arguments may be interpolatable, other than a cross-fade.
TabAtkins & leaverou: yes.
dino: Do we already have a list of images you can interpolate
TabAtkins & leaverou yes.
dino: Implementation-wise, one level is easier, but meh.
leaverou: Is there any implementations which have done it the
other way so we can test it?
dino: We have a lot of bugs in cross-fade interpolation.
dino: Just random bugs.

fantasai: We should do recursive, and if there are no
implementations, we just mark it as undefined in level 4.
fantasai: I mean, if we end up without implementations, then we
push it out to level 4 and in level 3 say that it's
astearns: So we mark it at-risk immediately?
fantasai: Yes.
Florian: Make it clear that it's "at risk of being undefined" not
"at risk of being removed" (and therefore defined to do
the opposite).
leaverou: If implementations care about it working by a cross fade
and not other rules, then authors will depend on it.
fantasai: That's why we want recursion now.

dbaron: How do they actually differ?
TabAtkins: In the example above, 1st argument stays as it is.
Let's say the second argument is a linear gradient from
black to white, and the next one is a gradient from
black to white 50%, then it makes a difference.
dbaron: Okay.
dino: The generic case means adding a cross-fade.
dbaron: This example is confusing
dbaron: and uninteresting.

leaverou: Let's start with recursive and change it if there are no
Rossen: ok
Rossen: Any objections?
leaverou: It will be at risk.
Rossen: Yes.
leaverou: Cross fade is the only piece which isn't at risk.
Dino & tabatkins: Chrome and WebKit implement image interpolation
with cross fade.
<dbaron> (pre-fork, so one implementation)
Rossen: No objections.

RESOLVED: Do interpolations recursively on each argument, but mark
it at risk.

Interpolation in gradients and color stops

leaverou: We have special rules for interpolation in gradients.
leaverou: <enumerates the special rules>
leaverou: Do these rules apply to the color stops before or after
leaverou: You could have a gradient today that is white to black
and a value of 0 gets fixed up to 20%-
leaverou: color stops with no position get positioned between the
adjacent ones.
leaverou: Color stops become equal to the previous one in some
leaverou: Layout needs to happen because you need to compute some
lengths to do the fixup.
leaverou: So it's optimal to do interpolation to do on the fixed
up positions, but it may be impossible because of layout.
TabAtkins: <describes a case where this happens>

TabAtkins: If it's pre-fixup, then during the transition, the
animation is not smooth. Post-fixup gives a more
correct solution.
TabAtkins: When you're making stripes, it's common to just put 0
as the position, because it forces it to be at the
previous color stop's ending point. So fixing up is
TabAtkins: If we stick with pre-fixup, we break this content.
fantasai: I'm not convinced that post-fixup is better.
TabAtkins: But I just talked about the the 0 common technique
leaverou: On the past, we needed layout. Today, we can use min()
or max()
fantasai: min() doesn't exist today as far as css-images-3 is

dbaron: Doses "fixup" only mean positions of color stops, or
elimination of redundant color stops.
TabAtkins: Elimination doesn't happen. This is well-defined.
dbaron: That makes it easier.
leaverou: Many people use redundant color stops to force gradient
interpolation instead of generic image interpolation.
fantasai: They need it as a placeholder.
TabAtkins: dbaron, why do you think it's easier?
dbaron: There is extra complexity if you want to ignore the color
stops. You need to know exactly which ones to ignore. But
if the algo says to never ignore, then it's okay.
TabAtkins: Yep.
TabAtkins: Both options are difficult.

TabAtkins: We can represent the intermediate steps w/o layout by
using max().
fantasai: We don't have that.
leaverou: We will.
<dino> leaverou++ for imminently not momentarily
fantasai: There are 0 implementations, and not even a spec yet.
fantasai: We can't rely on that here,
fantasai: You can say "don't do any gradient color implementations
until you implement min()" but that's a bad dependency.
TabAtkins: Or it may just be wrong.
TabAtkins: You could just use calc() for the stops instead.
fantasai: The goal is to get the spec to REC, min() won't be able
to achieve this. So it's a bad dependency.
TabAtkins: We should never do the bad thing because of process.
fantasai: The existing behavior in the meantime is valuable.
fantasai: Is it going to be okay to change the behavior of this
property when browsers finally implement max()?
TabAtkins: Nope.
TabAtkins: But it shouldn't delay it.
ChrisL: It's not "process", it's that there are no implementations.
TabAtkins: It doesn't matter when it gets implemented.
Florian: We can always change it, but it depends on the compat at
that point.

leaverou: If we say that interpolation happens pre-fixup, we will
break things.
fantasai: But we don't have a choice because there is no
implementation of max()
leaverou: We should wait longer and get it right.
fantasai: What will we do in the meantime?
leaverou: We already waited 6 years.
fantasai: What will the implementation do in the meantime until it
implements max()
TabAtkins: It will be buggy.
leaverou: This isn't the first time we've done this.

fantasai: I want it to be defined what you do if you don't
implement max().
TabAtkins: I don't want to have to carefully control when we make
a change to the spec based on when people implement
min() and max().
fantasai: We need a definition for both cases.
TabAtkins: Sounds good.
Florian: Isn't it better that the intermediate behavior is buggy.
TabAtkins: It doesn't matter.

<leaverou> Can someone test this in Edge 15?
leaverou: Why doesn't my example work in Edge????
Rossen: I dunno.
<fremy> leaverou: quick guess is that it uses explicit in one and
implicit in other
<fremy> @leaverou: that one works: https://wptest.center/#/i4sli8

Rossen: fantasai: What resolution do you want?
fantasai: I dunno. I'm not convinced of what we're trying to do.
leaverou: We could make max() required to implement this.
fantasai: I'm not convinced that the theoretical best (even if
max() exists) is this behavior.
fantasai: If we had color stops relative to the position of the
previous color stop, we could do it.
ChrisL: This would actually work with what authors want. When
authors say "0" they actually are just using a
placeholder. We could give them a keyword.
leaverou: Why would an author use a keyword?
leaverou: We could do the interpolation on the declared list of
color stops, but there is more existing content which it
wouldn't work with.

fantasai: Depending on what your goals are as an author, you might
have different goals as an author,
fantasai: both behaviors are reasonable.
surma: Most use cases will want to animate from wherever it is on
surma: rather than where it ought to be.
leaverou: People can use whatever units they want in their color
stops, and not worry about ordering. But now people will
have to think about this stuff just to get the proper
interpolation (and use min() or max()).
leaverou: Content may do what UAs should be doing, themselves
leaverou: like a polyfill.
leaverou: Can we say that UAs that implement max() should do it
according to these rules, but other ones should be
abrupt? (So authors can fix it in the future).

TabAtkins: We can cut it down to things which would require layout
(which is just percentages).
fantasai: Percentages are common.
TabAtkins: If you're all percentages, you're fine. If you're none
percentages, you're fine. The only bad case is if you
leaverou: If you fall back to generic interpolation, which is
cross fade, people will rely on it, because cross-fade
looks nice. If its abrupt, people won't rely on it.
fantasai: They could.
leaverou: That's what happens now, so if you're right we shouldn't
do this at all.
fantasai: Then your cross fade vs abrupt transition could be
random, then they for real can't rely on it.

Rossen: Can we resolve?
TabAtkins: Proposed resolution: In the one case where you need
layout-time information to do fixup, if you don't
implement max(), you must do an abrupt interpolation.
leaverou: That works.
Rossen: Any objections?

RESOLVED: In the one case where you need layout-time information
to do fixup, if you don't implement max(), you must do
an abrupt interpolation.

Backporting gradient midpoints to L3 because we have 3 implementations

leaverou: Rik implemented all the implementations so they are not
independent so it doesn't qualify.
Florian: Independent implementations require independent authors.
ChrisL: We have 3 impl, so edge will be pressured to do it. So
edge will do it independently.
Rossen: This will just hold up the level 3 spec for longer, to
wait for another impl.
fantasai: We don't know how to test gradients so we don't have
Florian: We have some but not many.
Florian: Opera has tests for gradients.
Florian: They work by using a software implementation in canvas.
ChrisL: Making a reftest for this is hard, because has to be pixel
ChrisL: Can do a visual test, where a person says "yeah, that
looks about the same".
Rossen: Back on topic please.
TabAtkins: We should reject b/c not independent.

RESOLVED: Reject this proposal

Premultiplication in gradients

fantasai: Issue was saying "transparent" keyword should compute to
2 color stops: one of the previous hue of the previous
color, and the hue of the next color.
fantasai: Currently transparent is just transparent black.
leaverou: Instead of using premultiplied, we should special-case
"transparent" since every case which needs this is due
to transitions to or from transparent.
leaverou: When you don't use transparent, you don't want to lose
the color information in your color.
leaverou: There are gradients which are impossible to do in a
premultipled RGBA space.
TabAtkins: You are wrong. You can use dummy stops.
TabAtkins: We do it in non-premultiplied, but we use dummy stops
to emulate premultiplied
TabAtkins: because of Skia.

TabAtkins: Problems! A) Transparent is equivalent to RGBA(0, 0, 0, 0)
which disappears by computed value time. This
changes that to make it special, which retains its
leaverou: Or we special case RGBA(0, 0, 0, 0).
TabAtkins: That is worse because of rounding. Rounding could
trigger this erroneously.
ChrisL: This is an author convenience because people want to go to
and from transparent. We lumped together color and opacity
together, which is unwise, and makes this hard.
astearns: Does special casing transparent as 2 stops makes
transitions break because the number of stops changes?
ChrisL: So you would have to fix this up behind the scenes like
you do now.
TabAtkins: Our internal data model retains the knowledge of the
input number of stops.
ChrisL: So yes, the implementation fakes the extra stops.
TabAtkins: No, because you either have to keep transparent around
long enough as independent value, to fake at paint time.
TabAtkins: This requires a change to transparent across all colors
which isn't good.
leaverou: This also applies to transitions and gradients.
TabAtkins: And the color: property
TabAtkins: because of serialization
TabAtkins: author code may depend on this (b/c they assume 4
tuples) would break.

Florian: Will this be fixed later when we switch the working color
ChrisL: The working color space is independent of
Rossen: proposed resolution: don't do this.
Rossen: objections?

RESOLVED: Reject the proposal