CSS Nesting Without Preprocessors

It has been more than a decade since developers decided to jump directly to a preprocessor for their CSS needs instead of pure CSS coding. One of the reasons is the ability to create variables and use nesting in their code to make it easier to read and maintain. However, a lot has changed since Sass was first created, and later other preprocessors like LESS and Stylus became popular because CSS now supports a lot of the features that made preprocessors favored years ago. I see this development as what JavaScript has evolved into including a lot of features from jQuery which eventually made the library less useful.

Today, we are going to cover a little bit of CSS Nesting because it will soon be supported by all major browsers. But, at the moment of this writing, it is only supported by the latest version of Chrome, Edge, and Safari.

Before preprocessors, there was a lot of code duplication in terms of selectors because developers need to type the selectors over and over to give them context and specificity. The following example styles a navigation element.

nav ul {
  margin: 0;
  padding: 0;
}
nav ul li {
  padding: 1rem;
  border-bottom: 1px solid #000;
}

However, in Sass, it was more intuitive because you could use the parent-child relationship in CSS similarly to how it looks in HTML. Thus, with Sass, you could do something like the following example that would generate the same code.

nav {
    ul {
        margin: 0;
        padding:0;
        li {
            padding: 1rem;
            border-bottom:1px solid #000
        }
    }
}

This makes more sense and became popular among developers because you could see the relationship between the elements and how they are related in the HTML. In CSS we can do something similar with the use of & or nesting selector.

nav {
    & ul {
         margin: 0;
         padding:0;
       
     & li {
             padding: 1rem;
             border-bottom:1px solid #000
         }
     }
 }

As using a type selector within a nested selector is not valid, it is necessary to use the nesting selector. But, if you were using a class, for example, you don’t need the nesting selector as seen in the next example.

nav {
    .container {
        margin: 0;
        padding:0;
     
      .list-item {
            padding: 1rem;
            border-bottom:1px solid #000
        }
    }
}

In the future, preprocessors might become obsolete as jQuery did when the browser implemented similar features. But, this means that it is another built tool or process that we don’t have to depend on in order to create web pages. The future looks bright for front-end development and the more features are used in the browsers, the better the development experience improves without hurting the user experience and the clarity of the code.

Teylor Feliz
Teylor Feliz

Teylor is a seasoned generalist that enjoys learning new things. He has over 20 years of experience wearing different hats that include software engineer, UX designer, full-stack developer, web designer, data analyst, database administrator, and others. He is the founder of Haketi, a small firm that provides services in design, development, and consulting.

Over the last ten years, he has taught hundreds of students at an undergraduate and graduate levels. He loves teaching and mentoring new designers and developers to navigate the rapid changing field of UX design and engineering.

Articles: 182