In “Meaningful CSS: style like you mean it”, Tim Baxter argues for replacing CSS approaches that heavily rely on classnames with a markup-centric approach. I think adding styling to HTML elements is hugely beneficial, but works best when combined with a class-based approach. We need a bit of both.
In his article, Tim explains that in the past few years, HTML (especially when enriched with ARIA) has become much more expressive. So expressive, that we can throw away class-based approaches to styling. We can just style on HTML elements themselves.
Your team’s standards vs web standards
The challenge in CSS is to find a way to apply the styles you want to the things you want to apply them to. Classes let you give your things any name. Classes are to “[represent] the various classes that the element belongs to”, says the HTML standard . With a ‘class-based approach’ I mean approaches like OOCSS and BEM, that recommend you to define components or objects with just or mostly classnames.
The most-used argument for a class-based approach to CSS is that it makes things easier for teams. Once a team agrees on the preferred nomenclature for a thing, they can consistently use those names within their team.
But consistent standards already exist, in the form of web standards. Why not make those the baseline? Tim Baxter also says this:
if there is any baseline level of knowledge we should expect of all web developers, surely that should be a solid working knowledge of HTML itself, not memorizing arcane class-naming rules
Yes, let’s add styling to HTML where we can! This is wonderful, because web standards for markup were made through a long process of mailing lists, IRC discussions and face to face meetings. They have already gone through the trouble of defining what things are on the web.
Web standards define the difference between inputs for phone numbers and those for email addresses. They define the difference between a definition list and an unordered list. And the difference between quotations and paragraphs.
We need a bit of both
Adding style rules to native HTML elements, and use the power of some of the many attributes HTML comes with, sounds very sensible to me. Because the web standards people have already defined and documented what things mean in HTML, we can just use those semantics and be done with it. This also aids your users. Some of them may be using a screen reader or search engine to access your site.
But there is a problem here. The issue with using ‘just’ HTML to apply CSS, is that HTML is simply not as expressive as the design languages that often underly our web projects. Many web projects contain various instantiations of the same, meaningful HTML elements. In such projects, the meaning cannot come just from the elements themselves.
To be more precise, I think avoiding class-based approaches does not align with how web teams collaborate.
Web standards document:
- what a form is
Our project’s design language contains:
- a newsletter form
- a search bar
- a contact form
- a poll (why not?)
These are all different types of forms, and would often not benefit from sharing style rules. The interaction designer has had user tests done and decided to do labels next to inputs in the contact form, and make the search bar expand when you click it. They’re all forms, but they’re all different.
Web standards document:
- what an input with the type ‘submit’ is
Our project’s design language has:
- the newsletter signup submit
- the search button
- the ‘Contact us’ form’s submit
- the button to submit your choice in the poll
Again, I think their is much more difference in meaning than we can ever distinguish between with styling just
<input type="submit"> .
We can design beyond the list of available HTML elements
If we expect to te able to style just HTML elements, we should only allow designers to design one style for each HTML element. We would just hand them the list of available HTML elements , and they would create a design for each. That would be an insane process to follow. Unrealistic, too. Interaction designers have user journeys to worry about, they need to keep track of the whole picture.
Designers for the web, rightly, design more than just individual HTML elements. This is why, for front-end developers, it makes sense to use classes like
.form--contact . Or, depending on whether they differ a lot,
I have built websites where all the forms look the same, all the tables look the same and all the quotes looks the same. In those projects, they really exist, classnames are mostly unnecessary. Yet, most larger web projects are not like that. They have a lot of variations and for their meaning they cannot rely on HTML elements alone.
We have to be pragmatic about this. We should collaborate on websites that go beyond just what native HTML elements have to offer. Creative combinations of markup can bring our users a great experience. Classes aid creative combinations.
Using classes to draw distinctions
So, I think we need to define blocks with classes, so that we can distinguish between all the different components that are in our project’s design language. There is no harm in adding classes for variations of those blocks, or elements within the blocks. Yup. After (a lot) of initial scepticism, I quite like BEM and have seen it work.
Classes are essential to do the work we need to do: style websites with a varied design language that creatively uses combinations of HTML elements. Using lots of classes should not stop one from using meaningful markup. CSS experts should always also be markup experts, as meaningful markup is important for many reasons.
I really liked Tim Baxter’s article about styling HTML elements not classnames. It provokes thought and is a welcome alternative to the let’s-add-classes-to-all-the-things consensus. And I agree, adding styling to HTML elements is powerful, as they have inherent meaning.
But I think HTML and ARIA are (still) not expressive enough to draw the distinctions our designers draw. Classnames are essential in making such distinctions. The best approach, is to use both classes and meaningful markup.