The Squirminal Web Component
A lightweight structural-only zero-dependency web component to progressively animate to reveal HTML content. I believe the name came from an awkward portmanteau of squirmy and terminal.
This one is a few years old (but I am currently cataloguing my web components) and was developed to fake an antique terminal for the web-based CLI used in the Your Year on Netlify project.
- Source Code
- Demo (more demos below)
Features
- Works with
prefers-reduced-motion
- Works without JavaScript (fallback to full content)
- Add a blinking cursor via
<squirm-inal cursor>
- Autoplay (only when visible) via
<squirm-inal autoplay>
- Works with text nodes inside any arbitrary HTML content.
Better than Before
When I worked on the slide deck for my Smashing Conference talk in 2021, I developed a similar mechanism to do this, but in a much less efficient way: each syntax highlighted character was wrapped in an additional wrapper element on the server!
I wrote about this in Queue Code—“Live” Code without Errors and you can play around with it on the demo below:
That approach leaned heavily into server rendering unnecessarily—the whole point of this effect required client interaction and the fallback experience was the original content in its entirety.
Lessons learned
Squirminal is a better approach that doesn’t require expensive DOM modification on the server and is much more powerful—it can work with any arbitrary HTML content (e.g. lists, images, tables, etc—it’s not limited to syntax highlighted text) and leaves the original content intact and unmodified before or without JavaScript.
There is an important lesson here—in this case the best progressive enhancement compromise involved less server rendering! Ultimately this use case and interaction required clientside interactivity, so it was okay to lean into that a bit more—while still building on a good progressive enhancement baseline.
This was an important reminder to me that progressive enhancement is a continuum of possible solutions—and it’s important to adjust where your solution lives on that continuum as needed and for your individual requirements (and hopefully your tools don’t force you into a corner before you can make those decisions).
Demos
class MyComponent extends HTMLElement {
connectedCallback() {
// web component stuff
// web component stuff
// web component stuff
// web component stuff
// web component stuff
// web component stuff
// web component stuff
// web component stuff
}
}
if("customElements" in window) {
customElements.define("my-component", MyComponent);
}
In the wild
Live Site Walkthrough
Here’s a demo screencast I recorded of my personal Your Year on Netlify flow.
10 Comments
Robb Knightmare
@zachleat I’ve been using this for a while and it looks fantastic https://echo.rknight.me Echo: RSS Cross Poster
Zach Leatherman
@robb Awesome! I’ll link that from the blog post!
Matheus Fantinel
@zachleat you mentioned it works with JavaScript, but not in web component form, right? With JS disabled it doesn't load anything, unfortunately. That's the main thing stopping me from going all-in on web components right now, and I'm not sure if it's “fixable”
Zach Leatherman
@fantinel a couple of muddled terms there, but this is what it looks like on the demo without JS (it just shows the content).
Eric Portis
@zachleat First I read this as "Squirm–I Am Not A Lawyer" but now I see my mistake, it's actually a portmanteau of "Squirm Criminal"
Matheus Fantinel
@zachleat oh sweet! I think I had opened the "Queued Code" page instead ????♂️This is nice! Am I right in assuming that the web component isn't loading at all and is just behaving like a container div?
Zach Leatherman
@fantinel correct!
Zach Leatherman
@fantinel you’re right that the queuecode demo doesn’t work without JS ????—although I think that’s a bug and not a technical limitation
Zach Leatherman
@eeeps 1337 h4x0rs commit smooth criminal terminal crimes
Eric Portis
@zachleat You've been `banner`ed You've been `cowsay`ed By a squirmy terminal