- From: Dael Jackson <daelcss@gmail.com>
- Date: Mon, 16 Aug 2021 18:10:33 -0400
- To: www-style@w3.org
=========================================
These are the official CSSWG minutes.
Unless you're correcting the minutes,
Please respond by starting a new thread
with an appropriate subject line.
=========================================
Shared Element Transitions
--------------------------
- JakeA shared a presentation with the group about the WICG proposal
to create the ability to do shared element transitions, including
planning to create a declarative CSS approach to do at least a
subset of the transitions.
- Github for the proposal:
https://github.com/WICG/shared-element-transitions
- Recording of the presentation:
https://www.youtube.com/watch?v=UIWZFXwAPxE
- The group was very interested in the proposal and had several
questions
- There is still experimentation around how best to handle
allowing a browser to escape out of a transition that's
taking too long without causing breakage
- Cross-origin shared element transitions will need to be tightly
defined. There needs to be consideration of pixel access and
when one page tries to access an element that's not there.
One possible avenue is to use a timer to allow the pages to
coordinate when transitions occur.
- Any additional feedback or thoughts should be added to the github.
Once a more firm proposal about the necessary CSS elements is in
place it will be taken up by the working group.
===== FULL MINUTES BELOW ======
Agenda: https://github.com/w3c/csswg-drafts/projects/19
Present:
Rachel Andrew
Adam Argyle
Rossen Atanassov
Tab Atkins-Bittner
L David Baron
Christian Biesinger
Oriol Brufau
Daniel Clark
Emilio Cobos Álvarez
Elika Etemad
Robert Flack
Simon Fraser
Megan Gardner
Chris Harrelson
Daniel Holbert
Jonathan Kew
Una Kravets
Chris Lilley
Alison Maher
Tess O'Connor
Morgan Reschenberg
Florian Rivoal
Jen Simmons
Alan Stearns
Miriam Suzanne
Lea Verou
Scribe: TabAtkins
Slides scribe: fantasai
Shared Element Transitions
==========================
github: https://github.com/w3c/csswg-drafts/issues/6464
proposal: https://github.com/WICG/shared-element-transitions
JakeA: [projects slides]
JakeA: I'm helping out with this Shared Element Transitions work,
along with Jeremy and Khushal
JakeA: Current state: when you navigate on the web, the page just
changes
JakeA: but on apps, especially in mobile, you get these lovely
transitions between states
[slide shows various transitions, like sliding in a sidebar, swiping
across the screen horizontally to show different panels, etc.]
JakeA: They look nice in person, and can even be directly useful, to
help communicate transitions between states so there's less
context loss
JakeA: I asked people on twitter about this, especially if they'd
like it in a SPA or MPA (multi-page app)
JakeA: most people were interested in it for a multi-page app!
[slide shows Twitter survey of SPA vs MPA, 31% to 52.9%]
JakeA: I see why - you can already kinda do it in a SPA, but it's
impossible in an MPA
JakeA: Strong feeling that many sites *become* SPAs just to get these
transitions; not sure, but it feels like it.
JakeA: And that's a problem, SPAs have a lot of issues, and they're
often done badly.
JakeA: But even when done by experts, you lose things like HTTP
streaming, have to load a big JS bundle, etc.
JakeA: So thinking about this space
[slide shows timeline:
2015: Chrome proposal and experiment
2015: Chris Lord (Mozilla)'s sketch
2017: Jake's sketch
2018: Tab's sketch
2021: This round!
]
JakeA: 2015 was an early chrome proposal, didn't go very far, and the
people left for other projects
JakeA: 2017, I sketched an API. Each time we learned more things that
might work.
JakeA: 2018, Tab had his own proposal
JakeA: And now we're here today
JakeA: Not the first people to try this out, even back in '97 IE had
something.
JakeA: 24 years ago, you could use <meta> to do page transitions
[1997: IE4 with navigation transitions via meta tag
<meta http-equiv=page-enter
content="RevealTrans(Duration=0.600, Transition=6)]"> ]
JakeA: There were 22 transitions to choose from; several dupes from
different directions, like "wipe left" and "wipe up"
JakeA: also a special 23rd transition that made a random choice
JakeA: Slightly kidding, but I think a predefined set of transitions
can get us pretty far
JakeA: But not all the way, I got feedback from people asking for
custom control
JakeA: If we look at some of the nicest transitions in the android
docs
JakeA: It's animating between states in multiple ways; some things
are shared between the states
[shows Android Contacts list, clicking on name of person shifts the
name up and colors/layout changes to show their profile above/
below ]
JakeA: This person's name in the address list moves to be the header
for their profile
[Jake shows his homepage with 2-line title vs 3-line title]
JakeA: On my blog, when you're on the index page and click thru to an
individual post, the headers are basically the same. Why
couldn't that transition?
JakeA: Every element on the two pages are different, even different
tag names.
JakeA: Some elements change content, some elements (dates) don't
change content but do change position.
JakeA: Header changes layout, it does a fade to the new larger text
JakeA: and header container scales its height
JakeA: then the rest of the page just fades content
JakeA: There was a bunch of moving parts here, but overall, it was
simple because it was done with just textures, no live layout
between the two
JakeA: So didn't need to keep the old page alive
JakeA: there are some concepts we keep coming back to
[slide: Change]
JakeA: First, there's a change
JakeA: But before that, we need a prepare step
[slide: Prepare, Change]
JakeA: where the outgoing page offers up parts of itself to be
involved in the transition
JakeA: Like my blog example, offering the header, the date, the
sidebar
JakeA: Then the change happens, letting the outgoing page be cleared
from memory except for the textures it's offering up
[slide: Prepare, Change, Transition]
JakeA: Then the Transition happens, where the new page animates in
JakeA: Like, if you have a series of chat messages, the old page
might have three messages, the new has four; the three can
just fade in, but the fourth has to do something special; this
is where that can happen
JakeA: Like I said, these are textures; we don't want to do layout on
the old page
JakeA: But we also don't want the new page to get pixel readback from
the old textures
JakeA: New page is trusting what the old page gave it - it says "this
is a heading!" and the new page trusts that it's a heading
JakeA: for cross-origin transitions that's a potential concern
[slide: cross-origin transitions]
JakeA: The old page could offer up bad stuff
JakeA: A bad page could transition into a news page, offering up its
"header" and boom, it's the q-anon logo
JakeA: So cross-origin transitions either need to be heavily
restricted
JakeA: or need a two-way handshake to agree on which textures to share
[slide: single-page app transitions]
JakeA: There's also single-page app transitions
JakeA: Not as many authors are interested
JakeA: because they're actually quite hard to do today
JakeA: You need DOM for both states at once, which means you need to
protect the old stuff from being interacted with, or being
seen by a11y tools
JakeA: Need to control for scroll position, how it can mess up CSS
mid-transition, etc.
JakeA: Twitter says they don't do transitions precisely for these
reasons
JakeA: So we were thinking about this and realized this should work
on the page transitions model just as well
[slide: prepare, change, transition]
JakeA: You're still doing a prepare phase to record bits of the old
state, then you transition into the new state
JakeA: We already have a sketch of the SPA model behind a flag in
Canary
JakeA: Here's an example of the Preact website
[slide: Preact website SPA]
JakeA: Author of the site says it's "a mess", but it has a router for
the overall site transition as many SPAs do
JakeA: But even though I didn't understand much, I could easily poke
in and add the transitions API, and it all just works
JakeA: Back button reverses transitions, it's all just very little
code
[slide: preact website with subsections fading in and out in the
content panel]
JakeA: In spirit, our current design is very similar to the old IE
version, with a list of predefined transitions
JakeA: New bit is this "shared elements" notion, like the heading and
sidebar in the guide.
JakeA: In this example I'm using this to keep them in position and
only change the content by sliding it in
[slide: Interesting Problems]
JakeA: While we need the bare-bones for EWM reasons, I think there's
definitely a high-level version that solves 80% of cases
JakeA: Some problems.
[slide: cross-fading]
JakeA: First is cross-fading. Transitions have a lot.
JakeA: Hard to do in CSS right now
JakeA: Especially between elements with transparency.
JakeA: Can use explicit opacity on the two states
[slide with .thing1 { opacity: 1 } .thing2 { opacity: 0; } ]
JakeA: Here's a slide where the two are identical save for a few
extra words on the second
[slide: cross-fade shows image, which doesn't change, but fades
to semi-transparent halfway in the transition nonetheless ]
JakeA: Midway thru the transition the shared pixels fade a bit,
ideally we could fix this
JakeA: CSS has a cross-fade(), which does the right thing
JakeA: Which isn't always what we want
<chris> This is because the cross-fade needs to be done in
linear-light
<TabAtkins> (That's not the only reason)
<chris> so that 0.5 + 0.5 = 1.0 :)
<TabAtkins> cross-fade() also blends sizes tho
<chris> (interested to know the other reasons)
[slide: background-image: cross-fade(...); ]
[slide: Not quite elements, not quite images]
JakeA: We're not dealing with elements *as such*; images might be
okay since we've just got textures left over
JakeA: but not all an image - Some information like transforms we
might want to carry over so it can animate properly
[slide: timings and deadlines]
JakeA: Another thing to think about is timings and deadlines
JakeA: Right now when you click to a new page, the browser shows the
new page when it wants, when the data comes in
[slide: iWouldLikeToDoAPageTransition(); ]
JakeA: But if the incoming page wants to control the transition, it
should be able to signal for it
JakeA: But how long can we wait?
[slide: iWouldLikeToDoAPageTransition(); await massiveImageLoad;
nowDoThePageTransition(); ]
JakeA: How long do we wait for the "i want to handle this" signal,
and how long do we wait for it to actually do the transition
after it signals?
JakeA: We like progressive rendering
JakeA: Do we want to allow pages to delay until a 5MB image loads?
JakeA: They can do it today, kinda
JakeA: But maybe if they, say, don't do it in 5s we just do a page
swap
[slide: Thoughts? Questions?]
JakeA: So, questions?
<JakeA> https://github.com/WICG/shared-element-transitions - repo
(API design in flux)
<JakeA> https://preact-with-nav-transitions.netlify.app/ - preact
site demo
florian: Intriguing! Overall makes sense at a high level.
florian: Curious how much ends up being declarative vs JS, how they
intertwine, I'm sure y'all are thinking of this
florian: There was also something between IE4 and modern stuff. I
believe Opera experimented around 2010
florian: They were a little like the declarative transitions, but
also a concept of arranging things in space, so you could
say "this page is left of that one" and it would
automatically swipe over to it
florian: tied into gestures as well
florian: Wondering if there has been any thought on these lines,
including tied in with the "shared elements" part
florian: This notion of arranging bits of space, I thought it was
interesting
florian: Doesn't seem obvious that it doesn't fit
JakeA: Hard to talk about binary declarative vs imperative
JakeA: For some people it just means "JS" vs "CSS", but Web
Animations - which is it?
JakeA: We almost certainly will end up with something declarative to
some extent
JakeA: Lot of desire to do this animation out of the control of
either page; the pages just dictate how they want it to go,
but it's actually handled outside
JakeA: I did put a sketch together purely in CSS, and I think I got
to 15+ properties and hadn't thought about the destination url
negotiating yet...
JakeA: I anticipate the destination being done in JS at least
JakeA: And maybe there's a smaller subset that can be done in pure
CSS with simple behaviors
JakeA: Before I had the ability to associate elements with some ID,
and if the destination page uses the same ID they're
automatically tied together
JakeA: In the JS API I presume it'll be similar.
JakeA: There needs to be a way to give more information - like, by
default it maybe just translates, cross-fades, and scales
JakeA: But scaling isn't always what you want, as I showed in some
examples
chris: If you've got two things transitioning opacity...
chris: You need something where .5 + .5 = 1. That needs linear light;
images aren't linear painted, which is why there's lightening.
TabAtkins: linear-light was one problem
<chris> agreed
TabAtkins: Other problem is that halfway through, two 50% things laid
on top of each other means together they are only 75%
opaque
flackr: Gaming has opacity saturation buffers to solve this
khushal: Yeah we found that, there's a blend mode that can do that
khushal: I found a webkit bug asking to expose this to mix-blend-mode
<khushal> https://bugs.webkit.org/show_bug.cgi?id=142416 is a bug
which talked about the blend mode that would work for this.
emilio: So the idea is that the destination page can observe stuff
about the transition, like position of old elements
emilio: That seems like in conflict with the UA being able to control
the transition
JakeA: We hope within the API to catch spots where, like, if an error
is thrown it doesn't deadlock the transition
JakeA: With this model you can definitely delay the intro of your own
page. Having the incoming page control it means you're only
harming your own performance
JakeA: Question of how much we want to prevent people - they can
already delay their own page arbitrarily.
JakeA: Worry about damaging legit use-cases to guard against some
people getting it wrong
emilio: Main thing I'm concerned about is an animation working on a
good computer, but breaking on a crappy phone
JakeA: Right, so think if the transition isn't ready within 3s we
just bail, or something like that
JakeA: Like doing font-rendering intervention
emilio: I took a look at the API, which is promise based; if you bail
on the transition it rejects the promise, right? If the
promise rejects unexpectedly the page might still break.
emilio: This would be much simpler if the UA could decide what to
render without the destination page being involved, but I
understand it breaks some of the fanciness.
JakeA: I see you're looking at the GH page for the API; that's still
in flux
JakeA: We're definitely looking at ways to mitigate these problems
JakeA: Issue on GH right now looking at moving to a JS API similar to
WebLocks
JakeA: In that you provide a callback to run later that returns a
promise. Errors become rejected promises instead of breaking
script, so you somewhat avoid deadlock.
khushal: Design thing I'm thinking about, which page controls the
transition. Reasons for that to be diff between same-origin
vs cross-origin
khushal: Incoming page controlling the transition is good because it
has info from both sides, and can make better decisions
khushal: But for cross-origin cases, we can't let the incoming page
know about the outgoing page, so the outgoing page has to
control the transition completely
khushal: This requires different API shapes, and it's causing some
API divergence
JakeA: This is something I ran into for the CSS-only version
JakeA: If you've got a shared item in the outgoing page which doesn't
have an incoming equivalent, or vice versa, it becomes hard to
deal with
JakeA: It's hard in CSS to talk about an element that isn't there
JakeA: Whereas in a JS callback you can get handed five elements, and
four match in the new page, and you can figure out what to do
with the leftover
astearns: You mentioned pixel access - I assume incoming page has no
pixel access at all
JakeA: Correct
JakeA: Probably model will be outgoing picks up an element for
sharing, and a StructuredClonable of info about it, like "I'm
a heading" or whatever
JakeA: But no pixel access
JakeA: Hope we can one day get to a state where we can read the
pixels on a page
JakeA: We have origin isolation right now, maybe some even stricter
version could some day allow this
astearns: And with outgoing pages opting into data sending, for
cross-origin the incoming page might need to be restricted
from knowing which of its transitions actually matched. No
info about which headings matched, etc, just always run them
JakeA: Two angles there - don't want Page A to find info about Page B
they didn't want to share
JakeA: In some cases the number of chat messages can leak that
JakeA: But there's also Page A and B *wanting* to share info, but for
privacy we don't want to allow them
JakeA: Not sure where the line is right now
JakeA: Might be that cross-origin is just the IE model - a list and
the whole view moves
astearns: You talked about having a high-level declarative variant
with less features
astearns: I hope if we get there, the high-level thing can be hooked
by the low-level, so you can intervene when necessary
<fantasai> +1
JakeA: Yeah, I think CSS shorthands model is something like what we
want to go for
JakeA: Can set up a "sliding" animation, and it can specify a
WebAnimation-like set of keyframes
JakeA: And maybe we just wrap that up in "slide-left" keyword, but
with full control to do your own
<astearns> prefers-reduced-motion would turn all of this off,
presumably
fantasai: One, incremental rendering, if you're on a slow connection
you want the partial page to show up early
fantasai: Dunno how that's considered right now, just want to make
sure it's not forgotten
fantasai: There was also a discussion about shared element
transitions in Burlingame, I think, not sure if there are
notes or if it was informal; think Ojan was involved
fantasai: Big point I remember there was that cross-origin ones
shouldn't leak info
fantasai: Another idea was sharing a timer between the two, so
outgoing and incoming pages could put things on the same
timeline
fantasai: Couldn't necessarily coordinate between elements, but could
at least ensure timing matched up
JakeA: For incremental loading, definitely one of the fundamentals I
want to keep.
JakeA: Definitely a tension between that and page transitions
JakeA: Would be nice to have a way to say "don't transition until X
element is around"
JakeA: Very hard to do right now, tricky with a Mutation Observer
JakeA: Might be a waitForElement() API to let you delay as little as
possible
JakeA: In the blog example I want *some* of the content to be there,
but don't need the whole page necessarily. Probably want a way
to say I just need the top of the page, not the stuff a MB away
JakeA: Nothing concrete there yet, but it's on our minds
JakeA: I didn't know about the transitions discussion
JakeA: I'll try to find notes
JakeA: In chat Alan asked about prefers-reduced-motion
JakeA: Yeah we'd just ignore the transition in that case
JakeA: Re: leaking cross-origin, absolutely a concern, need to lock
down properly
JakeA: Re: timeline sharing, that's similar to my previous 2017 idea
JakeA: That version required both pages to be alive at the same time
JakeA: which is an issue for low-memory devices
JakeA: Thought right now is one side controls the transition; the
other side just offers things to be transitioned
khushal: Interesting to think about whether incoming page *has*
contextual info to control the transition or not
khushal: If you're on a news aggregator, and it wants to have a
transition to links, ok. But if the user enters in the
omnibox, maybe the incoming page gets control over that
instead. Or maybe browser-initiated just doesn't get
transitions.
khushal: Also, re: same vs cross-origin
khushal: In same-origin when incoming can control, we also let it
control when the transition states
khushal: and it gets all the info about the outgoing page, so it can
do smart things
khushal: but in cross-origin, when the incoming page doesn't have any
info but might still have useful timing info, that's a
difficult question
eugene: Riffing on khushal's comments, if you have cross-fade
capabilities, the omnibox can do its own thing controlled by
the UA
eugene: we've also got scroll-to-text capability now
eugene: and ideally when you're referring to a shared element,
hopefully we have a consistent way to refer to those elements
eugene: Another comment, declarative vs imperative. Declarative is
basically marking up a single transition, I think it falls
down when you want multiple things simultaneously
eugene: So it's important to have the models build on each other
eugene: Big call for extensibility, building more on top of this
eugene: Think the right model is to build on the animations
ecosystem, so all the existing animations work, and users get
new abilities as animations get better
JakeA: re: scroll to text, I think you can use a css selector to id
the element
JakeA: that works okay for scroll-to-text because the lifetime is
relatively short
JakeA: And if the highlighting doesn't work, it's not a huge loss
JakeA: Could be worse on transitions
JakeA: Concern I have is you're navigating around a site, and
mid-article the site redeploys and the class names have changed
JakeA: So model we're using right now isn't tags or selectors, it's
literally just a bunch of named element references
JakeA: {"heading": someDOMEl}
JakeA: Might need a way to bail on transitions so if two versions of
a site are totally incompatible they can figure it out
<jbroman> I think scroll-to-text uses a snippets of text rather than
CSS class names to avoid this
eugene: I think if it's a problem for page transitions, it'll be more
of a problem for people who save links from their search bar;
"scroll to image" is just as bad
flackr: I assume that BF nav, we want to use the transition that you
saw when you came in
flackr: Not sure how it would work with the current API
flackr: But should be some way of memorizing the transition so we can
reverse it if we go back
flackr: Is that something we can do?
JakeA: Yes, and the more automatic we can do the better; people don't
often test that
JakeA: Maybe we only do it if the page is in BFCache
JakeA: Gets more complicated if you're reloading the old page as well
JeremyRoman: This is a very big rathole, but interesting
JakeA: I think limiting it to BFCache and only +1/-1 transitions is a
good start
astearns: Assuming you'd like more feedback in the WICG repo?
JakeA: Yes, that's the right place for it
astearns: And we can do CSS issues when you come up with a
declarative CSS version of this
JakeA: Absolutely. Thanks!
<jbroman> +1; thanks CSSWG for your time
<vollick> thanks, all!
astearns: I think it'll be great to bring the web platform back up to
IE4 standards.
<JakeA> https://github.com/WICG/app-history/
<JakeA> For the minutes: https://github.com/WICG/app-history/
provides a "navigate" event which provides a central place to
hear about navigations, kinda like I was able to use on the
preact site (due to its router). This means if you want to
hear about navigations, you don't need to listen for all link
clicks, all form submissions etc etc
<br dur=10min>
Received on Monday, 16 August 2021 22:12:14 UTC