[CSSWG] Minutes Tokyo F2F Fri 2017-04-21 Part I: CSS Images L3, Interpretation of url() [css-images][css-values]

=========================================
   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-
               https://lists.w3.org/Archives/Public/www-style/2016Jan/0181.html)

===== FULL MINUTES BELOW ======

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

Present:
   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
           response.
   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
              document.
   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
             objections?
   <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
            "forever"...

   fantasai: We have references coming into this from other non-W3C
             places.
   Florian: Which ones?
   fantasai: Printers.
   fantasai: They have some idea of HTML & CSS because of their
             printers.
   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"
           value.
   TabAtkins: Unless we want to say that it accepts an angle but only
              0.

   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
             interpolation.
   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
         between?
   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
             undefined.
   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
             implementations.
   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
             fixup?
   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
             cases.
   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
              common.
   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
              (above).
   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
             concerned

   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?
              http://dabblet.com/gist/24224c83758444bf3be8b05fd7069a84
   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
          screen
   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
              mix.
   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
             tests.
   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
           perfect.
   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
              identity.
   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
            space?
   ChrisL: The working color space is independent of
           premultiplication.
   Rossen: proposed resolution: don't do this.
   Rossen: objections?

   RESOLVED: Reject the proposal

Received on Saturday, 27 May 2017 00:57:03 UTC