Gotchas in Naming CSS View Transitions
I’m playing with making cross-document view transitions work on this blog.
Nothing fancy. Mostly copying how Dave Rupert does it on his site where you get a cross-fade animation on the whole page generally, and a little position animation on the page title specifically.
To animate the page title, I need a unique ID to target the element I want to transition between pages, e.g.
<!-- 1st page HTML -->
<a
href="/2024/i-love-kitkats"
style="view-transition-name: kitkats">
I Love KitKats
</a>
<!-- 2nd page HTML -->
<h1 style="view-transition-name: kitkats">
I Love KitKats
</h1>
The problem with the above is that, if I have page that lists all my blog posts and I have another one about KitKats, what will the ID be?
Well I already have a globally-unique ID for each post: the post’s URL path!
So, in my static site generator, I think “I’ll just use my post’s path as the transition name!”
<a
href="/2024/i-love-kitkats"
style="view-transition-name: /2024/i-love-kitkats">
I Love KitKats
</a>
I’m not actually sure if this will work because of the forward slashes, but I try it.
No dice.
“Maybe I need to wrap it in quotes, like a the name of a value in font-family
?”
So I try that:
<a
href="/2024/i-love-kitkats"
style="view-transition-name: '/2024/i-love-kitkats'">
I Love KitKats
</a>
Nope, that doesn't work either.
Ok, fine. I’ll just strip out the slashes in the path. I don’t need the slashes for it to be a unique identifier, e.g.
postPath.replace(/\//g, '')
Which gives me HTML like this:
<a
href="/2024/i-love-kitkats"
style="view-transition-name: 2024i-love-kitkats">
I Love KitKats
</a>
Still no dice.
After trying to get it working without looking at the manual, I concede to looking up view-transition-name on MDN. The docs say I have to use “a distinct identifying name (a <custom-ident>
)”.
“What is a <custom-ident>
?” I follow that link and read about it.
The docs throw some shade at me:
A
<custom-ident>
must not be placed between single or double quotes as this would be identical to a<string>
.
Whoops.
Ok, so it’s an identifier that has some special rules, like that you can’t use an already-reserved global CSS name like “inherit”, “unset”, or even list style names like “disc” or “square”.
Also you can’t use a forward slash (my bad).
And you can’t start the string with a number (my bad).
So I stick a prefix on each, e.g.
'title-${postPath}'.replace(/\//g, '')
Giving me:
<a
href="/2024/i-love-kitkats"
style="view-transition-name: title-2024i-love-kitkats">
I Love KitKats
</a>
Boom! It works!
So there you go. Way more than you ever wanted to know about the gotchas of a creating a unique view-transition-name
.
And if you didn’t know about <custom-ident>
in CSS, now you do!