While doing my usual browsing of source code, I happened upon a curious way of styling.1 The website was not applying styles via classes; it was using HTML attributes:

<div am-PriceTable>
  <div am-PriceTable-Option="past">
    <div am-PriceTable-Time>Early Bird</div>
    <div am-PriceTable-Price>650</div>
    <div>Sold out!</div>
  <div am-PriceTable-Option="past">
    <div am-PriceTable-Time>Middle Bird</div>
    <div am-PriceTable-Price>750</div>
    <div>Sold out!</div>
  <div am-PriceTable-Option="past">
    <div am-PriceTable-Time>Late Bird</div>
    <div am-PriceTable-Price>850</div>
    <div>Sold out!</div>

The HTML structure above might look similar to the BEM naming conventions.

The main questions that arise from this approach are:

  1. How are the elements targeted by CSS; and
  2. Does it pass HTML validation

Targeting HTML attributes with CSS

CSS attribute selectors are used to apply styles to elements, like so:

[attribute-name] {
  /* Your styles here. */

The PriceTable-Option element is also being assigned a value:

<div am-PriceTable-Option="past">

In this case, past is a modifier; a style that modifies the base styles of the element.

HTML and CSS validation

When it comes to validity of HTML attributes with a custom namespace, the short answer is: they are invalid. Only data-* attributes are allowed to be customised by the developer.

data-* attributes were added to keep things consistent and allow the validators to handle custom attributes. This is the only way custom attributes can be defined while still being valid when passed through a validator.

The data-* namespace works in favour of the nature of HTML. Who knows what attribute names will exist in the future? If a custom attribute like fudge is used, there will still be a (highly unlikely) chance that fudge becomes a new attribute in the next HTML specification.

Even though the document will be marked as "invalid", there is no real reason as to why custom attributes shouldn't be used. It's incredibly unlikely that user-defined attribute names would become actual attributes in the HTML specification.

In terms of CSS, attribute selectors are perfectly valid and classed under CSS 2.1 selectors and are supported by modern browsers (all the way to Internet Explorer 7). Mozilla's docs give a great overview of attribute selectors.


  1. There is a name for this methodology; it's called "Attribute Modules for CSS". At the time of writing, the definition for AMCSS (available on GitHub) has not been updated since 2015 so it is safe to say this technique has likely been deprecated in favour of more modular approaches (particularly the ones coming as a result of CSS in JavaScript).