Chris’ Corner: Useful HTML and CSS Patterns
The <table>
is one of the grand enemies of responsive design. They don’t wrap (that wouldn’t make much sense) so they can “blow out” the width of a mobile device pretty easily. The overflow
property also doesn’t work on them. So you gotta find a way, and it really depends on the data. Sometimes a row of table data is pretty independently useful (imagine a row of employee data) so making all the <tr>
and <th>
/<td>
element display: block
and stacking them works. But that doesn’t work for data that needs to be cross-referenced. I think there are 3-4 other patterns that involve shuffling the data around to be more narrow-screen friendly. The old group of jQuery plugins Tablesaw from Filament Group showcase some of them.
Lately, I find rather than dig around for a display-altering solution, people just wrap the table in a <div>
and let that <div>
have overflow
. So now you’ve got a table that you can scroll/swipe around without really changing how the table looks. I find myself consulting Under-Engineered Responsive Tables by Adrian Roselli on how best to do that regularly.
Ryan Mulligan has a cool take as well in Full-bleed Table Scrolling on Narrow Viewports. The “full bleed” part means using the edge of the browser window. Which you might otherwise not! Typically there is padding on the left/right (“inline”) edges of content, which would also be limiting the width of the table.
The blue line in the screenshot above shows the padding on the column of content, which limits the width of the content inside there, but the table is explicitly pulled out from it to the edge. It’s a little thing but it’s classy!
Josh Comeau’s tutorial Animated Pride Flags has lots of fun things to learn along the way of creating a controllable version of this:
Notice that staggering is a big part of the look here. That happens with slightly different values to animation-delay
. Since Josh used React to created the DOM for this, the loop can output those values as inline styles and use the number of iterations that map
provides to stagger the value.
But wait! Maybe CSS should be helping us here, rather than us having to invent our own way to stagger things, right? That’s what the sibling-count()
and sibling-index()
proposal is all about. I’m a fan.
Josh’s tutorial basically just starts here and then covers more and more details. I especially like the bits of also stagging how much any given column “billows”, which is another use-case of staggering a custom property value. Also don’t miss the bits about double-stop color gradients and rounding width values to prevent awkward pixel gaps.
How should I mark this up? is always fun trivia. For me, anyway, I’m a very exciting person. Sometimes HTML has pretty cut-and-dry right and wrong ways to do things, but sometimes it doesn’t. There are differents ways with styling tradeoffs, accessibility tradeoffs, amount of markup tradeoffs, etc.
Lea Verou found a good one in What is the best way to mark up an exclusive button group? In other words, a group of buttons where only one can be active at a time. A multi-toggle? Lea, and plenty of other people, assumed that a group of <input type="radio">
is the right answer (only one radio button can be active at once), and then style them like buttons. I thought about <select>
too which can only have one active choice, but no way are you going to be able to style that as buttons, even with the wildly more styleable <select-menu>
.
Léonie Watson stepped in with advice that essentially boiled down to: if they look like <button>
s, you should use <button>
s, so there isn’t “a mismatch of expectations in terms of keyboard interaction and shortcuts.” Interesting!
Lea thinks maybe we need a <button-group>
. Again, I’m a fan. I would have even kept <hgroup>
around, me, for grouping multiple headers.
Have you heard this (correct) advice? Placeholders aren’t labels. Like, don’t do this:
<input type="text" placeholder="Your Mastodon Profile" />
Do this:
<label for="mastodon-profile">Your Mastodon Profile</label>
<input type="text" id="mastodon-profile" placeholder="https://fosstodon.org/@codepen" />
A placeholder can be a little bonus hint or something, but even then, if that hint is important it should be accessible text which placeholder text is not.
I’m thinking of that because I saw Stanko Tadić’s CSS only floating labels. Floating labels is a pattern where text that looks like placeholder text (text within the input) moves away from the input but remains visible. This has gotten a bit easier as of late with the :placeholder-shown
pseudo-class.
What I like about the floating label pattern is that it continues to use <label>
, so the accessibility remains. It’s also just kind of clever and fun. What I don’t like about it is that I don’t think it does anything truly useful. I’ve heard proponents of it say that it “saves space” because the label is inside the input. But it’s only inside the input until it’s focused, then it moves out, and it moves out to somewhere where it needs to remain visible and have space. So……… why don’t you just put the labels where they move out to in the first place? Kinda feels like movement, for movement’s sake.
If you haven’t tried to create a password with Neal Agarwal’s * The Password Game yet, you really should give it a crack.