Grow your CSS skills. Land your dream job.

[W3Conf] Nicolas Gallagher: “The purification of web development”

Published by Chris Coyier

Nicolas Gallagher (@necolas) is a front end developer at Twitter and has worked on big projects like HTML5 Boilerplate and Normalize.css. Nicolas talked about questioning old assumptions about front end web development.

These are my notes from his presentation at W3Conf in San Francisco as part of this live blog series.

"Best practices" are not "absolute truths."

Nicolas was an anthropology student for longer than he's been a web developer.

Heraclitus (535BC): philosopher. Contempt for human kind. Misery is the way. Sad Keanu of his time. Died of rubbing cow poop on himself and laying in the sun. Major idea: everything is an illusion. "You cannot step twice into the same river; for fresh waters are flowing in upon you."

Democritus (460BC): also contempt for human kind. The "laughing philosopher". World's first troll. Conservation of mass and energy. Atoms.

These ideas were left in lurch for thousands of years until science found them. Plato and Aristotle rejected these ideas, but you can't blame them. The ideas came back when the time was right.

Web development is also a world of ever-changing contexts. Nicolas keeps doubting assumptions that were true, even six months ago.

HTML class attributes were added for CSS1 "to increase granularity of control over elements."

The CSS Zen Garden (2003) was one page of HTML, but there were loads of different designs for it where only the CSS changed.

Real statements from real people and real specs:

"Don't use unsematic class names."

"Your HTML, like diamonds, are forever."

"Authors are encouraged to use class attribute values that describe the nature of content, rather than values that decirebe the desired presentation of the content."

This stuff is crazy to Nicolas. He once designed his blog with zero classes. Making (so called "perfect semantics") But making changes became impractical. Hard to read. Hard to understand. Hard to make style changes.

This is more true:

There is a notion of "ugly" HTML class names though. This kind of class name is fashionable at the moment: hyphenated-lowercase-4-life. E.g.:

.button { }
.button-group {}
.button-primary {}
.button-group-item {}

This kind of thing doesn't communicate much. Contrast that to these "ugly" class names:

.Button {}
.ButtonGroup {}
.Button--primary {}
.ButtonGroup-item {}

This naming convention communicates much more. Double dashes are a modifier. Single dashes is a component child. These aren't ugly. They may not be fashionable at the moment but maybe they will be. This particular pattern comes from the Russian search engine Yandex.

Note: There may be some historical reasons on why classnames have which characters:

Another old best practice is: "Don't use extra elements." Nicolas has gone deep into the world of pseudo elements to avoid the use of extra elements. In retrospect, this made it much harder to understand what is going on. Not that "junk" markup is good, but stuff like Web Components makes much more sense.

CSS is the wrong tool for imparting structure on content/design. HTML is for that. Web Components gives us the ability to use the correct tools without worrying about "junk" markup.

Comments

  1. Dimitrie
    Permalink to comment#

    so is it , or is it not smart to use the underscore/dash class bem naming convention used by nicolas?

    • Felix
      Permalink to comment#

      I think that the answer is the same as always… “it depends”

    • Permalink to comment#

      @dimitrie It is up to you, underscores can cause problems which is presumably why Yandex went with single and double hyphens to distinguish between elements and modifiers.

      Whether you choose to adopt BEM as a naming system is up to you / your team.

      I think the takeaway here is that having a naming system as part of your styleguide is a good idea. It will take a bit of getting used to but once you have got it ingrained into your documents you will save a lot of time wondering how to name your classes.

      I have just started planning usage of BEM naming conventions for new projects – I know it will be a pain to start with but see big wins further down the line. SASS was a pain to starts with but I really wouldn’t want to be without it now.

    • Unless your supporting browsers below IE 6, Netscape 7, Navigator 5, or Opera 6; it is completely safe to use underscores. Whether you want to use them is up to you.

      (Read: “Historical”)

  2. As well you say the ” absolute truths ” they do not exist but always it is suitable to follow(continue) a few procedure of common use.

  3. Permalink to comment#

    Good topics please keep the continue…

  4. Sounds like a great talk. I think we do need to re-examine “best practices”.

    I read through the link Eric Meyer posted about underscores. If you read it, you’ll see that using underscores in IDs/Classnames does not work in, Netscape Navigator 4.x and Opera 3.x through 5.x.

    If it was 1998, I could understand not using underscores in ID/Class names, but its 2013.

    I prefer to use hyphens when naming classes.

    .urgent-note  {color: #C00;}
    

    Through I have used underscores before for module components, or what Yandex refers to as elements. If I had a heading title in my note I might use a class like.

    .urgent-note__heading {font-family: serif;}
    

    I could also see coming up with a different naming convention like:

    .urgent-note-Heading {font-family: serif;}
    
  5. The rising popularity of web applications is changing a lot in the web development world of best practices. OOCSS arose from web apps, and from OOCSS we’ve started questioning the best practices we used before. Now we’re okay with less semantics (web apps aren’t read by search engines anyways), more classes, much more ambiguous attributes (data-), and more markup.

    I think it’s fairly clear that there are two branches of web development – there are web sites and there are web apps. They use the same tools, but have completely different needs. As such, the best practices surrounding both need to be unique to each.

    Many people, myself included, actually wonder if a document format (which is what HTML is) is the best tool for creating web apps. It’s the tool we have, but is it the right tool? This is another assumption that needs to be challenged – that a web page must, ultimately, be built on top of HTML, CSS, and JavaScript. Is there no room for other forms of natively executing code in a browser?

    • I don’t really see the need to abandon the HTML doc as a fundamental container. It’s not limited to HTML, CSS, and JavaScript. I also use PHP, MySQL, and will be using nodeJS, IndexDB, Python, Ruby, and others as I learn them.

      Having a common document container for web based content, whether it’s considered an app or a static document makes the web somehow more workable for the browser vendors and users. It doesn’t limit the variety of possible interactions with a web site.

      I do think the whole notion of having to use apps siloed by a handful of megacorps., just because you’ve switched from your laptop to a smartphone, has to go. I also think the new and upcoming generations of SOC’s will give smaller portable devices the capacity to catch up when it comes to processing power.

    • Websites or web apps, OOCSS is fit for both, and work very well there. As Necolas said: class names are there for developers, not machines. OOCSS is simply an approach to making class names work harder for us.

      Sometimes I think Object Oriented CSS is a bad name for what it is. It implies an entirely new language or at least an entirely new way of approaching CSS; but it’s neither of these, it’s a challenge to what we consider best practices by what actually works.

      There hasn’t been a real divergence of web apps and sites. Sure the concept of web apps arose in the past few years, but it wasn’t something new and it wasn’t a complete break between the two. Both sites and apps have changed together and in the same ways.

      The idea is that the web has grown up but our best practices more or less have not.

      Nicole Sullivan’s goal wasn’t to reinvent the wheel, she saw that our best practices weren’t turning out the best results, and she saw a pattern that wasn’t documented but worked really well.

      Lastly, HTML/CSS/JS are now expanding past the browser, they are extremely powerful tools that aren’t getting replaced anytime soon (and probably never should be).

  6. strages
    Permalink to comment#

    @JamesKyle thanks :D that was the most clear answer

  7. People don’t seem to understand BEM Methodology in the slightest, it’s not about underscores, dashes, or camel-casing. It’s Block-Element-Modifier, it’s about giving structure to your class names that can be understood by an entire project or organization.

    The system I use is:

    .object-name
    .object-name.modifier_object-name
    .object-name .object-name_element
    .object-name .object-name_element.modifier_element
    .object-name .object-name_element.is-state
    

    Example Using a CSS Preprocessor:

    .menu {
      // Object
      &.left_menu {
        // Object Modifier
      }
    
      .menu_item {
        // Object
        &.first_item {
          // Object Modifier
        }
        &.last_item {
          // Object Modifier
        }
        &.is_active {
          // Element State
        }
      }
    }
    

    The generated CSS output would be:

    .menu { }
    .menu.left_menu { }
    .menu .menu_item { }
    .menu .menu_item.first_item { }
    .menu .menu_item.last_item { }
    .menu .menu_item.is_state { }
    

    For which the markup would be:

    <nav class="menu">
      <a class="menu_item first_item" href="#">Item</a>
      <a class="menu_item is_active" href="#">Item</a>
      <a class="menu_item" href="#">Item</a>
      <a class="menu_item last_item" href="#">Item</a>
    </nav>
    

    You could switch out underscores and dashes for anything you want, the important part is constructing a system that helps you organize your styles in a way that will help you cut back. I optimized mine so that I don’t have to write really long class names all the time (Which add up fast).

  8. My take on class naming is use part semantic, part generic term. i.e.
    #nav-facebook{float:right;margin:0;padding:5px 20px 5px 0;}
    #logo-container{position:relative;top: 18px;max-width: 550px;}
    #logo{width: 100%;z-index: 0;}
    #logo-position-fix {max-width:1080px;margin:auto;}
    .headerbg{background:url(images/soul-sanctuary-header-bg.jpg) center center #000;height:100%;}

    It’s nice to have a system you can work to, and one that others can read if you’re are working along side other programmers, but I think if you spend too much time wondering was a class or id should be called, you’ll never get anything done. If your system is understandable and efficient. That’s the main thing.

    • That’s the point, come up with a system that works for you and use it so you don’t have to think about selectors every time you write one.

      If you don’t have a system (especially when working on a team), every selector you write will deteriorate you’re code base until it become unmanageable.

  9. What I’m starting to find odd these days is that use of classes is increasingly becoming less useful as far as dealing things via CSS is concerned. The worst limiting factor these days is IE8 (in addition to some mobile browsers) which does not support many of the new CSS3 selectors, especially :nth-of-type, :target or :checked that can be very useful.

    In general I often find the use of classes to be there for JavaScript developers so that they can use the same CSS class names as variable names. But when I’m working from pure HTML & CSS perspective I rather use classes only on parent elements and then deal directly with the actual elements. A recent example of this…

    HTML

        <section class="imagelist">
            <input id="page1" accesskey="1" type="radio" name="imagelist1" checked="checked" />
            <input id="page2" accesskey="2" type="radio" name="imagelist1" />
            <input id="page3" accesskey="3" type="radio" name="imagelist1" />
            <label for="page1" title="To page 1">1</label>
            <label for="page2" title="To page 2">2</label>
            <label for="page3" title="To page 3">3</label>
            <ul title="This is page 1">
                <li><a href=""><img alt="" src="pienikuva1.jpg" /></a></li>
                <li><a href=""><img alt="" src="pienikuva2.jpg" /></a></li>
                <li><a href=""><img alt="" src="pienikuva3.jpg" /></a></li>
                <li><a href=""><img alt="" src="pienikuva4.jpg" /></a></li>
            </ul>
            <ul title="This is page 2">
                <li><a href=""><img alt="" src="pienikuva5.jpg" /></a></li>
                <li><a href=""><img alt="" src="pienikuva1.jpg" /></a></li>
                <li><a href=""><img alt="" src="pienikuva2.jpg" /></a></li>
                <li><a href=""><img alt="" src="pienikuva3.jpg" /></a></li>
            </ul>
            <ul title="This is page 3">
                <li><a href=""><img alt="" src="pienikuva4.jpg" /></a></li>
                <li><a href=""><img alt="" src="pienikuva5.jpg" /></a></li>
            </ul>
        </section>
    

    CSS

    /* contains fallback style for browsers that do not support new selectors */
    .imagelist { }
    
    /* fallback overdrive */
    head ~ body:nth-of-type(1):nth-last-of-type(1) .imagelist { }
    
    .imagelist > input { }
    
    .imagelist > label { }
    
    .imagelist > label:hover { }
    
    .imagelist > label:before { }
    
    .imagelist > ul { }
    
    .imagelist > ul > li { }
    
    .imagelist > ul > li > a:first-child { }
    
    .imagelist > ul > li > a:first-child > img { }
    
    .imagelist > ul > li:hover > a:first-child > img { }
    
    .imagelist > input:nth-of-type(1):checked ~ ul:nth-of-type(1) { }
    .imagelist > input:nth-of-type(2):checked ~ ul:nth-of-type(1) { }
    .imagelist > input:nth-of-type(3):checked ~ ul:nth-of-type(1) { }
    
    .imagelist > input:nth-of-type(1):checked ~ label:nth-last-of-type(1),
    .imagelist > input:nth-of-type(2):checked ~ label:nth-of-type(1),
    .imagelist > input:nth-of-type(3):checked ~ label:nth-of-type(2) { }
    
    .imagelist > input:nth-of-type(1):checked ~ label:nth-last-of-type(1):before,
    .imagelist > input:nth-of-type(2):checked ~ label:nth-of-type(1):before,
    .imagelist > input:nth-of-type(3):checked ~ label:nth-of-type(2):before { }
    
    .imagelist > input:nth-of-type(1):checked ~ label:nth-of-type(2),
    .imagelist > input:nth-of-type(2):checked ~ label:nth-of-type(3),
    .imagelist > input:nth-last-of-type(1):checked ~ label:nth-of-type(1) { }
    
    .imagelist > input:nth-of-type(1):checked ~ label:nth-of-type(2):before,
    .imagelist > input:nth-of-type(2):checked ~ label:nth-of-type(3):before,
    .imagelist > input:nth-last-of-type(1):checked ~ label:nth-of-type(1):before { }
    

    All the current major desktop browsers play nice with this syntax and I find it quite readable as well. A lot of interaction can be done with just HTML and CSS alone, you don’t need JavaScript for many of those simple transitions. For example the search box on this site could easily be done in just plain HTML and CSS.

    Of course I do understand that adopting this for a major project is a different story.

    • MY EYES!!!!

      In all seriousness, I hope you don’t actually use selectors like that. Even if every browser supported them, they’d still not be a good idea.

      Also, classes haven’t changed, so how could they possibly be any less useful?

    • You say “not a good idea” but you’re not giving any reasoning.

    • Hahaha, well first off as I said before you lack browser support. Second, in what project are you using more selectors like that than classes? Third, if there is such a project your styles must be enormous. Fourth, if what I think you’re doing with those selectors is what you are actually doing, then you should be using javascript not CSS (style vs. function). Fifth, that code is completely dependent on the markup (one tiny thing changes it all breaks). Sixth, eck that CSS is ugly. Seventh, just because something can be done, doesn’t mean it should be. Eighth, is this not enough reasons yet? Ninth, there’s a million ways you could be writing cleaner and shorter code than that. Tenth, read a book. Eleventh, I’m done here.

    • Pat
      Permalink to comment#

      While you can create complex selectors using CSS3 like you’ve shown I wouldn’t really advise it. Reasons why I choose not to do it are:

      Browser support in IE8 is non-existent
      Your styles aren’t very modular. They can’t be used in many places as they are tied to these specific sections of the DOM.
      Your CSS/HTML is highly coupled make it fragile. If you add a single new HTML element into your DOM here, it could potentially screw up all your styling.
      It’s a specificity nightmare. If you want to make one of those items different than the others you will have to create either a longer selector, use an id or use the dreaded !important

      I almost style exclusively with classes and when I want to use ids/classes in my javascript I use a ‘js-‘ prefix, e.g. js-rotator. I never use CSS styling classes in my JS as this means I can change my markup/CSS and it won’t have an effect on the JS.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".