From our sponsor: Chromatic - Visual testing for Storybook, Playwright & Cypress. Catch UI bugs before your users do.
The use of presentational class names in web development has been considered a bad practice for about as long as classes have been around. The notion is so ubiquitous that when making that claim, few people even bother to justify it anymore, as if it’s self-evident.
Even the HTML5 specification draft states the following:
authors are encouraged to use [class names] that describe the nature of the content, rather than [class names] that describe the desired presentation of the content
They never say why you’re encouraged to do this. They just state it as truth.
However, recently an increasing number of people have started to question this age-old advice. As developers started to build bigger and bigger applications, they found that these so-called “best practices” were often hindering the development process.
The problem comes when generally good advice like prefer semantic class names gets turned into never use presentational class names under any circumstance.
Best practices for writing front-end code shouldn’t be dogmatic. They should be based on whether or not the advice actually helps the development process. As web technology changes, what was once sound advice will not necessarily always be so. We have to continually examine our best practices and only use them if they make our lives easier.
The Case Against Presentational Class Names
When people tell you to avoid presentational class names, they seem to always cite obviously bad examples like big-red-header
or rounded-corners-6px
. Clearly these are bad names, and I don’t know any serious developer who would argue otherwise. This isn’t the debate I want to have.
When I say “defending presentational class names”, I’m referring to things like col-3
, nav-inline
, form-stacked
, vertically-centered
, etc. These names are abstract enough that they won’t be affected by minor cosmetic updates, but they’re still clearly presentational.
Though before I make the case for presentational class names, I think it’s good to review why we’ve historically avoided them.
The Problem of Redesigning
Developers strive to separate presentation from content, a form of the more generic software design principle: separation of concerns. The idea is that you should be able to easily modify one part of the code without affecting another part. You have modularity and encapsulation and therefore a more robust architecture.
In front-end web development, separating content from presentation allows you the freedom to redesign an entire site without touching the HTML (a notion popularized by CSS Zen Garden in 2003). When you use presentational class names, those names often won’t makes sense after a redesign, so you’re stuck either changing the HTML or redefining the classes to something they’re clearly not.
While all of this is without a doubt true, I’m not convinced that the problem of redesigning is actually a problem at all. I mean, I’ve been redesigning websites for many, many years. I’ve worked on big sites and small ones; I’ve worked alone and as a member of a large engineering team. And not once, in my entire career, have I worked on a redesign where I wasn’t allowed to alter the HTML. For me and most designers I know, when you redesign a site you want to change the markup. We’re a picky bunch; the previous person’s markup is rarely good enough for us!
The theory that an entire site can or should be redesigned by just changing the CSS isn’t practical and doesn’t reflect how real designers and developers approach new projects.
The truth is that right now CSS just isn’t powerful enough to handle any design you can throw at it. A certain markup structure is often needed to achieve complex designs. And if you’re adding extra markup just to achieve a particular look, then that markup is presentational regardless of what class name you give it.
In the future CSS will be more powerful and this will likely change, but as of today, HTML and CSS need to work together to achieve all but the most basic site designs. If we’re already forced to use presentational markup, are presentational classes really that different?
Class Names Should Be Semantic
This argument is kind of obviously circular, but I include it since it’s so commonly cited as a reason not to use presentational classes. Louis Lazaris illustrates its circularity comically in a recent blog post of his.
I fully support the use of semantics in HTML documents, but semantics can only be derived from markup when there’s a universally agreed upon meaning to that markup. HTML elements and certain HTML attributes have established semantics, but classes do not. A browser, screen-reader, or search engine cannot and should not be expected to parse your class names and guess at their meaning.
The Case For Presentational Class Names
If class names do not impart semantics then there is no inherent reason to use a semantic name over a presentational one. The choice of names should be purely based on their utility, on what helps or hinders the development process.
Given this, perhaps there are situations where presentational class names may actually be helpful. Here are some of the cases where my experience has shown presentational class names to be valuable:
Style Reusability
If a class name is used to describe the content, that class can only be used where that content exists, but when a class name describes a visual pattern, it can be used in many more places. The more abstract the visual pattern, the more reusable the class.
The web is full of UI components that, at their core, are a combination of the same abstract visual patterns. These patterns — layout configurations, grid systems, form styles, navigation techniques, etc. — can be reused not just within the same project, but on any project, regardless of content.
Sometimes these patterns can be expressed with non-presentational names (like the OOCSS media object), but oftentimes a presentational name is most appropriate. Calling a presentational pattern by a non-presentational name can add confusion where none is necessary.
Easy Developer Adoption
CSS is a language of visual design, and when writing CSS you’re usually concerned with making things look a certain way. If your primary skillset isn’t design it’s not easy to code the visual parts of a website.
However, if you have an existing component library that’s well-documented with exactly which classes can be used to create which components, implementing new designs is as easy as adding the right classes to the right elements. This is commonly known as a live style guide and is increasingly popular among large engineering teams.
The popularity of frameworks like Twitter Bootstrap have proven, beyond any doubt, that UI libraries are desperately wanted and appreciated by back-end developers. And without at least some presentational classes, these libraries would be far less useful.
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
Semantic Names Convey Less Intention to Others
Often a site design will require the same visual pattern for elements whose content is completely unrelated. If you’re avoiding presentational class names at all cost but also don’t want to repeat yourself, you’ll likely create a new class with a vague name like secondary-heading
to use in each of these situations.
Now, secondary-heading
isn’t a bad name inherently, but if the elements you give these classes to are truly unrelated and live in difference places on the page, then you’re not actually solving any problems. If there’s no contextual relation, then there’s no guarantee that you’ll always use the same visual style for these elements in the future, nullifying the reason to avoid presentational names in the first place.
In fact, this class name now describes neither the content nor the presentation, so, in that sense, it’s actually less semantic than a presentational class name, which at least has some valuable meaning.
Using presentational class names in a situation like this would likely clarify your intentions in the markup, reduce repetition, and make future updates to the style much simpler.
Keeping the Separation
I argued earlier that the problem of redesigning wasn’t really a problem at all. But that doesn’t mean there aren’t still compelling reasons to pursue a separation of concerns.
Separating presentation from content will help create a more modular front-end architecture. The problem is that separating content from presentation is usually oversimplified to mean removing all presentational elements from the HTML document.
Markup is not content. HTML adds structure and semantics to our content, but it is not the content itself. I think it’s time we stopped equating the two.
I’ve already shown that most site designs require a certain HTML structure, and if that’s the case, why pretend it’s not? If markup and CSS are required to work together, we shouldn’t waste our time fighting this fact.
We can achieve modularity and a separation of concerns in many other ways. In fact, almost all web development frameworks already do this for us. Ruby on Rails, for example, has a rich system of layout files, templates, partials and helpers that all work together to make the markup as abstract and DRY as possible. With abstraction like this, managing a lot of classes becomes significantly easier, even with an eventual redesign.
A good separation of presentation and content looks like this: The CSS should describe how our UI components look. The HTML markup should indicate which components we use. And the content should be somewhere else entirely.
CSS Preprocessors
There’s been some discussion recently about the idea of object oriented Sass. A well documented example of this is a recent post by Ian Storm Taylor. You can read it for yourself for a full understanding, but the gist is that you declare your presentational styles as regular classes (or use the Sass %placeholder
feature) and then you @extend
those classes with non-presentational selectors to avoid putting presentational classes in the markup.
While this approach certainly has some merit, I don’t believe it’s the answer. In my experience it creates as many problems as it solves and seems to be largely a case of semantics for semantics sake. Here are a few of the problems:
- This approach doesn’t address the issue of dealing with back-end developers who don’t specialize in CSS. For them, adding a class to the HTML is easy, but requiring them to learn a CSS preprocessor is much harder. It also introduces an extra step in the process. Previously they only had to edit the markup; now they have to edit the markup and update an
.scss
file. - This concept also assumes that maintaining HTML with a lot of classes is inherently harder than maintaining CSS. My experience has suggested otherwise.
- When you omit the class from the HTML you lose the inheritance chain. By that I mean it’s not clear from the markup what class or classes the element is extending. For example, if you use
@extend .button
inside a selector likeform input[type=submit]
, now you lose the ability to select all.button
instances via JavaScript.document.querySelectorAll(".button")
won’t work. - Using Sass’s
@extend
feature, though not as bad as@mixins
, will still add size to your generated CSS, especially the selector count. This can be a big problem if you’re approaching the 4095 selectors limit for IE 6-9 (yes, even IE9). - Using
@extend
on selectors of a different specificity level than the class selectors you’re extending can cause unintended consequences. It’s important to keep in mind that a selector like#aside > nav
that extends.col-3
will still have the specificity weight of that ID and that can cause conflicts. If your components are defined with a low specificity, using them in high specificity contexts might not always work.
For the more curious, I recently wrote a detailed examination of the issues surrounding OOCSS and Sass’s @extend
feature.
Summary
Presentational classes, when used appropriately, can be a great assets to any web developer’s tool belt. They allow for style reuse across any number of projects and can better communicate intention to other developers on a team.
As long as you properly understand the downsides of mixing markup and presentation, such class names need not be avoided at all costs. An appropriate separation of style and content can be achieved in other ways.
Most of all, the important thing is to examine and measure your own productivity. You should use whatever class names make your life easier. If presentational classes cause problems, don’t use them. If you find them helpful, don’t worry so much about it.
Finally someone said this! I hate when people start treating different types of class names as ‘bad practice’ while they never work with huge website redesigns or web apps!
Sorry that I disagree, but in the era of responsive designs, having class col-3 doesn’t really make any sense… because because of the lack of space you style your col-3 now as a row instead of as a col…
It is not that bad, but learning a preprocessor is not a bad idea at all. You should consider it instead of having a hell of classnames in the html.
Roy, you are out of your element here… do you know what col-3 even means in terms of these frontend frameworks? If you did, you would realize your argument makes no sense. This is related to a grid system, not simply a 3 column layout. Please read up on the topic before you comment and share opinions built on assumptions.
Finally !
An article by someone who makes websites, real websites, and not theorycraft and “tricks” by one which never did a decent website. Never seen ONE redesign keeping the HTML. True separation is a myth in webdev, an ideal to strive for.
Best article on codrops ever.
Designers arguing against css names should stfu and optimize their stupid selectors before talking about names.
Glad you came out and said this! After all, class names -apart from micro-formats, etc.- have no inherent semantic value.
Let’s keep our HTML semantic and our class names maintainable.
I know that in a big project, having a bunch of classes o selectors just doesn’t do no more, specially when they are elements similar on to another. BUT, HTML is for markup and content while CSS is for style, the correct thing to do is NOT MIX THEM.
So… you have a col-3 class on div element.. it doesn’t say what the content is, it doesn’t help for semantics and if you need to change the style of that element you change the HTML so now has a col-4 class. I’m sorry but WTF!? you are changing THE HTML to make CSS changes, that is WRONG! Now it get’s worse when you don’t remember how many units is the col-4 width, and you have to go to the .css file, search the selector, see what’s it’s value to be sure if you need that class or col-5 instead, wth? just search for you semantic selector and you change to whatever value you want, 1, 3, 1000px; 4 ems, 50% whatever!
I understand that it’s sometimes easier to use presentational classes; but I think it’s wrong, if you need to change the appearance of an element you should only touch a .css file.
The best aproach in my opinion is using OOCSS (Object Oriented CSS) http://coding.smashingmagazine.com/2011/12/12/an-introduction-to-object-oriented-css-oocss/ and things like the media object http://www.stubbornella.org/content/2010/06/25/the-media-object-saves-hundreds-of-lines-of-code/
now I want to see a Framework using OOCSS instead a bunch of .col-3 .push_bottom selectors, that would be great.
Doesn’t OOCSS promote using presentational class names? In the first example given (in the Smashing article you shared), it talks about extracting theme-like styles and putting them into a presentational class called “skin”. Unlike “button”, “box”, or “widget”, “skin” has zero semantic markup as far as the HTML is concerned. It is a presentational class.
I like the SMACCS approach, which definitely uses presentational class names and is very familiar (or a type of) OOCSS.
I thought the point of CSS was to define style and not to define my HTML.content? “Semantics” is the meaning, or an interpretation of the meaning, of a word, sign, sentence, etc. If I’m using a grid framework I know exactly what col-3 means as defined by that framework. Now say there are 3 columns each with an article with a class “newsitem” for instance. I now have to find a way to define styles for 3 generic blocks with essentially the same HTML code. How do I target the one I need?
Who says you should ONLY change a CSS file? In this case if I need to change the layout what’s easier, changing the class on the HTML element or coming up with new CSS in the stylesheet for each class (or worse if I’m doing it “semantically”–having to rearrange a bunch of CSS selectors when I already have a class that defines the style I need. II’m not advocating color and font classes but all semantics all the time just for semantics’ sake is just as ridiculous.
By that logic, changing a header from H3 to H4 to change its style is also wrong. Which I think we all would agree is complete nonsense.
Going by what you say, if we had two headings we could end up with H2 being bigger than H1 and taking visual weight. Which of course semantically is clearly wrong. But you say styling changes can only be made using the CSS…
Sorry, but that is just nonsensical, and horribly bad practise.
Great article, I love that you’ve argued both sides and seem to advocate being flexible in the approach to class naming. It’s easy to make up best practice rules with language like never and always… but in practice, especially on a large scale or complex design you’ll always end up making exceptions.
I must have spent hours discussing what to name a few tricky classes without describing their appearance, before finally coming to the realisation that in some cases it can be an extremely difficult task with no real benefit. In my understanding, the whole point of semantic class naming is to make your code more readable; to make things easier when you come back and work on it a month after you’re done, or when a new dev comes onto the project. If you’ve had to resort to some vague but presentation agnostic name because the element had a purely presentational purpose, you’ve actually made it harder to associate this class with the element(s) it’s applied to, not easier. So you’ve spent longer coming up with something less readable.
I think a consideration of responsive design would have rounded off the argument – if the same markup can concurrently be presented in different ways on different devices, that’s where appearance-specific classes can start to get misleading. The same element might be one column of three on the desktop layout, and also a single column on a mobile device. Col-3 might work in one case but be wrong in another. In a RWD approach you don’t get the opportunity to re-work the HTML to suit the new design, because you’re not getting rid of the old one. To re-state the point I think you’ve already made, this is where flexibility, and applying common sense to a situation instead of blindly adhering to one dogma, becomes really important.
This kind of judgement call is why our industry takes both an analytical and a creative mind all rolled into one. I think when we try to bend every task to fit into the best practices we’ve learned – instead of taking every situation on its own merits – we’re kind of cutting ourselves off from something important: our ability to think critically.
I’m not saying we should just be bashing code together until it works, but we need to weigh all the different opinions of best practice together and come up with a compromise that suits a given situation.
Excellent read, and an interesting outlook on using good practices to write clean and reusable CSS. I never would’ve known that IE9 (and older) had a selector limit! Something to keep in mind when working on really large projects, I suppose. Thanks for the good read, Philip 🙂
Excellent! Finally someone else (and apparently a few others here) who I think can think for themselves! Ben Flanagan said something very good:
It is not that bad, but learning a preprocessor is not a bad idea at all. You should consider it instead of having a hell of classnames in the html.
I am just as surprised to learn that IE9 and others had a selector limit, nonetheless best practice rules are always the way to go imho….
I guess I’ve always considered semantics from the users point of view and not mine as the developer. By that I mean, I’ve always considered how someone that can’t view my site will hear it. Class names like .address or .name or .date (overly simplified for illustration purposes) will mean more to someone using a screen reader than .span-6 or most other presentational classes.
That said, certain presentational classes like .button may prove useful to those listening. I just haven’t run into a situation yet that forced me to not use semantic class names. Full disclosure here, I haven’t worked in the development of large sites with multiple developer but after read this article I can see how presentational classes can be helpful in that situation.
Now I know truly semantic classes go unnoticed by most users and that in itself could be an argument for presentational all on its own. But if we are trying to achieve universal sharing of content then isn’t semantics, markup and class names, an important step in that directions. While it’s true that semantic class names have no intrinsic meaning to the screen readers themselves, they certainly will to the person listening to the screen reader.
The definition of semantic is “Of or relating to meaning, especially meaning in language.” according to The Free Dictionary. So if semantics were meant to make developers lives easier the presentational classes would be fine. If on the other hand it was meant to improve understanding of content by the users then presentational classes leave something to be desired.
I guess my question then is, who were semantics envisioned to help? Developers or users?
Brian, apparently Roy doesn’t share the same native language as you and I (which I’m sure must be frustrating when discussing such a complex subject). However, I believe he is referring to the ability that preprocessors give to developers to avoid declarative classes in markup by using mixins to style the grid from within the stylesheet (as is clearly outlined in the documentation on the Foundation website. Once you’ve read this documentation (I assume, for the second or third time as you were quick to point out the failing of others to do so) I’m sure you’ll better grasp the concept of how css preprocessors can reduce the dependence on declarative classes (if not remove the need for them entirely) and allow for more semantic markup.
Probably just a simple oversite on your part. I’m sure Roy is as eager to accept your apology (the one I’m sure that you are most willing to extend) as you are to tell your colleagues in the web development community about the valuable lesson you’ve learned about declarative classes and the power of css preprocessors. Good Luck!
I completely agree with this article. It’s a guideline and not gospel. With that said, I noticed the reference to Foundation. Foundation originally used presentation classes in v2 and v3, but have now transitioned to moving this to the CSS using Sass and Mixins in v4. While I agree with the article, if your framework allows you to remove the presentation classes from the html, it’s even better!
what happened if after completion of final work you compressed that CSS ?
Does really name of css classname matters when you don’t think about redesigning??