Comments on Meaningful CSS: Style Like You Mean It

64 Reader Comments

Back to the Article
  1. Really interesting article. I love the idea of using ARIA roles/attributes over custom classes wherever possible: seems so obvious, and yet I haven’t on the whole been doing that - at least with any consistency - until now.

    What remains unclear to me is how to retain the neat namespacing that an approach like, eg. BEM provides (which leads to lots of long, ugly class names, but which also has significant advantages in terms of being able to write modular CSS). Any thoughts on this at all?

    Copy & paste the code below to embed this comment.
  2. Its an article on CSS architecture, that is poorly thought through.

    Copy & paste the code below to embed this comment.
  3. Very good food for thought, and bound to draw its share of controversy. I can see that, in some cases, this would lead to more maintainable CSS, and in some cases, it would lead to more maintenance difficulties.

    What do you consider layout classes to be? Utility classes? How about the ol’ standard OOCSS example, .media?

    I’d personally add at least one other valid case for classes: stylistic variations (‘modifiers’ in BEM parlance), such as button.cta or ul.compact. Is that what you mean by this case?

    When there are not existing elements, attributes, or standardized data structures you can use.

    Copy & paste the code below to embed this comment.
  4. Love the article.
    Spot on.
    Is snippet #3 missing the closing </label>??

    <label for=“id-name-field”>What’s Your Name

    Copy & paste the code below to embed this comment.
  5. Some of the points made are important to consider, but I would disagree with the practice of your css styling elements directly. I have a goal with my css, where I try to make classes work in isolation.

    To explain, there will be times where you need an element such as a form or submit button differently. If you have styled root elements such as ‘form’ or properties like ‘[type=submit]’, then you will need to create other classes that override a bunch of properties found in the root element. Then if the root element styling changes, your ‘child’ classes all need to be updated also. This is problematic for maintenance.

    Copy & paste the code below to embed this comment.
  6. Is snippet #3 missing the closing </label>??

    Thanks, jdelia. Corrected.

    Copy & paste the code below to embed this comment.
  7. Why would I use classes vs HTML5 elements? First, to me it brings better versatility and backwards compatibility. For example if I have WordPress theme and would want to change the structure a bit, I would need to add many CSS rules to keep existing websites from breaking. If I use classes instead, most likely I will not need any backward compatibility rules.

    So I guess we can use HTML elements for main structure points and classes for smaller elements where needed.

    Browser compatibility might be one of the cases of double tagging like MAIN CLASS=“MAIN”, especially if your code is used in governmental or healthcare sector.

    Copy & paste the code below to embed this comment.
  8. I must confess I feel a sudden guild of not upping my HTML-game sooner… I loved the article but could you reflect on the following?

    1) CSS-performance: I never considered -until now- using “qualified attribute-selectors with value” like [role=button] because of its performance. Classitis has it’s own performance issues. So don’t we trade in selector-performance against classitis? Or do you consider the one more important then the other?

    2) Working in a Drupal-world, things get thrown around a lot semantically. I couldn’t agree more on how important it is to get the HTML-semantics right. But I do secretly sleep a bit better at night when I know the theming is only class-based. Naming conventions like BEM no longer depends on a specific html-structure to be sustained throughout the project. Won’t we be sacrificing maintainability by moving away from class-based approaches?

    Copy & paste the code below to embed this comment.
  9. @Mathieuspil Also we have to remember that best practices of using ARIA selectors have tendency to change. So one day you might need to change CSS if you need to adjust the ARIA markup. So we come back to maintainability question…

    Copy & paste the code below to embed this comment.
  10. I think this article is missing a few points:

    - Separation of concern: semantics (and structure) may change while styling may not. For this reason, tying the styling to HTML is bad regarding maintenance.

    For example: using “form > p or fieldset > p” would prevent authors from replacing a `p` with a `div` (a very strong possibility) without editing the style sheet.

    - Since you mention HTML bloat, why not pointing out that using “[type=text]” instead of “.text-input” will lead to more selectors in the styles sheet (url, number, tel, email, etc.). A class being more generic can target different/more elements.

    - In the “Common vs. optimal form markup” section, you say people should use `form` instead of `.form`. While I agree that using `[role=button]` is better than using `.button` (as long as those elements are truly acting like buttons, i.e. they are actionable via space bar), I would warn people about what this means in regard to the cascade since `form` (type) is less specific than `.form` (class). In my opinion/experience, it is better to write rules with the same specificity “range”.

    Copy & paste the code below to embed this comment.
  11. Reusing classes on a different markup is really performant in cross project reusability. Defining things globally never worked out in the wild since a lot of the time we need to override the default styling for various reasons such as multiple states of a single form. I really appreciate the clean approch but building scalable interfaces is all about micro chunks of content working together in an orderly fashion, not reusing larger globally defined components. A simple form in reality is actually lot more than a couple of labels and inputs. Still a lot of good points were made in the article.

    Copy & paste the code below to embed this comment.
  12. Hey, it’s 2016. No, people don’t want to style in different ways while keeping the same semantic markup anymore. Now they want to style the same on different semantic markup.

    Copy & paste the code below to embed this comment.
  13. TL;DR; Attribute selectors like [role=button] doesn’t have support in older browsers and that is the reason, why classes are still used as a main tool to style elements -> and it surely will do for another few years.

    You must understand that semantics is like categories for things in our native language. It shouldn’t serve another purpose. For example even though there are all cars, and buildings, and phones. It says nothing about it’s color, size, material etc. You will always add another word before the “category”  eg. Blue Car -> and that word is a class that describes its appearance. 

    You can have “global” <car> tag, but all cars doesn’t look the same. So you end up with car.blue blue selector or “.blue-cars car” selector -> yeah, chaining and nesting, the thing all the BEMs and OOCSS tried to solve because of no namespacing option for CSS.

    You’ve solved nothing with your “form” vs. “.form”, you’ve just introduced inconsistent syntax and possibly created opportunity for chaining.

    The main idea of this article should not be to style tags, but to use better class names, that make sense.

    I am big fan of attribute selectors specifically AMCSS modules that can bring some kind of containment which CSS currently lacks.
    ( https://amcss.github.io/ )

    My advice for styling tags is simple. Don’t style them directly! (except for normalize).

    Copy & paste the code below to embed this comment.
  14. this approach is simply unsustainable on a large project. Trust me, I’ve tried. I work with the CSS on one of the oldest commercial sites on the web, and when we’re re-platforming and re-skinning, we have to write new styles and markup that lives side-by-side with legacy. This approach does not support what we’re doing.

    I really like the philosophy here though, and would definitely recommend it for smaller sites or projects.

    Copy & paste the code below to embed this comment.
  15. I had a very long comment that was somehow deleted in the the submission process…

    However, the gist of it was that I think you bring up a lot of good points, but that the real answer to the problem you are proposing a solution to isn’t to neglect classes all together, but to instead write classes with meaningful names (BEM syntax?) and generally know when it’s proper to write CSS utilizing appropriate semantic hooks, whether those be based on mark-up or attribute selectors (native to HTML or ARIA).

    Copy & paste the code below to embed this comment.
  16. Food for thought. Most of my concerns are already mentioned, but here goes:

    - When you suddenly discover you need e.g. a button element that is unstyled/very differently styled, then you suddenly have to struggle with resetting styles.
    - Selectors like form > p, button and [role=button] all have different specificity. One of the advantages of BEM is that most selectors are the same specificity, giving a more predictable cascade.
    - However, I agree that careful use of ARIA attribute selectors promote good markup and probably should be considered more often, but only when the risk of needing to override styles is also considered.

    Copy & paste the code below to embed this comment.
  17. I have a few concerns about this approach falling short under non-simplistic development scenarios.

    Using html tags to apply visual styles can be restrictive, especially in larger (real life) systems. 

    A simple example would be a data entry page with a search option in the header.  Two forms, matching markup, different visual styles.  Applying styles to the ‘form’ creates a coupling between the semantics of the content and the visual presentation. 

    In simpler systems this could work but in more complex scenarios it’s worth considering alternatives that explore patterns in how content is displayed.

    Your markup might look busier with more classes but the separation of concerns will make for fewer surprises when someone tweaks how a form should look.

    It’s also forward facing, with the impending increase in component based design and development, sharing content patterns across components without making assumptions about the markup used.

    Also, whilst it may not be a priority, there are concerns over the performance of attribute selectors in CSS so I’m not sure but the ARIA label approach could cause problems.

    Copy & paste the code below to embed this comment.
  18. “You can’t have more than one main element”

    There’s some disagreement between WHATWG and W3C over whether or not multiple main elements should be allowed, and if you’re in the WHATWG camp, you may very well have multiple main elements on the page.

    https://html.spec.whatwg.org/multipage/semantics.html#the-main-element

    Copy & paste the code below to embed this comment.
  19. Doesn’t really sound thought threw by someone who’s made a website. Styling by Aria roles over classes, what advantage could that possibly have. At least classes can be reused for example .button could be applied to a button… or an <a> tag! Sweet. Welcome to web development. Let’s not break the web over one persons idea of what semantics should be lest we go back to the early 2000’s “header > ul:first-child > li a > span”

    Copy & paste the code below to embed this comment.
  20. “A word of caution: don’t throw ARIA roles on elements that already have the same semantics. So for example, don’t write <button role=“button”>, because the semantics are already present in the element itself.”

    From http://a11yproject.com/checklist.html:
    “Note: When you validate html using landmark roles, you’ll receive a warning stating these roles are redundant. In HTML5, several of the landmark roles are implicit via the native structural element which is supported by most modern desktop browsers with the exception of IE and iOS Safari. So, if you support IE and iOS browsers, you’ll want to use the landmark roles. For more information, read Quick Tip: Aria Landmark Roles and HTML5 Implicit Mapping.”

    Copy & paste the code below to embed this comment.
  21. The W3C recommends paragraph tags for wrapping form elements. This is a predictable, recommended pattern for wrapping form elements.

    The markup in the document is non-normative. It’s not a recommendation - it’s there to serve as an illustration.

    Copy & paste the code below to embed this comment.
  22. Completely agree with the problem you mentioned about too many <div>s. Finding closing <div> in the forest full of <div>s is quite painful.

    However, the proposed solution in this article will cause more problems later on in the project as many people pointed out.

    I am also looking for the answer to this problem and couldn’t find perfect answer yet. Your solution about using role=”...” is quite interesting though :)

    Copy & paste the code below to embed this comment.
  23. I’m not sure everyone in the comments is willing to consider the proposal of this post. 

    BEM or any other CSS architecture advocates for separating styles from content. This article is not arguing that you must use styles and HTML together. It is arguing that you start with the most “correct” HTML and then style it.

    When it comes to styling you can override my-form__my-submit--primary or form.my-form button[type=submit].

    Styles will always be coupled to something. It could be coupled to the HTML and I override the styles via element selectors. Or I couple my styles to my specific CSS naming conventions. In either scenario, if I need something unique I’m going to override existing styles. 

    The advantage of the approach prescribed here is that you’ll have good markup to move forward with.

    Copy & paste the code below to embed this comment.
  24. The example isn’t realistic. Take button for example, you still have .btn-secondary .btn-success .btn-warning .btn-danger to take care with.

    So your suggestion just creates a special case in style sheet.

    Copy & paste the code below to embed this comment.
  25. Wow, I didn’t realize there would be so much resistance to an idea like this. We’re implementing a lot of it, in what is going to be thousands of complex sites, with very little trouble. It feels to me, like a lot of these comments are similar to the comments you might have seen during the movement away from tables for layout… Actually, I still see arguments for tables for layout occasionally… weird, I know…

    Copy & paste the code below to embed this comment.
  26. A nice idea but impracticable except on small sites. Because of the specificity problems it creates, and because of the maintainability problems it creates in the markup, as already noted. The resistance to this idea has nothing to do with kneejerk conservatism. It comes from countless hours of hard experience by people who understand the semantic imperative, who want to do the right thing, but who recognize that it is better to make a small compromise in order to keep their sanity. A tiny compromise really, because CSS preprocessors allow completely semantic class-naming.

    Copy & paste the code below to embed this comment.
  27. @philwills No one is arguing that writing semantic HTML is a bad idea. The issue here is the scalability of attaching all or most of your styling to the HTML elements or attributes of those elements. Like many have said, not a big issue for small sites, but not maintainable for large/complex sites.

    Copy & paste the code below to embed this comment.
  28. I have to agree with the OOCSS community feedback on this one. I like the idea of performance gains, but I don’t think the rubber will hit the road with large projects where numerous are developers contributing, that are already using Bootstrap, and other naming styleguides like MVCSS (http://mvcss.io/styleguide/naming/). I also don’t think the performance gains will have an impact when looking at the overall picture of things that impact performance in modern projects.

    Separation of concerns are essential, and we have things like this being taught by industry experts:

    - Only bind CSS to CSS-based classes:
      .im-a-css-class {

    - Don’t write DOM-like selectors:
      header nav ul li a {

    - Don’t bind CSS onto data-* attributes:
      [data-value=“foo”]

    - Don’t bind JS onto CSS classes:
      document.getElementsByClassName(‘nav’)

    - Use JS classes:
      .js-site-nav

    (from: https://vimeo.com/140641366)

    Copy & paste the code below to embed this comment.
  29. Nice idea, but but my concern is that at some point you will end with a data/aria attributes bloat in order to style precisely some custom elements (especially if the design is not completely consistent)
    Other concern is that you are using semantic attributes for style hooking, which couples a lot the markup and the style. If more meaningful class names are used and a semantic markup, you should be ok.

    Copy & paste the code below to embed this comment.
  30. @Tim Baxter, it’s not maintainable because you are tightly coupling your HTML semantics with the visual presentation.

    Please read: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Writing_efficient_CSS.

    You clearly violated most of the points made in that article. The W3C has not “built” large scale, cross-browser websites. Semantics have to change - no matter what you end up with. Div spaghetti is inevitable because of the various cross-browser solutions to common problems, but classes remain agnostic to the HTML semantics.

    Classes don’t make your HTML harder to reason about, they can make it easier by using more meaningful class names, they can be used to describe the div spaghetti.

    For performance reasons, avoid child selectors like “form > p”, classes help resolve this.

    I can go on and on about why classes trump semantic selectors.

    Also, Regression is a hell of a drug.

    Remember this, HTML can and will change, but classes can remain frozen in time and still present the same old visual you expected.

    Copy & paste the code below to embed this comment.
  31. Inspired by http://nicolasgallagher.com/ ‘s normalise css, I made a bootstrap-like setup with three css files:
    1. A classless stylesheet which normalises and styles all the HTML elements. This was so that we could build prototypes quickly across a very large public sector organisation with lots of developer teams and still have consistency. This sheet is sacred.
    2. A “classes” stylesheet for when you need to override the default styling set in the default stylesheet.
    3. A “molecules” stylesheet where I placed the styles for re-usable HTML components. Here the parent wrapper gets a class but the children (as much as I can avoid) remain classes.

    Sometimes a fourth sheet is added for custom elements which will not be used very often in other projects. This overrides the other sheets. I know it’s not optimal to override but it means we can keep the other three sheets clean and relevant.

    Copy & paste the code below to embed this comment.
  32. I love some of the things that this article promotes – we should definitely all be striving to create more meaningful semantic markup rather than div soup and using roles for certain use cases in styling makes a lot of sense.

    But I don’t agree with the argument that we should be throwing away hugely useful conventions such as naming schemes and CSS methodologies – ideas that have evolved and grown over years to help tackle many of the issues when authoring CSS on a larger scale.

    The main point that I think the article misses when comparing this approach to using class naming schemes is specificity and how much of a pain point this can be on sites of scale.  The reason a naming scheme is so useful is that it keeps the specificity as low as possible, meaning it is much easier to override styles when needed.  It also means you can build up components using semantic classnames, so should that structure change in the future, the styling isn’t so tightly tied to the markup and is much easier to update.

    On a simple site this isn’t as much of an issue, but on large platforms this becomes very important.

    One of the biggest goals for me when writing CSS is to separate my concerns – the more that you hook CSS into HTML semantics and structure, the harder it becomes to change one without also changing the other.  This doesn’t mean that you can’t still write meaningful markup with considered semantics, which I think is the articles most valuable point.

    Copy & paste the code below to embed this comment.
  33. This article completely ignores CSS specificity, which fights against code reuse and modularity and is the reason why we’ve developed these class-heavy methodologies in the first place.

    Following the recommendations of this article would result in overly lengthy selectors and a tangled mess of specificity overrides in your CSS.

    The author should seek first to understand.

    (By the way, the comments system here is broken.)

    Copy & paste the code below to embed this comment.
  34. (Sorry everybody, we’ve been working out some conflicts between our commenting system and our CDN.)

    Copy & paste the code below to embed this comment.
  35. This completely overlooks specificity, code written this way would be a total nightmare to maintain.

    Please no one do this.

    Copy & paste the code below to embed this comment.
  36. As I understand it, the thesis here is that HTML + ARIA now has enough semantics to describe the presentation/UI of any web product.

    This just isn’t true. Let’s look at some examples.

    First, it’s pretty common to have a variety of ways of presenting homogenous listings of, say, articles. Google’s Material Design system, for instance, has Lists, and Grid Lists. The first is optimized for textual content, where any icon or other image is secondary. The Grid List, by contrast, is optimized for content where the image element is the most important (e.g. products, or albums). AFAIK, neither HTML nor ARIA provides “native” semantics to distinguish these two objects. There is little need to, from the standpoint of what HTML and ARIA are meant to do. Yet from a user experience point of view this distinction is a good one, and is definitely not arbitrary.

    Let’s look at another example. Say I have a main navigation. Let’s mark it up following this article’s advice:

    
      <nav>
        <ul>
          <li><a href="/">Home</a><li>
          <li><a href="#search-pane">Search</a></li>
          <li><a href="/orders">Orders</a></li>
          <!-- etc -->
    
    
      nav {}
      nav ul {}
      nav li {}
      nav a {}
    

    Now, let’s say I also have a secondary nav, for logging in and other user account actions. It shouldn’t look the same (let’s assume the main nav is a vertical sidebar, and this is a horizontal strip at screen top-right). If it’s part of a <header role="banner">, I can use a descendant selector:

    
      [role="banner"] nav {}
      [role="banner"] nav ul {}
      [role="banner"] nav li {}
      [role="banner"] nav a {}
    

    Unfortunately, since the main nav styles also apply here, I will need to override any that conflict with what I want for this secondary navigation. Even worse, any time anyone changes (or adds to) the styles for the main nav, they need to know to check the secondary nav to make sure that hasn’t been negatively affected. This is the opposite of separation of concerns, and is perhaps the main reason approaches like OOCSS were invented.

    I could come up with a lot of other real, practica examples. Note also that neither of these would be isolated to “large” sites or apps – every developer faces these challenges.

    In my mind, the following CSS is actually more meaningful (i.e. semantic) than the strings of more generic selectors above, because the speak the language of the product itself:

    
      .secondary-nav {}
      .secondary-nav__items {}
      .secondary-nav__item {}
      .secondary-nav__action {}
    

    As other commenters have noted, this approach improves robustness of the code and makes it more maintainable, since I can add a <button type="button"> to the secondary nav (if that’s what the best semantics are) and have it styled like the other actions just by adding a class. I can then refactor it to be an anchor with a fragment href later if that turns out to be better, and I don’t need to track down and change the CSS again. Likewise, if I need a div wrapper somewhere (say, to support some new dynamic behavior), I can add that with less risk of breaking a child selector somewhere.

    The best thing is that these modular and mostly class-based approaches don’t prevent us from writing beautiful, semantic markup and using ARIA appropriately. Good front-end development requires that, period. Now, many many designers and devs could do much better at learning the basics of HTML and ARIA, I’ll grant that. I’d strongly encourage it to boot. But robust, modular UI code builds on the standards of HTML and ARIA and does not mistakenly believe they are sufficient on their own.

    The current community movement is towards the idea of well-considered design systems embodied in reusable UI components that encapsulate markup, style and behavior (this approach needn’t sacrifice progressive enhancement, either). This is not a world of endless selector chains, specificity conflict and unforseen side effects. Preprocessors and other tools have made it possible to have a single representation of a component, obviating the need to change a class in hundreds of instances. The best systems come out of solid product goals and design patterns, and use class selectors (among others) to make codebases full of meaning. There is no need to worry so much about classitis or divitis: its time as a source of problems has passed. Semantic markup, ARIA and modern UI development can be friends! Isn’t that a good thing?

     

    Copy & paste the code below to embed this comment.
  37. Has there been any discussion of how we might transition to a more useful css specificity model? Perhaps something like was done with box-sizing: border-box. Then we could have both clean html AND clean css.

    Copy & paste the code below to embed this comment.
  38. Ryan Frederick hits the nail on the head - and so does Tim Baxter, each in their own ways.

    The fact is, a combination of *both* approaches is required for efficient, semantic and maintainable code.

    As developers, we should always be looking at reducing clutter in HTML - and it’s never been easier to do so!

    We have a plethora of meaningful tags and attributes at our disposal - and we should learn how to use all of them.

    We also need to learn to encapsulate common design patterns and to avoid nested selectors wherever feasible.  Classes make this far easier to achieve.

    As for avoiding div soup, creative use of pseudo-classes can result in a much clearer separation of semantic markup and style.

    Copy & paste the code below to embed this comment.
  39. On a large site, wouldn’t predictable, tested and documented markup patterns provide even more value than on a small site?

    — Tim Baxter on Meaningful CSS: Style Like You Mean It

    Yes! And especially in the case of accessibility & interactive widgets, I couldn’t agree more.

    Predictable markup patterns mean a predictable experience for users of assistive technology such as screen readers. Take a menu widget for example. If you allow the developer infinite ways to markup a menu, you are paving the way for inconsistencies in how your menus are described to screen reader users.

    What our users want is for the semantics of the menu to be exactly the same, for every menu, no matter how it has been visually styled. Markup patterns form a solid foundation in terms of achieving this. And it’s incredible how much CSS mileage you can get out of a fixed markup pattern these days. I have a standard pattern for most widgets and have not found a need to change them, even when the visual design changes. I like to think of them as my mini Zen Gardens :-)

    Copy & paste the code below to embed this comment.
  40. I consider thesis in this article idealistic and harmful.

    Basically it attracts people for the wrong reasons. The main assumption here is that it is possible to create highly coherent front end code base, that will even sustain itself, get stronger thanks to inherent forces of meaning and sense. This is highly attractive notion, as peaple strive for order, patterns and predictibility.

    But what is more harmful, the hidden implication here is that, there is sense connecting all of the mentioned technologies: ARIA, HTML, Microformats. We only need to discover it, embrace it.

    All od it is simply not true.

    You have to remember that front end environment is one of the most susceptible to change. It’s highly dynamic with no constraints on, why it shouldn’t be that way. It’s basically UI. If you start to force yourself to see in all of it high order meaning, you are doomed. It is beacuse HTML and ARIA have very basic ways of expressing content—very basic and thanks to that very flexible, composable etc. This is why tag can organize elements in form, but it also can group text.

    ARIA and HTML are good to express relations. They are not good display the content. And even with what they are good for it’s still really hard to use them, because of their hihgly general and versatile meanings. I mean… try to decide whether something should be <strong> or just <b>. And trust, right now we are in teritory of interpretation, with very little clear rules to help us.

    This means that these elements are highly composable. If you try to force on them predetermined structure, you already lost. It is because you assume that there will be content that can be split into similar objects, possible to express them in the same way. And that simply won’t happen. The possibilities of communication are to broad, to versatile.

    So what are we really talking about here? Think of it as an aspect of behavior. Something is <form> not because it has particular amount of input fields, not because it contains them grouped in particular way, not because of some ARIA elements, not even beacuse we use this particular name for it: ‘form’. Something is <form> because of the behavior of this element. It can look differently, but it will behave in the same way.

    And this is main part here: do not mix behavior with display. Don’t mix meaning with layout dynamics. If you start chasing this goal of meaningful CSS, you end up with messy CSS, very hard to maintain, that will break all the time.

    What’s worse, beacuse of very intensive coupling between the domains here, it will prevent you from creating more meaningfull HTML or ARIA elements. Imagine that. Imagine you created strict structure for particular component. You tied CSS with the structure. And after a while you found out, that you can improve accessibility or semantics of the component. In your current situation you cannot improve your codebase gradually. You cannot change HTML without touching CSS and figuring out what would be the best way to bind CSS with the new structure. How to again distribute layout and display responsibilities. HTML would seem to be untouchable. And you wouldn’t even start improving it piece by piece.

    Keep behavior and display separate. Make CSS composable to adjust it flexible nature of HTML.

    CSS is language for appareance, for layout interactions. It’s a visual enahncement of something that will still work without it. It should be treaded accordingly, as a separate domain, with interactions and relationships isolated from other domains as much as possible. BEM encourages it, but it is something of mental discipline, good organisation, and resolving highly complicated factors. Throwing into all of it also meaning? Why? There is no reason not to keep it separate. To me even such stupid classes like maring-left-20 is still practical. It’s very focused and very clear with it’s own responsibility. It’s bad beacuse of style, but style unfortunately can be amazingly not practical.

    And yes, use classes like ‘table’. Simply because this table is part of visual domain, not behavioral domain. It’s simple as that.

    And lastly, classitis argument is not really important. Whatever it takes to separate concerns, to split responsibilities, to ease out modifications—that is good. Classitis is very arbitrary way of judging something without no clear rules whatsoever.

    Clear you’re mind—separate concernes, focus interactions, simplify realtionships. Make your code composable and you will prosper in front end jungle.

    Copy & paste the code below to embed this comment.
  41. In my comment about widgets above I neglected to mention that I do use BEM too, so it’s not a completely class-free approach. I find that BEM helps strike a nice balance between class-itis and tight-coupling. So I guess this falls in line with Matthew’s comment above, which is “a combination of *both* approaches is required for efficient, semantic and maintainable code.”

    Copy & paste the code below to embed this comment.
  42. Interesting article which is no doubt going to cause disagreements. But anything that looks at better improving how we create our CSS and reduce HTML can only be a good thing.

    Copy & paste the code below to embed this comment.
  43. Interesting ideas. Are there any examples of this approach in the wild?

    Copy & paste the code below to embed this comment.
  44. > `<main class=“main”>`. But why?

    because

    > `<main class=“main—variation”>`

    Copy & paste the code below to embed this comment.
  45. Why main class=“main”?

    It could be more complex, and sometimes I’ve even made more complex : main class=“main” id=“main” role=“main”

    The id is just to provide an anchor (for skip links, etc.).

    The role is here for some old browsers that do not provide semantic for main.

    Why a class? Consider that another template has to have a left column or whatever. The main tag could change its place, and everything is down if you style on it. :)

    I do agree: some HTML are really bloated and could be lighter, but if we started to have recommendations like “don’t rely on HTML structure”, it was to solve other problems :)

    Copy & paste the code below to embed this comment.
  46. some times you need to do it like that . in wordpress if you are creating a theme you can’t change all the html on the website .

    Copy & paste the code below to embed this comment.
  47. This article has annoyed me a little.
    CSS architectures should be considered again for every project. I am not bias to using any architecture. I use lots of different architectures all the time, as they solve (or reduce) different sets of problems.
    If I tried to use a WordPress theme style architecture for the application I support at work, I’d be fired.

    Copy & paste the code below to embed this comment.
  48. Thank you!  I’ve been trying to make this case for a while myself.

    I think writing everything in your stylesheets using BEM or SMACSS (or what have you), can create as many problems as it solves.  Like all things, moderation.  There’s no reason to create a `.className—whichWillNeverGetUsedAgain` to bypass global scope when a `.meaningful-parent-description elementName` pattern will do.

    Global scope has a purpose and can be very useful, and a lot of these classes end up being really unsemantic and bloat the markup.

    I find that using LESS’s @import (reference) and @extend together (or postcss-reference if you prefer PostCSS) a great way to set up component patterns and then abstract them out to meaningful, and simple selectors.

    Copy & paste the code below to embed this comment.
  49. Not getting into the merits here. Just want to remark this:

    Tim Baxter, both in the article and in comment 20, you say W3C states paragraph tags are recommended for wrapping form elements. In fact, as pointed out by Terrence in comment 24, the section you mention is non-normative.

    And I’d like to add that you linked to an old W3C work: HTML5 Editor’s Draft from 25 October 2010. The same example can be found on the most recent HTML5 Recommendation from 28 October 2014.

    Actually, the example in the current W3C HTML Editor’s Draft uses DIVs instead of paragraphs.

    Copy & paste the code below to embed this comment.
  50. Using attribute selector would definitely give some possibilities in the structure of CSS.


    But… Attribute doesn’t scale in performance. If you have 1000 different classes. The SCOM/DOM parsing time won’t differ if you have 10 or 10000 elements.


    This is not true for attribute selectors unfortunately. As they on an average site, could mean the parsing could take 10-100 times longer.

    Copy & paste the code below to embed this comment.
  51. Hm.. You gave me some food for thought..

    Copy & paste the code below to embed this comment.
  52. Hm.. You gave me some food for thought..

    Copy & paste the code below to embed this comment.
  53. This is a great article and expresses ideas that I’ve been trying to convey for some time, without ever being able to put it nearly so well.

    The real beauty of the approach is that it allow CSS selector specificity to work the way it was always designed to work. Instead of treating specificity as your enemy and fighting it in the way BEM tries to do, specificity becomes your friend, a jigsaw piece that fits naturally it to its place.

    Copy & paste the code below to embed this comment.
  54. You can’t be serious , really !
    This approach is what i tried back when browsers started to adopt css3 and miserably failed , it can raise so many maintenance difficulties , though it’s good for small ( really small ) projects , but even then personally i think it’s overkill :|

    Copy & paste the code below to embed this comment.
  55. “In HTML, every element has a very specific, agreed-upon meaning [...]”

    Funniest thing I read this week :-)

    Copy & paste the code below to embed this comment.
  56. I keep seeing resistance to this concept and I honestly don’t get it. When you think of atomic design and the concepts behind OOCS and BEM consistent markup that can be composed into more complex components should go hand in hand. What I see most often is OOCS/BEM being used in place of good markup - essentially admitting defeat in that A) we have to deal with crappy code so put some lipstick on the pig B) we don’t really care about architecture or optimization, we just want it to look and work a certain way.

    Why can’t this simple concept be used with a variety of other best practices? For example I’d like to investigate how this might work in a React application with SASS and CSS-Modules.

    To me form follows function. So when people get frustrated with the concept that is suggested above by pointing out how BEM classes can be used across a variety of different tags, it makes me think “yeah, you could, but why?” Do I really need “btn” styling for button, input type=“button”, a, div, span, p… and on and on, or does that “btn” class infer a behavior too and that behavior is encapsulated by a specific HTML tag or ARIA role? So why not just change the tag or the role to align to behavior and get styling with it?

    The other thing I think about is consistency. While it’s great that designers can have 34 different ways they want to style a form - do they need 34 different ways? Just like there are 1272 different ways that the developer can code that form to get to one of the 34 different designs. Is it necessary? Does it provide value?

    Sometimes constraint breeds creativity. Reducing the number of variations, constrained by how we use markup + css, may force designers and developers down a path that produces more consistency and potentially better usability. This is why there needs to be deep discussion about architecture and architectural limitations. How do you architect a solution that takes a standards approach and provides both constraints and flexibility where they are needed?

    I think there is definitely a middle ground in this religious war. I’d really like to see more openness to talking through how the challenges can be overcome versus seeing any single solution as the ultimate “already fixed that” solution.

    Copy & paste the code below to embed this comment.
  57. I like to work with css and html most of the time..

    Copy & paste the code below to embed this comment.
  58. I like to work with html because is very easy (sometimes), but when I have to use css, especially on blogger it is killing me…

    Copy & paste the code below to embed this comment.
  59. I know I’m late but this article raise an interesting (controversial) points.

    If you really believe this would be the right way to design CSS, why don’t you (or others) create some sort framework or architecture or whatever you named it that proves or demonstrate this kind a thinking in practice.

    Because currently the alternatives is bootstrap or other CSS framework that has symptom of divitis and classitis.

    Copy & paste the code below to embed this comment.
  60. +1000%

    Copy & paste the code below to embed this comment.