External Publication
Visit Post

Clickable cards

Donnie D'Amato November 8, 2024
Source
While having a good time with internet friends on Bluesky, I saw a thread asking about Josh Comeau’s website, specifically asking about why the entire card isn’t clickable. Josh’s replies concerning usability is spot on, and I’ve definitely been naughty doing the typical on a element right here on the blog homepage. The replies in the thread also have some good suggestions but I was wondering if there was alternative. I have two main criteria: Use HTML & CSS only, so there’s no need to listen for additional behavior. Ensure that it meets user expectations both in terms of accessibility and also visually. I think I have something… Forgotten memories In the list of HTML tags that people forget about, there’s two that are very often unused: and . These are meant to be used with an associated so a user can click defined regions of an image. The example for on MDN has a good sample of this. The idea is that you define the areas’ shapes using some attributes and then group them into the . Then you assign that to the using , which is a reference to the . Each can accept many of the same attributes of an , most importantly including and . So what if we could include a visually hidden image the size of the card and then add an to the entire area of the image? Let’s take a look: Sourcery We certainly don’t want to make a request for an image that is only being used to support this behavior. We’d want some resource that was quick and hard-coded. Stack Overflow has a topic on “smallest filesize for transparent single pixel image” which is exactly what we need. I’ll add a few additional attributes as well. The is added because this image is strictly to support the area that we want to click, we don’t want to expose it in the accessibility tree. The and attributes are ensuring that the image is the full size of the container it is placed within. And the is meant to reference a somewhere in the page. Next we’ll make the and : The and should be clear. The tells the to be the same size as the . The is the same text you’d expect for images, except here we’re using it as the label for the link. On MDN, it mentions that this is used for browsers that don’t show images. Finally, let’s put all of this in a card: Note that this could be optimized such that the is added once and all elements in every card can use the same reference. Then the only unique element to each card would be the attributes in the . This means you’re only “rendering” a single image. Styles Now for some styles, and there isn’t a lot so I’m going to write everything below and explain: First, the grid styles are a different way of getting the direct children to fill the container. Traditionally we’d place on the and then on the . However, that could cause layering problems since creates a new stacking context. The grid properties here will make the children fill the container. Next, the listens for when the element is focused and applies a ring to identify this card is ready to be interacted with. You can add your own indication, I’m using the default browser styles. Finally, the styles for ensure that it doesn’t take up any space in the composition but is still reachable with assistive technologies. The styles within here are a new way of supporting visually hidden so the text is reachable. I have a CodePen of the implementation below, including the traditional block anchor: See the Pen Clickable card! by Donnie D’Amato (@fauxserious) on CodePen. Results So now this should allow for all the normal link behavior; hovering to see the link destination, right-click to open in new window, etc.. This also allows for some more interesting options. Perhaps you’d want to allow for parts of the card to be clickable so that other text can be selectable, you could adjust the position of the to cover the area. Maybe you’d want to conditionally allow text in the card to be selectable. Use CSS to hide the . Have I tested anything else past what I’ve said here? Nope. But, maybe someone can be further inspired and continue down this path. Is this really any different from adding a display block and filling it inside the card like it is done with the ? Sort of, since it would still need content for assistive technologies to read, and you’d need to wrap the content in a and visually hide it specifically for ATs, or maybe use an . Maybe it’s easier, but maybe there’s something to the approach above that makes it better in some way? At the very least, I bet you probably learned about some HTML elements you haven’t heard of. 😉

Discussion in the ATmosphere

Loading comments...