Attribute Modules (AM) is a technique for using HTML attributes and their values rather than classes for styling elements. In doing so, each attribute effectively declares a separate namespace for encapsulating style information, resulting in more readable and maintainable HTML & CSS.
It's not a framework or a library, it's a style that better describes the components you're building. For an introduction to how AM was developed, see the original blog post by Glen Maddern. The specification itself is available on GitHub.
Example: Bootstrap Buttons
Buttons are one of the strongest use-cases for AM. Here we've converted some of Bootstrap's button markup as an example.
<!-- Large primary button -->
<a class="btn btn-primary btn-lg">Large primary button</a>
<a am-Button="primary large">Large primary button</a>
<!-- Default button -->
<a class="btn btn-default">Default button</a>
<a am-Button>Default button</a>
<!-- Small info button -->
<a class="btn btn-info btn-sm">Small info button</a>
<a am-Button="info small">Small info button</a>
<!-- Extra-small danger button -->
<a class="btn btn-danger btn-xs">Extra-small danger button</a>
<a am-Button="danger extra-small">Extra-small danger button</a>
The original Bootstrap markup is heavily convention-based: all buttons require a btn
class and a specific button class prefixed by btn-
. It results in cluttered, repetitive markup.
The AM version, in contrast, uses the attribute am-Button
as an identifier, and allows straightforward, natural, additive modifiers, e.g. large
, primary
, etc.
The CSS changes are quite straightforward:
.btn [am-Button] { /* Default button styles */ }
.btn-primary [am-Button~="primary"] { /* Primary colours */ }
.btn-large [am-Button~="large"] { /* Large sizing */ }
Example: Flexbox Grid
Using a grid system is commonplace and Flexbox Grid is one we're particularly fond of. Here we've converted some example markup into an AM style.
<div class="row reverse" am-Grid-Row="reverse">
<div class="column-12--hand column-8--lap" am-Grid-Col="12 lap:8"
<div class="box" am-Demo="box">Responsive</div>
</div>
</div>
The original markup shares some problems with all class-based grid systems. Because grid classes are used so frequently, it uses relatively bare css classes like row
& reverse
, but because columns need to be responsive, it eschews a global col
class and instead defines col-breakpoint-number
classes.
The AM markup, on the other hand, defines am-Grid-Row
and am-Grid-Column
modules, and since each of those define a namespace we can be free to use values of our choosing. These values can make use of a wider range of characters than is convenient with classes, so we can use a breakpoint:number
syntax, which is easier to understand at a glance. We can also adopt a mobile-first apporach by omitting the hand
breakpoint.
Example: Traits
While AM can be used as a drop-in for BEM-style class naming, you can also consider a module defining a more general namespace for grouping related styles. Similar to utility classes in Suit CSS, these can be thought of as reusable style traits, that can be applied on or within components.
<div class="u-posAbsoluteCenter" am-position="absolute center">
<div class="u-textTruncate u-textCenter" am-text="truncate center">
Very centered text.
</div>
</div>
Here, we're able to make use of the fact that values for am-position
and am-text
operate in different namespaces, so we can use the value center
in both places without worrying about naming clashes.
Built with AM
- am-Grid
An AM grid system, inspired by Flexbox Grid. View source. - amcss.github.io
A simple example of components in AM, broken up into four simple modules.
Call for feedback
We'd love to hear suggestions for inclusions to the AM specification, by adding an issue to our tracker or contributing to an existing discussion. If you create an AM-style CSS library or framework, please let us know.