#265: The Shared Element Transitions API and Origin Trials


[Robin]: This week I’ve been thinking about page transitions on the web and this post from Chris earlier this year:

We can technically build page transitions now, even without single-page-app architecture, but what I want are purpose-built APIs that help us do it cleanly (understandable functions) and with both performance (working as quickly as clicking links normally does) and accessibility (like focus handling) in mind.

If you’re building a single-page app anyway, you get the freedom to animate between views because the page never reloads. The danger here is that you might pick a single-page app just for this ability, which is what I mean by having to buy into a site architecture just to achieve this. That feels like an unfortunate trade-off, as single-page apps bring a ton of overhead, like tooling and accessibility concerns, that you wouldn’t have otherwise needed.

Why should we animate pages like this? Isn’t that just a nifty trick and that’s it? Well, it is more complicated than that in this blogger’s opinion, because I think full-page animations are really useful to indicate where you are in the UI.

Here’s an example I think of a lot: when you select something to watch in the HBO Max app for iOS, the whole UI animates to the right and deep down in my bones this feels wrong. Because now all of a sudden that menu (in my mental model of this app) is now off to the right. But it should be off to the left of my screen because when I click the back button I want to swipe this whole UI back to where I just was, sort of like a carousel.

(This rant should’ve been saved for my therapist, huh?)

My point here is that page transitions aren’t only cool kickflips that we can pull off as developers to impress our friends, but they also give users spatial cues about where they currently are in the UI. Bad animations make us disoriented and feel a bit lost, whereas good page animations make you feel confident and focused.

Doing this sort of thing on the web is pretty tricky though but there’s a new proposal called the Shared Element Transitions API which gives us “a high-level way to transition between page states.”

Jake Archibald explains:

When you navigate around apps on your phone, there’s usually some sort of transition, from a simple fade or slide from one screen to another, to more complex transitions that move different elements independently

Although, on the web, we don’t tend to get those kinds of effects. Creating a transition from one page to another after clicking a link is, well, impossible. But, it isn’t exactly easy within a single-page app either.

This new API is designed to make all those transitions much easier for single page apps. In the example below that Jake shares, the API is told which elements are shared across pages—in this case, that’s the header that sticks in place:

The really neat thing about all this, to me at least, isn’t this new fangled API but instead the way that the Chrome team is rolling this out. Because right now you can use this feature today in Chrome via an origin trial.

First, let me explain the problem. Today it’s kinda hard for browser manufacturers to experiment with new features and get feedback from the community but it’s also difficult for them to do that without them shipping broken stuff that they then need to roll back. Origin trials are the Chrome’s team solution to this problem.

The other problem is adoption: lots of us developers won’t even test stuff if it doesn’t have good browser support and we’re not going to build sites that require feature flags enabled in a particular browser. Here’s a great post from the Chrome team that explains all this:

The resulting situation is one in which features shipping on the web take a long time to design, and are then frozen into standards well before they have been significantly road-tested by real web developers.

And so with origin trials

Once your origin has opted into a trial of an experimental feature you can then build demos and prototypes that your friends and beta testing users can try for the duration of the trial without them needing to flip special flags in Chrome.

This sounds like a great idea to me, but how do you use it?

Let’s say you want to experiment with this new transition API, well first you need to register for the trial and it’ll give you a code. You can then add that string to a <meta> tag in the <head> of your website.

And then… that’s it. Developers are told right up front that this origin trial will expire at a certain date, in this case on October 12, 2021. So the incentive here is to play with these features, but not to build your whole application around them because after a certain date they just won’t work anymore. But during this time, folks who use Chrome will have these features enabled for them.

From my perspective, this all seems like a great idea, except I suppose that these features won’t be tested in Safari or Firefox or any other browser for that matter. I guess I do have a tiny concern then that it feels a tiny bit like we’re building a web app for Google.

I look forward to all this drama unfolding next week!

(Editor’s note: he is absolutely not.)


Stephanie Eckles wrote a great piece about some practical uses of CSS math functions like calc, clamp, min, and max. Perhaps my favorite takeaway from this piece though was how Stephanie defines container classes for setting a max-width on a block of text.

Usually, I’d write something like this:

.container {
  max-width: 700px;
  padding: 0 20px;

But Stephanie is so very much more punk rock than me, where she recommends the following:

.container {
  width: min(80ch, 100vw - 2rem);

On larger viewports, the element can grow to a max of 80ch, and once the viewport shrinks below that width, it will be allowed to grow to 100vw – 2rem. This definition effectively produces 1rem of “padding” on either side of the element.

ch units for setting the max-width! I like that an awful lot. Stephanie continues:

The ch unit is equal to the width of the 0 character given all current font properties at the time it is applied. This makes it an excellent choice for approximating line length for a better reading experience, for example.

Dang, this whole blog post is so so good. But eternal shame on me for not having signed up to Stephanie’s newsletter about CSS sooner though.


CSS accent-color is real neat. I heard about it a while ago, although I’ve never used it and yet this post from Adam Argyle and Joey Arhar has some great demos and a fantastic explanation that makes me want to explore it so very badly. They write:

CSS accent-color from the CSS UI specification is here to tint elements with one line of CSS, saving you from customization efforts by providing a way to bring your brand into elements.

Neat! So you could write something like this:

form {
  accent-color: deeppink;

And this would impact form controls like this:

Neat huh? As Adam and Joey mention in that post, this gives us an easy way to change all these accent colors when folks toggle on dark mode, too:

@media (prefers-color-scheme: dark) {
  form {
    accent-color: hsl(328 100% 65%);

This! This this this! I find this part very exciting because previously you’d have to style all these elements independently and keeping all that CSS in your head is tough. Now, it’s just a few lines of CSS to change the whole system.

Jhey Tompkins also made a neat demo on CodePen where you can see how changing these color variables impacts the UI:

This whole accent-color thing to me feels like just another way in which modern CSS is so much cleaner and better than it was a few years ago. And it shows how all the interrelated systems of CSS are continuously improving over time. It’s exciting stuff for sure!

TLDR Newsletter

TLDR is a free daily newsletter for developers and designers with links and TLDRs of the most interesting stories in tech 📱, science 🚀, and coding 💻!


Did you know WebPageTest (the premier performance testing tool out there) has a Twitch Channel? They do, and Chris Coyier was a guest with Tim Kadlec not long ago digging into CSS-Tricks.com itself to find performance problems. You can watch that video here, see the results of the findings here. They do this live on Twitch every other Thursday along with some great discussions with experts in the perf space. If this kind of thing interests you, make sure to subscribe and learn more about WebPageTest.

[Chris]: Admittedly this struck a nerve with me too:

Let’s stop fooling ourselves. What we call CI/CD is actually only CI.

Anton Weiss, DEV

I just say CI/CD when talking about the general DevOps concept of working with Git and running stuff when Pull Requests and merges happen. But that’s the CI part. For example, at CodePen, when any code is pushed to any branch, a bunch of things happen:

  • Linters run over the code making sure there aren’t obvious problems in the code.
  • Tests run (of various types across various languages) making sure code is doing what it should.
  • Messages are distributed (e.g. to Slack)
  • Ya know, stuff.

The more the merrier here, I think (as long as it all takes, say, just a few minutes). We always have our sights on more. I’d like to put in some automated performance testing and automated accessibility testing, for example. On Pull Requests, merging can be blocked unless tests pass, metrics are inline, and human(s) have reviewed it. We use GitHub Actions, for the record. Here’s a pretty nice intro to all that from Aleem Isiaka.

Then, when evvverrryyything passes, then what? Well, nothing. Hence the “only CI” sentiment. We deploy code when we want to deploy code. We have a special process for that, and even a special fancy UI we’ve built for it. It’s not “continuous.” That’s on purpose because shipping code to production feels like it should be done with purposeful timing. As well-tested as a release might be, why do it right before you leave for the weekend? Why not just wait until some normal morning where your butt will be in the seat for the next several hours, ready if something unforeseen does go wrong?

Maybe that’s poo-pooing on what can be the glory of true CI/CD, but hey, whatever. At the moment, I don’t feel like CI + deploy purposefully is particularly slow or problematic.