From our monthly sponsor: monday.com, a new way to manage your work! Meet the new visual project management tool.
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
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
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:
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.
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.
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.
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
- 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 .buttoninside a selector like
form input[type=submit], now you lose the ability to select all
- Using Sass’s
@extendfeature, 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).
@extendon 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 > navthat extends
.col-3will 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
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.