Web Components On Fire
This all started when I found an awesome CodePen
with some bouncing rainbow text. As happens to me all the time these
days, I thought to myself, “That could be a web component!” And a few
lines of code later, the <hotfx-slinky>
element was
born. Now any text can be bouncing rainbow text.
To use the custom element yourself, add this script to your page:
Then wrap your content in a <hotfx-slinky>
element.
If you want a little more control over the animation, you can change
some of the CSS variables that control it.
I was pretty pleased with myself at this point, but then I thought, people are going to want even more. And by people I mean myself. For instance, I already wanted horizontal movement instead of vertical movement. I was about to add another 5 variables and some more animations, but then I thought, this is never going to be enough for me....
Instead of adding more variables, I should just let people write their own CSS. Now we can get horizontal movement, or movement in three dimensions or whatever else you want.
The copied elements are in a shadow DOM, so we can’t style
them directly. Instead use the ::part(copy)
selector to get
at them. There’s a problem with that however which is that you can’t set
keyframes with it because your @keyframes
rules are not
inside the shadow DOM. So, the slinky element accepts a
<template>
element that just copies its contents into
the shadow DOM, including any <style>
tags.
Adding the template element also completely disables the default
styles. If you want to just disable the default styles without adding
your own, add the no-style
attribute.
But wait... let’s back up for a second: What is really going on here? Like at the most basic level.
This is a custom element that duplicates it’s children a bunch of times and then gives colors to them as a CSS variable.
What if we just throw some attributes on this puppy to control all of that? Then we can really open up the possibilities.
In the demo below, you can control the number of elements created with
the length
attribute and change the start and end colors
for the gradient. The rainbow
attribute tells the component
to take the long way around the color wheel when it does the transition
between two colors.
Now we can add enough elements to make that 3D one feel like a real rainbow slinky.
Each of these demos is unique but the basic idea here is the same. The
slinky makes copies of elements and assigns two custom properties to
them: --index
which is the number of the copy and
--color
which is the color on the gradient. In case you
need it, there’s also --length
which is the same as the
length attribute on the slinky.
Most of the animations with trails of elements involve setting an
animation-delay
property like calc(var(--index) *
50ms)
. Or you can just limit the maximum extent of the movement
by using calc()
with --index
on the transform
itself.
CSS is design silly putty—pure creative possibilities. Sometimes you just need more elements to play with. The slinky provides.
So far we’ve been playing with the same text. Obviously you can change the text, but you can also use any DOM element. Here we’ve got a circle of burning poop spinning infinitely in space while it smiles at you. Delightful.
Shout out to Yuan Chuan and his <css-doodle>
element
for part of my inspiration. CSS
Doodle makes a series of empty DOM elements which you
can style however you want with a custom CSS syntax. Most
of these simple text demos could be recreated using CSS doodle and a
::before
or ::after
pseudo element to add the
text.
Obviously, the answer is “yes” because it has been a lot of fun. But
there’s a more interesting question: should this be a custom element?
Well, maybe not. Instead of putting one <h1>
tag
inside a <hotfx-slinky>
and setting
length=20
, we could achieve the exact same thing by just
copy/pasting 20 <h1>
tags in our HTML.
Then our slinky would work without any JavaScript at all.
But, let’s face it, who has time to be a purist these days? Writing this as a custom element makes things quite a bit easier. For one, the element makes our HTML much faster to understand and modify. If you want to go from a 10 elements in your slinky to 90, you’re just changing one number instead of adding a ton of markup.
Also these attributes can all be changed on the client and the element will re-render it’s DOM. That’s the only way to make this thing dynamic like we did with the attribute controls above.
This custom element also works regardless of your server-side language. There are probably just as many ways to repeat a part of page as there are templating engines. With our code running in the frontend, any backend works to serve it.
Too much JavaScript or reliance on it when you don’t need it is bad. But in this case, we are only relying on a little bit of JavaScript (about 100 lines or so) and if it breaks, the page will still be readable. Your users will surely never notice.