About HTML semantics and front-end architecture

A collection of thoughts, experiences, ideas that I like, and ideas that I have been experimenting with over the last year. It covers HTML semantics, components and approaches to front-end architecture, class naming patterns, and HTTP compression.

We shall not cease from exploration
And the end of all our exploring
Will be to arrive where we started
And know the place for the first time.

T.S. Eliot — “Little Gidding”

About semantics

Semantics is the study of the relationships between signs and symbols and what they represent. In linguistics, this is primarily the study of the meaning of signs (such as words, phrases, or sounds) in language. In the context of front-end web development, semantics are largely concerned with the agreed meaning of HTML elements, attributes, and attribute values (including extensions like Microdata). These agreed semantics, which are usually formalised in specifications, can be used to help programmes (and subsequently humans) better understand aspects of the information on a website. However, even after formalisation, the semantics of elements, attributes, and attribute values are subject to adaptation and co-option by developers. This can lead to subsequent modifications of the formally agreed semantics (and is an HTML design principle).

Distinguishing between different types of HTML semantics

The principle of writing “semantic HTML” is one of the foundations of modern, professional front-end development. Most semantics are related to aspects of the nature of the existing or expected content (e.g. h1 element, lang attribute, email value of the type attribute, Microdata).

However, not all semantics need to be content-derived. Class names cannot be “unsemantic”. Whatever names are being used: they have meaning, they have purpose. Class name semantics can be different to those of HTML elements. We can leverage the agreed “global” semantics of HTML elements, certain HTML attributes, Microdata, etc., without confusing their purpose with those of the “local” website/application-specific semantics that are usually contained in the values of attributes like the class attribute.

Despite the HTML5 specification section on classes repeating the assumed “best practice” that…

…authors are encouraged to use [class attribute] values that describe the nature of the content, rather than values that describe the desired presentation of the content.

…there is no inherent reason to do this. In fact, it’s often a hindrance when working on large websites or applications.

  • Content-layer semantics are already served by HTML elements and other attributes.
  • Class names impart little or no useful semantic information to machines or human visitors unless it is part of a small set of agreed upon (and machine readable) names – Microformats.
  • The primary purpose of a class name is to be a hook for CSS and JavaScript. If you don’t need to add presentation and behaviour to your web documents, then you probably don’t need classes in your HTML.
  • Class names should communicate useful information to developers. It’s helpful to understand what a specific class name is going to do when you read a DOM snippet, especially in multi-developer teams where front-enders won’t be the only people working with HTML components.

Take this very simple example:

<div class="news">
    <h2>News</h2>
    [news content]
</div>

The class name news doesn’t tell you anything that is not already obvious from the content. It gives you no information about the architectural structure of the component, and it cannot be used with content that isn’t “news”. Tying your class name semantics tightly to the nature of the content has already reduced the ability of your architecture to scale or be easily put to use by other developers.

Content-independent class names

An alternative is to derive class name semantics from repeating structural and functional patterns in a design. The most reusable components are those with class names that are independent of the content.

We shouldn’t be afraid of making the connections between layers clear and explicit rather than having class names rigidly reflect specific content. Doing this doesn’t make classes “unsemantic”, it just means that their semantics are not derived from the content. We shouldn’t be afraid to include additional HTML elements if they help create more robust, flexible, and reusable components. Doing so does not make the HTML “unsemantic”, it just means that you use elements beyond the bare minimum needed to markup the content.

Front-end architecture

The aim of a component/template/object-oriented architecture is to be able to develop a limited number of reusable components that can contain a range of different content types. The important thing for class name semantics in non-trivial applications is that they be driven by pragmatism and best serve their primary purpose – providing meaningful, flexible, and reusable presentational/behavioural hooks for developers to use.

Reusable and combinable components

Scalable HTML/CSS must, by and large, rely on classes within the HTML to allow for the creation of reusable components. A flexible and reusable component is one which neither relies on existing within a certain part of the DOM tree, nor requires the use of specific element types. It should be able to adapt to different containers and be easily themed. If necessary, extra HTML elements (beyond those needed just to markup the content) and can be used to make the component more robust. A good example is what Nicole Sullivan calls the media object.

Components that can be easily combined benefit from the avoidance of type selectors in favour of classes. The following example prevents the easy combination of the btn component with the uilist component. The problems are that the specificity of .btn is less than that of .uilist a (which will override any shared properties), and the uilist component requires anchors as child nodes.

.btn { /* styles */ }
.uilist { /* styles */ }
.uilist a { /* styles */ }
<nav class="uilist">
    <a href="#">Home</a>
    <a href="#">About</a>
    <a class="btn" href="#">Login</a>
</nav>

An approach that improves the ease with which you can combine other components with uilist is to use classes to style the child DOM elements. Although this helps to reduce the specificity of the rule, the main benefit is that it gives you the option to apply the structural styles to any type of child node.

.btn { /* styles */ }
.uilist { /* styles */ }
.uilist-item { /* styles */ }
<nav class="uilist">
    <a class="uilist-item" href="#">Home</a>
    <a class="uilist-item" href="#">About</a>
    <span class="uilist-item">
        <a class="btn" href="#">Login</a>
    </span>
</nav>

JavaScript-specific classes

Using some form of JavaScript-specific classes can help to reduce the risk that thematic or structural changes to components will break any JavaScript that is also applied. An approach that I’ve found helpful is to use certain classes only for JavaScript hooks – js-* – and not to hang any presentation off them.

<a href="/login" class="btn btn-primary js-login"></a>

This way, you can reduce the chance that changing the structure or theme of components will inadvertently affect any required JavaScript behaviour and complex functionality.

Component modifiers

Components often have variants with slightly different presentations from the base component, e.g., a different coloured background or border. There are two mains patterns used to create these component variants. I’m going to call them the “single-class” and “multi-class” patterns.

The “single-class” pattern

.btn, .btn-primary { /* button template styles */ }
.btn-primary { /* styles specific to save button */ }

<button class="btn">Default</button>
<button class="btn-primary">Login</button>

The “multi-class” pattern

.btn { /* button template styles */ }
.btn-primary { /* styles specific to primary button */ }

<button class="btn">Default</button>
<button class="btn btn-primary">Login</button>

If you use a pre-processor, you might use Sass’s @extend functionality to reduce some of the maintenance work involved in using the “single-class” pattern. However, even with the help of a pre-processor, my preference is to use the “multi-class” pattern and add modifier classes in the HTML.

I’ve found it to be a more scalable pattern. For example, take the base btn component and add a further 5 types of button and 3 additional sizes. Using a “multi-class” pattern you end up with 9 classes that can be mixed-and-matched. Using a “single-class” pattern you end up with 24 classes.

It is also easier to make contextual tweaks to a component, if absolutely necessary. You might want to make small adjustments to any btn that appears within another component.

/* "multi-class" adjustment */
.thing .btn { /* adjustments */ }

/* "single-class" adjustment */
.thing .btn,
.thing .btn-primary,
.thing .btn-danger,
.thing .btn-etc { /* adjustments */ }

A “multi-class” pattern means you only need a single intra-component selector to target any type of btn-styled element within the component. A “single-class” pattern would mean that you may have to account for any possible button type, and adjust the selector whenever a new button variant is created.

Structured class names

When creating components – and “themes” that build upon them – some classes are used as component boundaries, some are used as component modifiers, and others are used to associate a collection of DOM nodes into a larger abstract presentational component.

It’s hard to deduce the relationship between btn (component), btn-primary (modifier), btn-group (component), and btn-group-item (component sub-object) because the names don’t clearly surface the purpose of the class. There is no consistent pattern.

In early 2011, I started experimenting with naming patterns that help me to more quickly understand the presentational relationship between nodes in a DOM snippet, rather than trying to piece together the site’s architecture by switching back-and-forth between HTML, CSS, and JS files. The notation in the gist is primarily influenced by the BEM system’s approach to naming, but adapted into a form that I found easier to scan.

Since I first wrote this post, several other teams and frameworks have adopted this approach. MontageJS modified the notation into a different style, which I prefer and currently use in the SUIT toolkit:

/* Utility */
.u-utilityName {}

/* State-utility */
.u-isStateName {}

/* Component */
.ComponentName {}

/* Component modifier */
.ComponentName--modifierName {}

/* Component descendant */
.ComponentName-descendant {}

/* Component descendant modifier */
.ComponentName-descendant--modifierName {}

/* Component state (scoped to component) */
.ComponentName.is-stateOfComponent {}

/* Component mixin (ancestor style dependencies) */
.with-ComponentName {}

This is merely a naming pattern that I’m finding helpful at the moment. It could take any form. But the benefit lies in removing the ambiguity of class names that rely only on (single) hyphens, or underscores, or camel case.

A note on raw file size and HTTP compression

Related to any discussion about modular/scalable CSS is a concern about file size and “bloat”. Nicole Sullivan’s talks often mention the file size savings (as well as maintenance improvements) that companies like Facebook experienced when adopting this kind of approach. Further to that, I thought I’d share my anecdotes about the effects of HTTP compression on pre-processor output and the extensive use of HTML classes.

When Twitter Bootstrap first came out, I rewrote the compiled CSS to better reflect how I would author it by hand and to compare the file sizes. After minifying both files, the hand-crafted CSS was about 10% smaller than the pre-processor output. But when both files were also gzipped, the pre-processor output was about 5% smaller than the hand-crafted CSS.

This highlights how important it is to compare the size of files after HTTP compression, because minified file sizes do not tell the whole story. It suggests that experienced CSS developers using pre-processors don’t need to be overly concerned about a certain degree of repetition in the compiled CSS because it can lend itself well to smaller file sizes after HTTP compression. The benefits of more maintainable “CSS” code via pre-processors should trump concerns about the aesthetics or size of the raw and minified output CSS.

In another experiment, I removed every class attribute from a 60KB HTML file pulled from a live site (already made up of many reusable components). Doing this reduced the file size to 25KB. When the original and stripped files were gzipped, their sizes were 7.6KB and 6KB respectively – a difference of 1.6KB. The actual file size consequences of liberal class use are rarely going to be worth stressing over.

How I learned to stop worrying…

The experience of many skilled developers, over many years, has led to a shift in how large-scale website and applications are developed. Despite this, for individuals weaned on an ideology where “semantic HTML” means using content-derived class names (and even then, only as a last resort), it usually requires you to work on a large application before you can become acutely aware of the impractical nature of that approach. You have to be prepared to disgard old ideas, look at alternatives, and even revisit ways that you may have previously dismissed.

Once you start writing non-trivial websites and applications that you and others must not only maintain but actively iterate upon, you quickly realise that despite your best efforts, your code starts to get harder and harder to maintain. It’s well worth taking the time to explore the work of some people who have proposed their own approaches to tackling these problems: Nicole’s blog and Object Oriented CSS project, Jonathan Snook’s Scalable Modular Architecture CSS, and the Block Element Modifier method that Yandex have developed.

When you choose to author HTML and CSS in a way that seeks to reduce the amount of time you spend writing and editing CSS, it involves accepting that you must instead spend more time changing HTML classes on elements if you want to change their styles. This turns out to be fairly practical, both for front-end and back-end developers – anyone can rearrange pre-built “lego blocks”; it turns out that no one can perform CSS-alchemy.

Translations

Reply on Twitter Retweet on Twitter Favorite on Twitter

33 comments

#

Matt Wiebe says…

Great stuff here Nicolas. You’ve helped me crystallize some nascent thoughts along these lines into something much more coherent.

#

Danny says…

Your posts are always throwing me curveballs Nic

#

Jeff Escalante says…

I almost agree with this, but I do not think that we need to use numerous html classes to achieve the flexibility and clarity that we want. When we’re talking about modern front-end code, we have the advantage of being able to use html5 and stylesheet preprocessors, and I think we can use this to clean up the html and make it more semantic, push back the style information to the css where it belongs, and organize the css much more cleanly so that it can be read almost as easily as the equally clean html.

For me, it’s about using classes/ids to mark of large content sections, and within the preprocessed css, nesting styles within those larger blocks as the top level of orgaization. As for reusable code, it’s all about mixins. Mixins are the replacement for classes – they hold blocks of styles, but offer two large advantages – the keep your html clean, they are where they belong (blocks of style in your stylesheets), and they can take parameters and contain logic, making them tons more flexible than classes. If you write a certain way, you can end up with slightly more css code in production using mixins, but that’s more than made up for by the additional clarity and flexibility that they afford (and the fact that css renders super quickly, and if you’re geeking out on performance, you can just write the selectors such that they do mirror classes).

I’d love to know what your thoughts are on this. I’ve written a few articles about it that have fairly high detail and directly oppose things like OOCSS, but they have mostly slid under the radar (ex. http://carrotblog.com/css-patterns-evolved/). I’m also authoring a css framework based on these principles, and although still very much alpha, in the places I’ve tested it, it has been extremely effective.

#

Dade says…

I’ve been doing some of this stuff for about a year, but this certainly gives me a lot better idea on how to keep things more flexible and scalable. Thanks for such an in-depth look at this, it is really good stuff.

#

Sam says…

Instead of using js specific classnames (like js-login), why not use data attributes? They’re a lot more extensible and they help reinforce the distinction between content, structure, layout and functionality.

We’re also experimenting with replacing classnames with data attributes to drive our responsive grid system. data-colspan="2" is a lot clearer than class="news-header colspan-2".

#

Brett Jankord says…

Great read, thanks Nicolas. I really like the idea of creating content-independent class names. I know a lot of people are looking at OOCSS lately and figuring out how they can use it on their own projects. Steven Bradley has posted some great articles on his thoughts about the technique.

I’m curious if you have any thoughts on Jeremy Clarke’s DRY CSS presentation and it’s merits compared to OOCSS, SMACSS, and BEM? http://tinyurl.com/7fkc5vo

#

Patrick Hamann says…

Great article Nicolas, and a subject that I too have been experimenting with over the last year (which I naturally arrived at after starting to work on large scale projects).

We’ve started to implement Snook’s SMACSS naming convention methodology at work and are already seeing the benefits not only scalability of modules but most importantly easy to read and maintain code across the team. (We also prefer a multi-class pattern over single).

But the true gem in the article is your research on gzipping compression and pre-processors, and will point anybody who raises the arguments against processors in this direction instantly.

Thank you for sharing your thoughts!

#

Christof says…

Great post! I noticed naming is actually the hardest problem and actually debated with colleagues for some minutes if not hours a proper (class) name…

Only problem with multiple classnames: If you cannot control the HTML the way you’d like to e.g. when working in/with/against certain CMS or have to deal with ignorant “backend” people who think they know HTML :(

#

doug says…

another tactic is to ‘reserve’ base class names by creating styles that are always selector spaced. i’ve found this quite effective, although it is a ‘convention’ thing.

to wit:

.item {}  // abstract definition

#cart .item {
  // styles
}

#category .item {
  // styles
}

#product .item {
  // styles
}

there is no “one solution” — the frontend structure and semantics vary depending on what you’re building. a web email client has very different needs than an ecommerce store, and you’ll see that reflected in the markup and css.

#

Artem Sapegin says…

Great article Nicolas!

I recently end up with almost the same naming conventions including is-states and js-hooks. The only exceptions that I use original BEM modifiers (because we use them at work and they look quite familiar for me) and I sometimes use cascade with semantic tag names inside blocks (.block h1, .block p).

#

Kaelig says…

Your post sums up in a few words a good part of the 300 pages of my book. Congrats.

Happy to see that more and more front-end developers are jumping on the OOCSS pragmatic wagon.

#

Larry Botha says…

Great post! I’ve been fiddling with the multi-class selection method on a recent project in such a way that the ‘defining’ class is not required.

i.e. I don’t use a .btn on the element, I’ll rather use .btn-primary immediately, where a universal selector styles all elements that contain a class of btn:

[class*="btn-"] {
  /* define default styles that apply to all buttons here */
}

.btn-small { /* styles for small button */}
.btn-medium { /* styles for medium button - may instead be defaults of universal */}
.btn-large { /* styles for large button */}

.btn-primary { background-color: grey;}
.btn-secondary { background-color: green;}

.btn-left {
  /* something on the left of this button */
}

.btn-right {
  /* something on the right of this button */
}

I know universals are generally frowned upon, but I’m not sure as to whether the actual penalty is significant when compared to the manageability they can provide.

#

Spoike says…

You might what to mention that the reason devs used the “single class pattern” was that some legacy browsers didn’t support multiple classes properly (such as IE6). Though I assume that this is hardly an issue anymore.

#

Jacob Rask says…

Excellent. Do your modifiers really need prefixes though? How about:

.btn { /* ... */ }
.btn.primary { /* ... */ }
.btn-group { /* ... */

If you’re fairly disciplined classes in your “global scope” will be confined to your modules anyway.

#

Tom says…

Completely agree with you Nicolas. This is exactly what we have found while making the BBC responsive news website.

#

Nicolas says…

@Sam said:

Instead of using js specific classnames (like js-login), why not use data attributes?

I’ve experimented with that approach too. At the moment, I leave data-* attributes for data that is needed in JS functions rather than as the hook itself. But that could change if I read compelling arguments otherwise – the clear separation between CSS and JS does seem appealing. What are the performance differences like?

@Artem Sapegin said:

I sometimes use cascade with semantic tag names inside blocks (.block h1, .block p).

Yeah, me too. Sometimes a component heading needs to be adjusted for the component, whatever level it is. I don’t always get the balance right and sometimes I have to refactor things (like the nav example) when I realise a component isn’t going to play well with others.

@Larry Botha said:

I don’t use a .btn on the element, I’ll rather use .btn-primary immediately, where a universal selector styles all elements that contain a class of btn

Twitter Bootstrap also makes use of that approach. My concern with it is that you have to make sure that the substring you choose to match will never unintentionally appear in another class, e.g., btn-group.

@Jacob Rask said:

Do your modifiers really need prefixes though?

I find it to be a bit “safer” than chaining classes together. It doesn’t rely on a team of developers to know how certain classes have different effects on different objects, and it can protect you from what external sources of code are doing.

Twitter Bootstrap used to chain classes but went on to abandon that approach in favour of “namespaced” classes in 2.0. Mark and Jacob might be able to give additional reasons for why they made the switch.

#

Morgan Craft says…

Nic, great write up. I’ve employed similar namespacing patterns for js-hooks and also as a means to namespace jsTemplates using mustache/icanhazjs.

To the posters talking about using the data-* I recommend against this as a best-practice. One should not treat the DOM as a data-storage layer, reads and writes should be avoided. With that said, I’ve certainly in the past used data-* values. But as I’m experimenting with backbonejs I’ve realized this can be avoided as html-elements are associated with a model that may contain the necessary data points.

#

DS says…

Good post, the reusable component based aproach in web sites is a very important thing. Especially if you build large scale web apps. In our company we go with the namespaced approach for layout speciic rules and class chaining for stateful components.

#

Seth BRo says…

Fantastic article. The way you distill so many advanced best practices into general principles is inspiring.

I’m with Jeff Escalante in it’s all about the mixins. Embracing Sass is the best thing I’ve done in my front end career. It allows us to truly use the cascade, as well as apply common presentation rules to a variety of classes without repetition or a reliance on the extended naming conventions you lean towards here.

The framework I’ve adopted breaks stylesheets into small partials focused by area of concern–colors, typography, grid, layout, forms, messaging, etc. Each of these contain a few variables & mixins for the cause, sets rules for base elements and/or establish broad, purposeful class names.

As Jeff mentions, css for specific pages of your site is then a matter of variation within limits–tweaking position & whatnot by targeting a parent container (I dynamically set a class on the body based on the name of the Rails controller, which allows dramatic change if needed).

I’m also a fan of data attributes as hooks for JS behaviors. I favor a single attr that informs scripts which objects to instantiate (e.g. data-behavior="InlineValidator"). This prevents naming conflicts & opens other attrs to carry data for said behaviors.

#

Chris Heilmann says…

Great stuff. A few things that popped into my head though whilst reading through it:

* The ‘news’ example only seems redundant. If you are using a site that it localised to other languages having a “news” in the class above a “Neuigkeiten” in the header makes it easier for a maintainer to understand what is going on.

* It feels wrong to me to have a NAV element and no list inside, but instead just links or spans as list-items via a class. We have an HTML element for that, called an LI which allows for fallback and gives you more elements to play with in your styling. Of course list-item as a class gives you independence of the DOM depth but it seems a lot of extra code for me when a nav list could be the reusable component. I am not disagreeing with the concept at all – I just get a icky feeling from the example of simulating a list and making it CSS dependent.

* The next step with all of this is now to work with frameworks, CMS and other systems to stop adding random code we can’t control of course. Let’s not assume that all people out there write everything by hand.

#

Rob Wierzbowski says…

Very much appreciate the article, Nicolas. It’s really helpful to see how other people (especially those working on large scale projects) are combining ideas from Smacss, OOCSS, and other css style guides.

Something I’ve noticed is that, if viewed separately, it can seem that smaller projects don’t require a modular, reusable html and css pattern like we’re discussing here (and the simpler html and css may weigh in with a few less kbs). But, when you look at multiple projects across a business as a single system, you start to see something approaching the complexity of a Yahoo Mail or Twitter, and the benefits to maintenance and development time become obvious.

#

Zachary Johnson says…

I think you’ve done a good job documenting some very important ideas. I do not however think it is necessary to tear down the current understanding of semantics in order to make these points. I think instead our current or perhaps old ideas of semantics are sufficiently flexible to include these new patterns.

For example, <div class="btn-primary"> is clearly a better use of class names than <div class="red round-corners">. By arguing that “class name cannot be ‘unsemantic’” you create an opening for people to believe that any class name is equally as good as the next. I think we instead need to build on our old understanding of what is and isn’t a semantic class name. And if you do actually want to argue that we cannot call “red round-corners” unsemantic, then we need to come up with a new term to describe that anti-pattern.

Similarly, I do not think it is necessary to throw away the HTML5 spec best practice about choosing class names. That advice is a helpful starting point, and I think the concept is suitably adaptable to be inclusive of the ideas in your article. The best practice you quote from the spec does not exclude class names like "btn-primary". Why can’t “button” be a description of the nature of the content? I agree with you that this class name is semantic in that it is derived from “structural and functional patterns”. A button is far from a purely presentational concept. Close your ideas and picture the endless possible presentations of a button.

I think you are actually very much arguing FOR the best practice in the HTML5 spec despite your assertion that it is a hinderance. Allow your understanding of these old concepts to be less rigid and more inclusive. In this case, I don’t think the old and the new are mutually exclusive of each other.

I’ve been using these techniques from your article for years now, sometimes alongside older non-component semantic classes, and I’ve not had trouble integrating both ideas into my understanding of semantics.

#

Nicolas says…

@Seth BRo said:

…it’s all about the mixins

I like working with Sass, and pre-processor mixins have their uses, but it doesn’t affect the way that HTML and CSS interact. In the end, you and the rest of the team still have to write HTML and that is where the classes really live.

@Chris Heilmann said:

It feels wrong to me to have a NAV element and no list inside…it seems a lot of extra code for me when a nav list could be the reusable component.

There’s nothing prohibiting the omission of a list within nav :). Even if I had included the extra list markup in the example, the point would have remained. The .uilist a selector still has greater specificity and any navigation link styles would affect a .btn-style link that you wanted to include. You’re still left having to consider using extra classes if you want to use one component within the other. If there’s a smarter and simpler way to solve the problem, I’d love to try it out.

@Zachary Johnson said:

I do not however think it is necessary to tear down the current understanding of semantics in order to make these points…By arguing that “class name cannot be ‘unsemantic’” you create an opening for people to believe that any class name is equally as good as the next…Similarly, I do not think it is necessary to throw away the HTML5 spec best practice about choosing class names

I’m not tearing down, throwing away, or redefining anyway. Nor do I suggest that any class name is as good as the next. The point I made was that not all class names are equal. Class names derived from content tend to be less reusable than those that reflect structure or presentation. That doesn’t mean that none of your class names should be content-derived, just that there is a benefit from abstracting reusable patterns into different class names. The examples using btn aren’t even in the same section of the post as the discussion about content-independent classes.

Within a single app not every class is expected to work in the same way, exist at the same level of abstraction from the content, or allow for the same degree of stylistic flexibility.

#

Karl says…

Really great article Nicolas. An important subject, and one that’s often given far too little attention.

#

Kevin Barr says…

Thanks for posting your thoughts, Nicolas. I’ve been working with reusable class names and continue to modify and refine my process. Your suggestion of using classes on sub-objects is new to me, but it seems like a brilliant idea and will address some problems I encounter with nested styles. Also like to idea of using js specific class names (or even data attributes as Sam suggested).

#

Manjari Shukla says…

I love your article …… it is very informative and thanks for explaining about HTML semantics and front-end architecture in a very easiest way. I easily understood and I am using it after reading.​​​​​​

#

Niels Matthijs says…

While this is a very strong article with strong argumentation, I do not agree at all with what is being said.

In short, use oohtml instead of oocss and take care of the oocss part using mixins. Works just the same, but comes with the additional benefit that the html is cleaner, more robust, easier to predict and easier to implement.

The long version: http://www.onderhond.com/blog/work/oocss-bad-oohtml

#

Nicolas says…

@Niels Matthijs: Hi, thanks for blogging your thoughts and sharing them here. I’m afraid that I’m not convinced by your arguments – dramatic as the title is :)

Microdata can be used for styling…

That would only further increase the tight coupling between your content and styles. Classes have always been used for CSS and JS hooks. This isn’t something unique to component-based approaches.

…obviously we haven’t been preaching the semantic use of class names just because we thought I’d be a fun thing to do.

What people have been preaching as “semantic class names” are names that reflect the content rather than their purpose. I think semantic class names are important, just not only the type of semantics that are purely content derived.

Contrary to your claims, the cascade is going to be an important part of any CSS methodology.

Probably worse is the strain oocss puts on back-end implementation…If there is a difference in style between two components, this means the component needs a different html output.

Of course. It seems to me that this will be the case with the vast majority of methods…unless you only want to rely on pseudo-classes and a known, fixed DOM structure.

It’s nice to have preferences, but I’m pretty interested to hear exactly why he prefers the oocss way.

I gave my reasons in the article. Furthermore, I don’t see mixins as an equivalent solution that “works the same” because they require you to regularly forge new CSS rules to hook into parts of the HTML. You cannot build larger templates from existing components.

You mentioned that these sorts of approaches are a “faux best practice”. I think they are more the result of pragmatism by developers in situations where it has proven beneficial. However, labelling something a “best practice” only seems to make it harder to move on in the future. Maybe we can just focus on finding effective, pragmatic solutions to existing problems and not getting too hung up about deciding which is “the one true way”, since everything changes so fast.

#

Niels Matthijs says…

I’m still not sure how you think mixins are different? You could define the same classes you use with oocss, only instead of directly hooking them into your html, you use existing elements to mix and match? Mixins just save you a lot of html trouble.

.mixin1 {...}
.mixin2 {....}

.news {.mixin1; .mixin2;}

I do get where we differ in opinion though. I’m not a big fan of pragmatic solutions to existing problems without considering their effect on the future. In the past it’s these kind of methods that linger long after they are needed and needlessly mess things up. You know, developing for ie6 only was once considered a very pragmatic and problem-driven solution ;)

I’m a fan of fixed html structures. A news item is a news item. The html for a news item should be the same throughout the entire site (/all your projects). If there are different views, you use classes that extend your newsitem (.news.overview, .news.detail, .news.minimal). Further identification is done based on immediate context (fe. aside) or page template (fe body.leaf).

That gives you all the hooks you need for styling. If you want to reuse skins for different logical components, just define mixins like you define your oocss classes.

#

Jakob Hilden says…

This is a super awesome article Nicolas. Thank you!

I’m with you on the OOCSS/SMACSS vs OOHTML argument. I think modular CSS provides a much better translation/connection between markup and stylesheet and it allows to to develop and test modules individually but with a great certainty, that they will also work in other contexts.

I have described SMACSS as as something like “data modeling from the other side” (from the visual/structural side), while OOHTML would be more like trying to take the classic content-driven backend data modeling one step further.

I have touched upon some very similar topics in my blog post about SMACSS and SASS: http://blog.railslove.com/2012/03/28/smacss-and-sass-the-future-of-stylesheets

Also, there is one little thing I wanted to point out about your differentiation between single- and multi-class component modifiers.

You are saying that it would be “easier to make component-level tweaks to an object”, such as .thing .btn { /* adjustments */ }. But actually if you are using SASS’s @extend feature, the selector of the extending class (here .btn-primary) will be added anywhere(!) the extended class (here .btn) appears. Many SASS users are not aware of that and it can also produce some unexpected surprises, but here the result is that it makes it just as easy to tweak an object in the single- vs. the multi-class pattern.

I put together a little working code example for this case here: http://voyage-editor.herokuapp.com/users/4f74c278326da50001000009/scripts/sass–at-extend-single-class

#

Andreas says…

Good job Nicolas. These are the same issues we always discuss in our company. Because developers use a different naming convention than designers. Developers always use their class names for styling and for script action selectors. the idea of giving a prefix like js-* is really a great idea of making html more flexible. So, we should have class names just given for jscript actions, and others just given for styling purpose! And mixin’s are really cool, too. Did not know that you could mix up existing classes and styles into another one. This could be really usefull if you have same styled articles (h1, p) embedded on different places. An article placed on the Startpage would look different than maybe an article in the Sidebar. They need the same overall structure and style (color, font, etc) but maybe different margins and paddings for example. so we could use our article class, but mix it with the sidebar margin class, to get the same style with different layout!

Perfect… I will get more deep into it! really nice starting point here, to get some more ideas, you should try and get better and better, from project to project!

Thank you Nicolas, and all the commentators of this article!

Well done!

#

guvenlik sistemleri says…

Thank you Nicolas, important subject, and one that’s often given far too little attention.

#

Yelena Jetpyspayeva says…

Hi Nicolas,

Thanks for talking & writing about BEM, that was encouraging and yet surprising for the whole team of us!

Wish the video of your talk will be available soon

Sincerely,

Yelena

Comment on this post

Please wrap code fragments in <code> tags, wrap blocks of code in <pre><code>, and use JsFiddle to post working examples.