Semantic CSS Styles Using Data Attributes

Estimated Reading Time: 2 minutes
January 4, 2016

What we currently have in CSS is the use of IDs, classes, pseudo-selectors, and elements. With HTML5 and CSS3, what if I told you there was another option? What I’ve begun using at InfoTrust, inspired by a former coworker (tbremer https://github.com/tbremer), is using data-attributes to control CSS and add another layer of abstraction that benefits organization in CSS..

				
					[data-button] {
    background-color: grey;
    border: 1px solid black;
    color: black;
}

[data-button~="primary"] {
    background-color: blue;
}

[data-button~="large"] {
    height: 40px;
    width: 120px;
}

				
			

One of the benefits of this approach is the separation of your style guide from your class structure. Who likes looking at classes like this:

				
					<button class="btn btn-large btn-primary">Button</button>

				
			

Repeating elements like this takes up space and makes your code look complicated, and difficult to type accurately.

Using the data attribute, which is a valid HTML5 selector and can be targeted by both CSS and Javascript easily (IE11+), it encapsulates the element and helps to keep the markup clean:

				
					<button data-button="large primary">Button</button>

				
			

Much better looking. Note that to properly target space-separated values like this, we use the “ ~= ” attribute selector which matches individual words within space-separated values.
Also, it’s worth noting that attribute selectors like [data-button] have the same specificity as classes, not lower as some might assume. This means you can still combine them with classes for additional styling:

				
					.secondary { border: 1px solid DarkBlue; }
<button data-button=”large primary” class=”secondary”>Button</button>
				
			

This approach lets your classes deal with layout or positioning, while the visual styling is handled by the data attributes, making your components more semantic and your HTML more readable.

				
					<button data-button="large primary" id="login" class="float-right">Button</button>
				
			

For very complex components, you might want to consider using multiple data attributes instead:

				
					<button data-button data-button-size="large" data-button-type="primary">Button</button>
				
			

While attribute selectors are marginally slower than class selectors in performance tests, the difference is negligible for most applications and outweighed by the semantic benefits.

Down the road when dealing with updates to the styleguide or refactors, you are able to avoid verbose CSS naming structures and can have a more fluid style guide. The possibilities are endless with this approach and in my opinion offers better semantic clarity for your styles and gives developers a more intuitive approach to writing their HTML and CSS.

Author

Last Updated: March 7, 2025
Talk To Us

Get Your Assessment

Thank you! We will be in touch with your results soon.
{{ field.placeholder }}
{{ option.name }}

Talk To Us

Talk To Us

Receive Book Updates

Fill out this form to receive email announcements about Crawl, Walk, Run: Advancing Analytics Maturity with Google Marketing Platform. This includes pre-sale dates, official publishing dates, and more.

Search InfoTrust

Leave Us A Review

Leave a review and let us know how we’re doing. Only actual clients, please.