Skip to content
tezvyn:

Theming with CSS data-* Attributes

Source: developer.mozilla.orgHardHow cards are made

Theming with CSS data-* Attributes

Think of data- attributes as labels for UI state, like data-theme='dark'. CSS uses attribute selectors ([data-theme='dark']) to apply styles directly, avoiding complex class logic.

Why it exists

HTML needed a standard way to attach custom metadata to elements for use by scripts and stylesheets, without misusing generic attributes like 'class' or 'id'. The data-* attribute family was created to store this private, custom data directly on the element it describes.

The mental model

Think of data-* attributes as queryable, state-holding labels you stick on your HTML. Instead of a messy class like 'card-active-dark-mode', you can have a clean ''. The element's state is now explicit, readable, and separate from its base styling class.

How it works

You add an attribute beginning with 'data-' to an HTML element, such as '<body data-theme="dark">'. CSS can then target this element using an attribute selector: '[data-theme="dark"] { background: #333; }'. JavaScript can read or modify this state via the HTMLElement.dataset property. For an attribute 'data-user-id', JavaScript accesses it as 'element.dataset.userId'. Note the conversion from kebab-case in HTML to camelCase in JavaScript. CSS, however, always uses the full kebab-case name in its selectors.

When to use it

Use data-* attributes to manage component-level state that CSS needs to know about. It's perfect for theming ('data-theme'), component variants ('data-variant="primary"'), or simple interactive states ('data-state="open"' on a dropdown). It creates a clean bridge between JavaScript logic and CSS presentation.

When not to use it

Avoid storing complex, structured data that belongs in a proper data store or JavaScript memory; data-* attributes are for simple string values. If the data is only used by JavaScript and has no visual representation or styling hook, there's no need to write it to the DOM. Also, they are not indexed for search engines, so don't use them for publicly visible content.

One canonical example

A theme switcher. A button click in JavaScript sets the attribute on the root element: 'document.documentElement.dataset.theme = "dark"'. Your entire stylesheet can then react. You define styles like '[data-theme="dark"] .card { background: #222; }' and '[data-theme="light"] .card { background: #fff; }'. This single attribute change reflows styles across the entire application without adding or removing any classes.

Interview question

For which scenario is using a data-* attribute the most appropriate solution?

  • a.To pass data exclusively between JavaScript functions without any visual impact.
  • b.To provide content that should be indexed by search engines for improved discoverability.
  • c.To enable CSS to apply styles conditionally based on an element's current state.Correct
  • d.To store complex JSON objects directly within an HTML element for JavaScript consumption.
Why?

The card states that data-* attributes are perfect for managing component-level state that CSS needs to know about, creating a clean bridge between JavaScript logic and CSS presentation. Storing complex data, providing content for search engines, or passing data only for JavaScript are explicitly mentioned as scenarios where data-* attributes should not be used.

Just read this? Test yourself on what you have been reading.

Read the original → developer.mozilla.org

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on css — each one lists the topics its interview covers.

See open roles