📝 Give the Stage to Attributes Because Accessibility Deserves the Spotlight
Eris Sulistina

Eris Sulistina @sejutaimpian

Joined:
May 14, 2024

📝 Give the Stage to Attributes Because Accessibility Deserves the Spotlight

Publish Date: May 28
2 0

There are many ways to target elements with selectors—Universal selector *, Type selector like header, ID selector #header, Class selector .header, and others.

But among all of them, I find myself (and other developers too) mostly using class selectors for styling. I get it—classes are more flexible.

But that doesn't mean you should use them everywhere. Sometimes all you need is a type selector. Sometimes, you just need an attribute selector.

Overusing classes can blind you to the unique powers other selectors have to offer.

And just like attributes, accessibility is often overlooked by developers.

Even though implementing accessibility may feel like doing twice the work, it actually makes your website healthier, more inclusive, and increases your value as a developer.

In this article, I want to open your eyes to attribute selectors and how they can shine—especially when combined with accessibility.

🤔 What is an Attribute Selector?

Attribute selectors let you target elements based on their HTML attributes. The syntax uses square brackets [attribute].

/* Targets elements with the hidden attribute */
[hidden] { .... }

/* Targets input elements with the required attribute */
input[required] { .... }

/* Targets elements with aria-hidden="true" */
[aria-hidden="true"] { .... }
Enter fullscreen mode Exit fullscreen mode

🎯 When Does an Attribute Selector Make More Sense?

  1. The attribute has clear semantic/functional meaning
  2. It's not possible or efficient to use a class
  3. You want to style elements based on data- attributes

✅ Semantically Meaningful Attributes

💡 Example 1: Alert UI

<div role="alert" aria-live="assertive">
    Profile updated successfully
</div>
Enter fullscreen mode Exit fullscreen mode
[role="alert"] {
    background-color: green;
}
Enter fullscreen mode Exit fullscreen mode

No need for a .alert class—just use its semantic meaning directly.

💡 Example 2: Required Form Field

<form action="#">
    <div>
        <label for="name">Name</label>
        <input type="text" required>
    </div>
</form>
Enter fullscreen mode Exit fullscreen mode
label:has(+ [required])::after {
    content: "*";
}
Enter fullscreen mode Exit fullscreen mode

This selector helps provide a visual indicator for required fields.

💡 Example 3: Tab UI

<button role="tab" aria-selected="true">Tab 1</button>
Enter fullscreen mode Exit fullscreen mode
[aria-selected="true"] {
    color: blue;
}
Enter fullscreen mode Exit fullscreen mode

This can replace .active with something more semantic.

💡 Example 4: Active Navigation

<a href="/" aria-current="page">Home</a>
Enter fullscreen mode Exit fullscreen mode
[aria-current="page"] {
    color: blue;
}
Enter fullscreen mode Exit fullscreen mode

Accessible and clean styling, all in one.

🚫 When Classes Aren’t Ideal

💡 Example 1: Framework Elements

<button type="button" data-bs-button>Click</button>
Enter fullscreen mode Exit fullscreen mode
[data-bs-button] {
    background-color: indigo;
}
Enter fullscreen mode Exit fullscreen mode

Can’t touch third-party code? No problem.

💡 Example 2: Detect Missing alt Text

<img src="https://picsum.photos/600/400">
Enter fullscreen mode Exit fullscreen mode
img:not([alt]), img[alt=""] {
    filter: blur(4px);
}
Enter fullscreen mode Exit fullscreen mode

Useful for debugging or warning about missing descriptions.

💡 Example 3: Label Without for

<label>Name</label>
<input id="name">
Enter fullscreen mode Exit fullscreen mode
label:not([for]), label[for=""] {
    opacity: .3;
}
Enter fullscreen mode Exit fullscreen mode

Helps catch potential UX issues in forms.

⚙️ Styling Based on data-* Attributes

💡 Example 1: Dark Mode

<html lang="en" data-theme="dark">
Enter fullscreen mode Exit fullscreen mode
[data-theme="dark"] {
    background-color: black;
}
Enter fullscreen mode Exit fullscreen mode

💡 Example 2: Button Variants

<button data-variant="primary">Submit</button>
Enter fullscreen mode Exit fullscreen mode
button[data-variant="primary"] {
    background-color: cyan;
}
Enter fullscreen mode Exit fullscreen mode

✨ Final Words

I hope this article helps you open up to using attribute selectors more intentionally—especially when dealing with semantics and accessibility.

With the right usage, we can write CSS that's:

  • Cleaner
  • More semantic
  • More inclusive

So from now on, let’s give the stage to attributes, because accessibility deserves the spotlight 🙌

Got a cool trick with attribute selectors? Share it in the comments!

If you liked this article, don’t forget to 💖 save, 🗨️ comment, and 🔁 share it with your dev friends!

See you in the next post 👋

Comments 0 total

    Add comment