Piccalilli’s front-end challenge: progress indicator
For fun I did Andy’s front-end challenge. Here is a dump of my thoughts as I was building it.
tl;dr: I ended up using silly CSS+pseudoelement drawing techniques because I wanted a single-element component that worked reasonably well without JavaScript.
- I was originally going to use
<progress>, but after some experimentation determined that::before/::afterpseudoelements andcontent: attr(value)don’t work with it. - Instead, I’m using
role="progressbar"on a<div>. - For screenreader accessibility, the goal is to have it appear as just a
progressbar. It would be possible to, for example, add an SVG icon with a description, but IMO the checkmark is purely presentational: knowing thataria-valuenowis 100 should be sufficient.- If the design had been more complicated, for example requiring a rounded endcap on the ring, it’d require SVG. Since it doesn’t and I want to keep it simple for authors, I’m avoiding that. That’s also why I’m not following his advice to “stray away” from inlining SVG in CSS.
- Now that I’m not trying to fit it all in a built-in element, don’t need to use pseudoelement tricks; can be more clear and explicit.
- The debate between doing it in a single element or using separate children for the ring, the value, and an SVG checkmark:
- I want to use a pseudoelement for the value anyway so that you can display the value directly from the
attr(). I want the number to work without JS even if the ring doesn’t. - I’m coming from a design system world, so am thinking about developer ergonomics. If the goal is to have a component that can easily be dropped into an application, I would strongly prefer that it’s a single element. For an author not to need to add light children, shadow DOM and a single element with CSS/pseudoelement drawing are the options.
- A Web Component with shadow DOM would be my normal go-to, but the prompt seems especially concerned with no-JS behavior. Declarative shadow DOM won’t really help here without some sort of SSR, so because it’s possible to implement this design without it, I’m opting for that.
- A custom element without shadow DOM would require an author to write the child elements themself, which would be annoying and prone to error.
- Could put a
<progress>as a light child of a shadow-using Web Component and visually hide the slotted content, but then you lose all visuals without JS.
- I want to use a pseudoelement for the value anyway so that you can display the value directly from the
- Does any of this really matter since the value wouldn’t be set without JS anyway? I don’t know.
- Should it be sized based on font size? Sure, why not.
- Browser support for
@propertyisn’t as good as I’d hoped, but still cool to progressively enhance it with an animation for the ring.
So with that, here’s the result:
See the Pen Piccalilli front-end challenge: progress indicator by Noah (@noleli) on CodePen.