By Hugo Giraudel

My Current CSS and Sass Styleguide

By Hugo Giraudel

It’s never easy to find a way to write consistent, future-proof, and robust CSS. It’s taken me months, if not years, to come up with a clean way to write mine. In fact, my process is still evolving, and I expect it to change even more.

In the meantime I have accumulated enough knowledge to write an article about how I feel about writing CSS. I don’t claim that these suggestions are for everyone, and they’re certainly not perfect. But I thought it would be nice to put these into an article to share them with the community.

Naming conventions

Naming conventions are a team decision. If, like me, you are dealing with your CSS on your own, you can go nuts and use something that suits you. Personally, I go with Nicolas Gallagher’s methodology which is influenced by the well-known Yandex BEM system.

BEM stands for Block Element Modifier, a clever and clean way to name your CSS classes. Yes, I said classes, not IDs. I don’t use any IDs in my CSS and neither should you. Any. IDs are overkill and can lead to specificity issues. Of course, IDs are still very useful for JavaScript hooks and HTML anchors.

The point behind the BEM syntax is to provide context directly into the selector in order to make them easily understandable to anyone new to the project.

Here is a very basic example of BEM:

.block { }
.block--modifier { }
.block__element { }
.block__element--modifier { }

Yes, double dashes, double underscores. We’ll see why in a moment.

So, what’s up with BEM? It looks long and ugly. Well yes it is! But the fact that is is long and ugly is actually what makes it efficient.

The main idea is simple: when you build a component, you give it a name. A child element of the component will be named like this .{{ name of component }}__{{ name of child-element }}. When an element is slightly modified it will be named .{{ name of component }}--{{ name of modifier }}. Of course, a child-element can be modified as well.

So what’s up with the double dashes and underscores? Well, these allow hyphenated names like .my-component. Then you can read .my-component--disabled without a problem. Same goes for the double underscores. Worry not, you will get used to it very quickly.

Since nothing’s better than a good ol’ example, here is a step-wizard module I wrote at work using the BEM naming system (which you can find on CodePen):

.steps { }
.steps__item { }
.steps__item--first { }
.steps__item--last { }
.steps__item--active { }
.steps__item--done { }
.steps__link { }

As you can see, we deal with 3 different elements:

  • .steps which is the module wrapper
  • .steps__item which is the main element for the module since it has at least 4 modified states
  • .steps__link, another element in the module

This may look kind of verbose but I can assure you this is a real pleasure to deal with once you get used to it. It is very descriptive and less prone to mistakes and confusions.

Naming variables

There has been a whole debate over naming Sass variables, especially those involving colors. Should we name our variables like the colors they refer to or should we name them according to their purpose across the project? Basically, which one would you rather have to deal with?

$blue: #4183c4;
// Or
$primary-color: #4183c4;

This is really a matter of opinion. I go with both.

$blue: #4183c4;
$primary-color: $blue;

This way I can have a bunch of cool variables like $blue-like-the-sky, $red-like-blood, and $sexy-pink that make more sense than hexadecimal colors and meaningful variables across the project to determine which color is supposed to be used where (primary here, secondary there, and so on).

Note: Hyphens (-) and underscores (_) are treated the same way in Sass so $blue-like-the-sky and $blue_like_the_sky are both refering to the same variable.

Naming Breakpoints

If you are not already naming your media queries, you really should do so. It makes a huge difference when having to update a breakpoint or read some code that is highly dependent on screen resolution. Naming breakpoints is as easy as using this simple mixin:

@mixin breakpoint($name) {
  @if $name == "small" {
    @media (max-width: 767px) {
  @else if $name == "medium" {
    @media (max-width: 1024px) {
  @else if $name == "large" {
    @media (min-width: 1025px) {

I used to pick a simple naming system like: small, medium, and large with the ability to add tiny or huge if required. This has the major benefit of being both very simple to read and device-agnostic, which is not the case with something like phone, tablet, and desktop, which don’t make much sense anymore since we have extra large phones and tablets and very small computer screens.

But! You could think of something more playful if you want to have some fun and your team is okay with it. I still go with baby-bear, mama-bear, and papa-bear from Chris Coyier on my own site, but why not something like r2d2, c3p0 and chewbacca? More cool examples like those are found in Chris’s article.

Tabs vs. Spaces

This is the kind of topic that leads to nuclear war, so I will just give you my opinion of the situation – feel free to think otherwise. I used to use only tabs but I ended up switching to spaces. Two spaces.

I am not sure there are many reasons for this, except that I feel like it suits me best. It has its pros and cons. Among the pros, it avoids having lines starting in the middle of the screen due to extra nesting.

Also, basic editors do not handle tabs very well. Think of textarea elements for instance. They let you insert spaces, but not tabs (unless you copy and paste from elsewhere, which is not ideal). Spaces are supported everywhere. Hence my choice for the former.

CSS Rule Sets

I like when things are clean. All my CSS rule sets are written the same way and they follow strict (yet standard) conventions. Here is an example:

.other-selector {
  color: black;
  padding: .5em;
  font-size: 1.2em;

Well, this is nothing more than the basics, which includes:

  • One selector per line
  • One space before the opening curly brace
  • A line break after the opening curly brace
  • A consistent indent
  • No space before the colon
  • A space after the colon
  • No space before the semi-colon
  • A line break after the semi-colon
  • No space before the closing curly brace
  • A line break and an empty line after the closing curly brace

Some side notes:

  • I tend to get rid of the padding 0 when dealing with decimal numbers between 0 and 1, making the number start with a .;
  • I try to make colors as short as possible, following this order: keyword > small hex triplet > hex triplet > rgb/hsl > rgba/hsla,
  • I avoid magic numbers at all cost (numbers that are not round or do not make sense by themselves),
  • I don’t use any px values (only em or even rem if browser support allows it) except when it is one (1px); pixels are not scalable, that simply sucks.

Sass Stuff

What I’ve just run through are pretty standard CSS guidelines. Now for some Sass-specific stuff.

.element {
  $scoped-variable: whatever;
  @extend .other-element;
  @include mixin($argument);
  property: value;

  &:pseudo {
    /* styles here */

  .nested {
    /* styles here */

  @include breakpoint($size) {
    /* styles here */

The different items in a Sass rule set go in the following order:

  1. Scoped variables
  2. Selector extensions with @extend
  3. Mixin inclusions with @include with the exception of media-query stuff
  4. Regular property: value pairs
  5. Pseudo-class/element nesting with & after an empty line
  6. Regular selector nesting after an empty line
  7. Media query stuff (with or without a mixin)

Taking our step-wizard example from earlier, here is what a real-life example in the above order would look like:

.step__item {
  counter-increment: steps; /* 1 */
  background: $step-background-color;
  float: left;
  padding: $step-baseline 0;
  position: relative;
  border-top: $step-border;
  border-bottom: $step-border;
  white-space: nowrap;
  &:after {
    @include size($step-arrow-size);
    @include absolute(top .3em left 100%);
    @include transform(rotate(45deg));
    content: '';
    z-index: 2;
    background: inherit; 
    border-right: $step-border;
    border-top: $step-border;
    margin-left: -$step-arrow-size/2;

  &[disabled] {
    cursor: not-allowed;

  @media (max-width: 767px) {
    width: 100% !important;
    border-left: $step-border;
    border-right: $step-border;
    padding: $step-baseline*2 0;

    &:after {
      content: none;

Nesting in Sass

Nesting has to be one of the most controversial features of Sass, or any other CSS preprocessor for that matter. Nesting is both useful – to avoid repeating the same selector again and again – and dangerous, because it can produce unexpected CSS. Only use nesting when it’s what you mean, not just because it is convenient. If you mean, .a .b, then you can write .a { .b { } }. If .b happens to be inside of .a but is enough by itself, don’t nest it.

Inception meme: We need to go deeper

I bet you’ve seen the movie Inception. Great movie, right? Well, you know how the characters can’t go any deeper than a dream within a dream within a dream, otherwise they end up in ‘limbo’? Well Sass nesting is the same: Don’t nest deeper than 3 levels. Ever. If you have to, it means either your markup or your CSS is poorly written. Either way, you might end up in ‘limbo’ and, as we saw in the movie, it ain’t pretty down there.

“Don’t nest deeper than 3 levels.”


When you work with Sass, you have two different ways to write your comments: the good ol’ /* */ you all know well, and the single line comment // that doesn’t exist in plain CSS (although you can get around that). The difference between these is that the single-line comments will not be compiled in the resulting stylesheet, ever. This is why single-line comments are referred to as “transparent comments” or “invisible comments”. Meanwhile, the regular CSS comments will be in the compiled CSS if you’re not compiling in compressed mode (you should be though).

As far as I am concerned, I comment a lot. CSS is a language full of tricks, hacks and dirty little secrets. I feel like I need to comment if I want someone (even me) to understand the code months later, even things that seem obvious at the time of writing the code.

 * Purpose of the selector or the rule set
 * 1. Hardware acceleration hack (
 * 2. Fallback for unsupported rgba
.selector {
  @include transform(translate3d(0, 0, 0)); /* 1 */
  background: black; /* 2 */
  background: rgba(0, 0, 0, .5);

I start with a small description of the rule set, then I number tiny details that are worth an explation. The numbers are then matched with numbered comments at the end of CSS rules (e.g. /* 1 */).

In the end I don’t use single-line comments much, expect in Compass extensions (e.g. SassyJSON). I started doing so when I realized regular CSS comments from my first Compass extension SassyLists were dumped to the CSS output on Sassmeister.

Quasi-qualified selectors with comments

I believe the idea of using comments to avoid qualifying selectors comes from Harry Roberts.

Qualified selectors are bad for many of the reasons described in Harry’s post. The most important ones being: They are over-specified unnecessarily, they break the cascade, and they are not reusable.

That being said, being able to say “this class should only be applied to this type of element” can be useful. Let’s say at some point you use CSS transforms and create a fallback for unsupported browsers, using Modernizr to detect support. Here is what your code might look like:

.no-csstransforms .selector {
  /* Styles here */

Now what if you want to explicitly indicate that the no-csstransforms class is meant to be on the html element and not anywhere else? Doing would make your selector over-qualified and is not a good idea. You could use a regular comment above the rule set to make a note, as we’ve seen in the previous section. Or you could try quasi-qualified selectors:

/*html*/.no-csstransforms .selector {
  /* styles here */

There you go: the class is now explicitly meant to be bound to the html element without altering you selector at all or breaking anything. This technique may look very odd at first but you can get used to it pretty quickly.

Final thoughts

As already mentioned, you might not feel comfortable using all these rules. And I don’t expect you to. What’s important is that you and your team are able to read each other’s code and update it easily.

Probably the best thing you can do with this post is take these suggestions and make them your own, adding your own flavour to them to improve your own workflow.

If you have developed your own methods for any of these areas of Sass and CSS, we’d love to hear them in the comments.

  • Hey Hugo, have you found doing media queries with a parameter gives much benefit over creating a series of mixins with the size in the title, like @mixin media-small, @mixin media-large, etc. It seems like it would be a little less safe to do it with a string parameter since a typo in the argument would not output the inner CSS.

    • True. However a typo in `@include media-small` wouldn’t have the desired effect either. Although I’ll give you that Sass compiler would crash because the mixin doesn’t exist. I suppose you could add a warning whenever the keyword isn’t recognized, thus you’ll know you’ve made a typo.

      • I just updated my breakpoint @mixin by abstracting both the breakpoint names and measurements to a Sass map: This has the same problem you’ve identified: it fails silently. Any suggestions on getting some kind of warning for typos/failures in this mixin?

  • TomButlerRje

    Honestly, I think it’s rather a pointless exercise being quite so pedantic with CSS at this level. The problem with CSS, at a more general level which leads to these sort of tidiness regimes is that it gets over-engineered (just look at how many lines of CSS exist in the average wordpress site with a couple of plugins). A better tactic to keeping CSS maintainable is to simply have less of it and separate it into files which pull in only the files needed.

    What I don’t understand about your BEM suggestion is that CSS already allows that without needing to invent a special notation for it. I can target all child elements in a component using .component .child or .component .child.modifer to suggest that using an alternative, bespoke, more verbose, syntax makes it easier for other developers to understand is nothing short of wishful thinking and in most cases, palpably false.

    • LouisLazaris

      Hi @TomButlerRje:disqus,

      Thanks for your comment.

      Hugo’s suggestions here are for the purpose of making the code easier to read. He’s mostly talking here about naming conventions and code organization, so that really has nothing to do with extra CSS coming from WordPress plugins… I don’t really know what that has to do with anything in this post….?

      And regarding the BEM methodology… BEM-style CSS makes it absolutely clear what is a ‘block’ and what is a ‘modifier’ without having to do really big nesting of descendants in your stylesheets (which is bad, but that’s another 3 paragraphs in another post!). With the BEM method, you rely on a single class that tells you in its notation whether it’s a block or a modifier. With the method you’re suggesting, yes it could work, but you’d have a much more complicated system in place because every modifier would have 2-3 classes chained together (whereas BEM there would just be one).

      And keep in mind that these techniques mean much more in a really large project and while working on a large team.

      • The wordpress example was purely a good demonstration of how CSS is often completely over-engineered. The only time you really need this level of complexity in CSS is when the CSS is over-engineered. Otherwise, it’s simple enough that there’s no need for such efforts and the time lost in organisation becomes more than it saves.

        I disagree, there are a hundred other ways of doing the same thing that isn’t nearly as verbose as the BEM method. As for 2-3 classes chained together, how is that any different that 2-3 parts separated by dashes and underscores instead of spaces?

        How is .steps__item–done any clearer than .steps .item.done? Generally speaking the modifier will be an adjective and the item/block will be a noun so English achieves this for us without needing a special notation and means that my HTML is tidier because I just have <span class=”item modifer”> instead of the more verbose and ugly <span class=”block__item–modifier”>.

        And then we get onto reusability and consistency. If you use the same modifier, let’s say “disabled” across multiple components, I can say “any disabled element has a strikethrough” using .disabled {} to target all disabled elements and can override using more specific CSS if needed for specific blocks. However, using the block__item–disabled method I need to specify this for every kind of disabled element.

        • LouisLazaris

          > As for 2-3 classes chained together, how is that any different that 2-3 parts separated by dashes and underscores instead of spaces?

          If it’s not different, then why do you have a problem with it? But the fact is, it’s very different. First of all, if you have 3 classes chained, that means you’ll have three different classes in your HTML, as opposed to just one. Secondly, what are the different classes defining? If they’re just for descendants, then you might as well just use hyphens. There’s no reason to use the method you’re describing and contrary to what you’re explaining, your method actually litters the HTML even more. This will also be confusing to future maintainers because they won’t understand why there are 3 classes on an element when only the last class actually has any styles attached to it.

          Also, your barking up the wrong tree here when it comes to BEM… Hugo didn’t invent it! He’s just saying he likes it! :) I think you should talk to the Yandex guys. :)

        • If you are worried about consistency, that’s a major part of CSS Preprocessing…

          .disabled {
          // your code

          .block__item–disabled {
          @extend .disabled;
          // block item specific disabled

          The point is that just using a lot of nested .disabled classes for specific elements instead of having their own tag is not as semantic. That’s what markup is all about. It isn’t “over-engineered.”

    • cmegown

      @TomButler I understand your point but the whole idea behind articles like this is about consistency, readability, and maintainability. While there is obviously some opinion that comes with it, these types of conversations are usually born from experience.

      Consistency is key for writing reusable/modular code in a language that doesn’t truly allow for actual object-oriented programming. The naming conventions and structure introduced with BEM syntax helps enforce consistency on projects of all sizes.

      Readability is key for working with teams and/or handing a project off to another developer. Have you ever been working with someone’s code and spent more time trying to make sense of it than actually making changes? I have, and it sucks.

      Maintainability is key because doing the concept work, writing the code, and launching the product is the easy (and fun) part. Long-term maintenance work can be tedious and extremely difficult if things aren’t set up in a way to allow simple additions and/or changes. When you’re working with small projects, it’s not as big of a deal. If you’re working with larger products, that may be integrated or linked to other products, maintenance becomes one of the most important facets of design.

      Although code standards like those written in the article may seem over-engineered, they exist because of extensive trial-and-error in projects of all shapes and sizes.

    • Stephen Benner

      @Tom Butler is COMPLETELY on the money with his comments about ‘BEM’, and everyone else is just missing out. Sure, each programmer is going to discover their own vision of clarity/efficiency in how they code, but this absolutely has become WAY too pedantic… Oh wait, did you say Nicholas GHALLAGHER uses this method?!? Excuse me while I delete my comment, obviously BEM must be great!

      No but seriously, while there may not be a ‘silver bullet’ for any programming language, this is a fine example of what I’ll call ‘silver bullshit’: nice and shiny on the outside, appealing to new developers, but in reality, total and utter crap. Don’t misunderstand me–obviously my own opinion on the convention isn’t relevant (personally, it makes my eyes bleed); what I take issue with is the presentation of this method as a ‘best practice’ or actually as part of anything bearing the title ‘style guide’. I could write an entire blog post of why this is BAD BAD BAD, but seriously just read Tom’s comment over and over again until you get it.

  • Nice, I do almost exactly the same things.

  • Zeno Zaplaic

    Nice article! It’s worth mentioning that the new Sass 3.3rc3 makes writing BEMs a lot sweeter

    .steps {
    &__item {
    &–first { .. }
    &–last { .. }
    &–active { .. }
    &–done { .. }
    &__link { .. }

    • Thomas Dobber

      I’d be careful with writing your BEM syntax like this. For one, It would make the Inception rule a lot harder to check and you’d actually have to look up the tree to understand which class name you are dealing with. I’ve been thinking about maybe just using this for modifiers.

      • seangore

        +1 – you are also adding external dependencies and adding unnecessary coupling to the project. IMO &– makes way more sense, and it is now native SASS. No reason not to use it.

        If the reader doesn’t understand the current context of &, you can slap them in the face.

      • Daniel Tonon

        If you keep scss modular with only 1 scss file per module then it makes finding rules easy. The module scss will tend to be small enough to find the element class easily but if not, you can search for the “__element” part of the name within the current file.

    • Yes, indeed. In fact, Stuart Robson (the curator of SassNews) wrote a neat little blog post about this:

      However I can see two downsides to this syntax: for one, as Thomas Dobber said, it makes quite hard to spot what’s going on and how nested you currently are.

      Secondly, this makes impossible to fuzzy-search any selector in a project, which can be a problem. I have still not moved to this syntax at work and I don’t think I will ever do so, even if I like it much.

      That being said, if I decide to use this syntactic sugar, I think I will do it through mixins. I find it very ugly as is, and my Sass syntax highlighter seems to panic with it so far. I like something like this though:

      .module {
      property: value;
      @include element('heading') {
      property: value;
      @include modifier('disabled') {
      property: value;

      Or even `b()`, `e()` and `m()` to be even shorter.

  • Thomas Dobber

    Using mixins for media queries is starting to feel like cheating to me. Don’t get me wrong I’ve been using them and you can use them to do some cool things (like creating separate stylesheets for old IE), but there is a perfectly good syntax for media queries already.

    I agree with everything you mention in your styleguide and my personal taste is exactly the same (to the point, although I really need to start commenting more), but I think it is very important to stay as close to the original syntax as possible the biggest reason for that being that it makes it even easier for fellow web developers to understand.

    I’d suggest using variables in media queries instead. Besides, it is good to keep in mind that: media query breakpoints should not be used much as they should only imply major layout changes and that once we can start using element queries properly we won’t need to name breakpoints because they will be scoped to an element itself.

  • I enjoy reading articles like this, it’s always nice to get insight into how my methods compare with others in our field.

    Thanks for sharing.

  • Matt Soria

    Thanks for sharing this brother! I follow most of the same guidelines, but I’m constantly struggling with class naming conventions. I try to stick to BEM, but sometimes it’s not obvious what to do with it, and sometimes I”ll look back at the way I named some classes and think, “No, it obviously would be this way…”. I’m interested in the points that Dan Tello made in this article though:

  • jokeyrhyme

    Anyone out there have experience using , or ? Which one is your favourite? Why? How do they compare?

  • seangore

    I don’t think assigning block-level comments to inline comments is at all useful. If anything, it confuses the reader. Why are you doing this? Do you really think it makes your code clearer? Whenever I see code like this, I remove it. I am constantly looking back, asking myself “Was this part number 2?”. Inline comments are much easier to read, and we know which line they correspond to. (By inline comments, I do not mean //, but you can also use /* */ if you want, just do it at the end of the line — or even in between).

  • I really think it makes code cleaner, but I can understand why people prefer adding comments at the end of the rule or between two rules rather than before the selector as a whole block.

    I’ve been using this for about 2 years now and I really enjoy commenting this way. I don’t like adding comments between rules, it looks messy to me.

  • I’d say if you’re looking for a naming convention, BEM is probably the easiest choice. It’s easy to use and easy to get used to.

    SMACSS is more like an architecture guide. It’s not just about naming components, it’s also about organizing them, using them and generally speaking keeping a clean and organized project structure.

    Regarding OOCSS now, I don’t like it. I just don’t feel comfortable at all with naming conventions and stuff. It looks messy in my opinion. But again that’s just me.

    • dapinitial

      Curious what all have to say about Web Components and making up your own style sheets and being more declarative such as: All attributes can be referenced and can be boolean by nature and we can use data-attr. Maybe I am late to the party but that’s how I’ve been doing things lately. Polymer sort of is going this direction and that’s what I gathered from the Google I/O of recent. Could even name space by prefixing with an initial of your project or something.

      OOCSS is weird in many ways out of the box but that’s because it’s more of an approach with lots of tidbits that I am sure were helpful for a particular project before it was published back in 2011 or whenever. Whenever I have to build a site and we don’t know if we can use the latest I always start with the .line and .lastUnit and .unit classes. It’s all I really need to have a perfect layout everytime. I don’t use a grid system or anything and I am sure people will through me under a bus but I just identify modules and determine how they are supposed to display relative to containers and viewports and do the math to ensure that they calculate properly. I like creating Sass responsive mixins for breakpoints and type and everything now… but line and lastUnit are definitely nice to have in the toolbox. I can pretty much create IE8-9+ layouts foolproof and they work just as well in modern browsers so it’s pretty much just looking out for people in healthcare and in the goverment and overseas who are up to speed with all us rabbits.

      • dapinitial

        weird I didn’t mean for it to post =”” for my attributes. Should have camel cased my components as well… and i know we are supposed to x- prefix them

  • I am not quite sure what to think about Dan’s article. I feel like it doesn’t do much more than adding complexity. It doesn’t solve much in my opinion.

    That being said, I like the idea of class names starting with a dash. They look fun and hacky.

    • Matt Soria

      Yeah, I haven’t tried them out yet, but I could see why they would work, so I might just give ’em a go.

  • Hey. You should probably update your mixin in order to:
    – avoid looping through the whole map every time, it’s heavy
    – deal with unrecognized breakpoint

    Here is what I suggest:

    @mixin breakpoint($name) {
    @if not index(map-keys($breakpoints), $name) {
    @warn "Invalid breakpoint `#{$name}`.";
    @else {
    @media (min-width: map-get($breakpoints, $name)) {

    • jkinley


      Why index(map-keys($map), $key) for determining if map contains a key and not map-has-key($map, $key)?



      • The only reason I can think of is that it was 3 years ago and I wasn’t as confident with Sass as I am now. Use `map-has-key` for that. :)

        • jkinley

          No worries. Thanks so much for all your contributions. Cheers!

  • manuelwieser

    Nicolas Gallagher uses a slightly different naming conventions now in his SUIT framework which I like more than the one he mentions in the referenced article.

    The difference is, that he sets block names in pascal case, elements and modifiers in camel case. Just thought I’d share if someone is unsure about all the hyphens and underscores ;)


  • While I agree that BEM has its merits, I still think it’s a messy and ugly way to go about things. Even on a small snippet of code like the step-wizard module example, legibility goes right out the window when you have more than one class per child element.

    I prefer the way SMACSS does modules where you just prefix the block name to child elements (ex: .block and .block-title, .block-text, etc.).

    All this double underscore and double dash business seems like overkill for most projects. One thing good thing about BEM for me is that the name is inherently funny because of this song :)

  • Christian

    Great article, please keep us posted on new discoveries.

    The only suggestion I might add is to prefix variable names with a category. For instance with colors I normally name my variables like:

    $color-main, $color-secondary, $color-highlight

    This way I can simply type “$col..” and my IDE will come up with a list of my available colors.

  • Paul Ferguson

    Some nice solid practices here, cheers for sharing.

    The media mixin is a little constraining, defining brakepoints base on content as well as the three predefined widths is very useful. Tacking on one last else and using the variable would do the trick although may want to update the name,

    @else {
    @media (min-width: $name) {

    To go one step further I’ve been using this approach form this great post which allows for CSS only safe mobile first media queries.

  • Hugo, you did well! I really enjoy to read about your well organised workflow!

    Only one thing what is still confusing for me is this spaces vs tabs in our CSS. Why everyone recommend to use only 2 spaces? Why not 4 for instance (what is default value in Sublime Text). 4 spaces makes my CSS more readable. We don’t need to nest our code very deep (Inception rule). Why, why why? My work convention is very similar but i still prefer my old good tab (4 spaces).

    • I’m not sure there is any reason other than taste here. I think 2 spaces are enough most of the time. It’s easy to indent, easy to type, no matter the environment, the shortcuts or whatever. I like 2 spaces.

      • Tabs can be interpreted as any number of columns depending on your environment. A space is always a single column. Hence, the only way to guarantee consistent code across multiple environments is to use spaces.

  • One thing I struggle with is nesting. By being able to nest in CSS, doesn’t it render your BEM redundant? For example: step__link can be express as step { .link {} } in SASS. So why bother doing step { .step__link {} } ?

    • Daniel Tonon

      The benefit is both reduced specificity and also it makes it clear what module the element class belongs to. It’s very common to have multiple different module classes applied to the same element. This makes it clear in the html what classes belong to what modules.

  • Good read! We’re recently shared our ides on several approaches to responsive CSS and how Sass 3.3 helps with it – take a peek at if you’re interested.

  • francoismassart

    I also like to use CSS Comb to sort the “native” CSS properties.

  • You shouldn’t do `.step { .step__link {} }` but only `.step__link {}`. That’s the whole point of BEM.

  • Sumidumi

    Very nice article. It’s the structuring concept that can be taken forward and really needs some thinking to organize CSS. I feel that too many underscores and dashed lines are hard to keep track. By the way, isn’t it HTML classes and not ‘CSS classes’? Somewhere I read (i think in Tab Atkins site) that there is nothing called CSS classes. I don’t have the link to share though (lost in the forest of my favorites!)

    Thanks for the beautiful writeup.

    • Daniel Tonon

      With the too many dashes problem. You could use camel case instead to keep the grouping clear:

      Instead of

  • garcilaso

    And what about when you have a reusable component, for instance:

    On the home page I want the li to be display:inline, and in the about us page to be display:block.
    The thing is I am not writing the code twice, I am including this chunk of code via php include.

    So I can not write this:

    How should I add the modifier to have the same reusable component displaying in two different ways? Should I wrap it inside of a container?


    • Daniel Tonon

      I wouldn’t name the modifier based on where it is used. More for what it is trying to achieve.

      So instead of “about” use “inline” so that if you want to use those same styles somewhere else it still makes sense.

  • Andrew

    Came across this website the other day and found it very useful as a somewhat Front-End newbie: It has a number of similar suggestions as what you mention in your article. Just wanted to share another resource for those interested.

  • I know this is older but just came across it.
    Nice collection! I think i’m going to adopt your BEM conventions. But everything else is pretty much spot on!

    Except for the media queries. I use vars to define my breakpoints, and pass them on the fly

    @mixin respond( $bp, $determinate : ‘max’ ) {
    @media screen and ( #{$determinate}-width: $bp ) { @content; }

    • Daniel Tonon

      You should try the mq-scss mixin on npm.

      @include mq (max, 600px){…}
      @media screen and (max-width: 600px){…}

      @include mq (inside, 960px, 600px){…}
      @media screen and (max-width: 960px) and (min-width: 601px){…}

      It has way more features than just the 2 examples I gave above though. Like creating “or” statements for targeting multiple different screen size ranges in the 1 media query with the same simple syntax.

  • Dmitri

    Great article! Thank you.

Get the latest in Front-end, once a week, for free.