CSS Nesting

CSS Nesting

Nesting Selector Styles in CSS

ยท

5 min read

When writing HTML you've probably noticed that it has a clear nested and visual hierarchy. CSS, on the other hand, doesn't SO FAR

If you're not familiar with CSS preprocessors (scripting languages that extend the default capabilities of CSS) like Sass, Less, Stylus, and more. these preprocessors give you the ability to use variables, nest css selectors within selectors, and much more

For a long time, a big reason to use preprocessors like Sass was that it has the ability to use variables but now css has variables too just as that css will soon have nesting as well

๐Ÿ€ About Nesting

Nesting CSS selectors allowing you to write more modular and maintainable style sheets and allowing you to nest your CSS selectors in a way that follows the same visual hierarchy of your HTML.

Currently, this feature is in the draft and is not available in browsers yet but we will see how to use it today, But before that let's take a closer look at nesting and how it can improve your code

Usually, CSS Rules for even moderately complicated web pages include lots of duplication for the purpose of styling related content for example in the below code we have to continually refer to table.colortable:

table.colortable td {
  text-align: center;
}

table.colortable td.c {
  text-transform: uppercase;
}

table.colortable td:first-child, table.colortable td:first-child+td {
  border: 1px solid black;
}

table.colortable th {
  text-align: center;
  background: black;
  color: white;
}

โš” The &

Just like in sass the ampersand (&) is used to reference the parent selector, in the below example, we're referencing the table data using ampersand to apply the text alignment

table.colortable {
  & td {
    text-align: center;
    &.c { text-transform: uppercase }
    &:first-child, &:first-child + td { border: 1px solid black }
  }

  & th {
    text-align: center;
    background: black;
    color: white;
  }
}

Besides removing duplication, the grouping of related rules improves the readability and maintainability of the resulting CSS.

๐Ÿ”” Note:

Nesting allows the grouping of related style rules, But be aware that overly nested rules will result in over-qualified CSS that could prove hard to maintain and is generally considered bad practice

If you're using a list of selectors each selector must begin with a nested selector (&) for example in the below example, if we wanted to target divider class we can't just add .divider it must be &.divider

.list {
  font-size: 2rem;
  &.item, &.divider {
    padding: 0.5rem;
  }
}

๐ŸฅŠ at nest

There's another way to nest using the @nest rule, this rule allows you to get around some of the limitations of the ampersand (&) nesting selector alone

For instance what if you want to select a parent that is outside of the scoped, we can add @nest

.wrapper {
  ...
}

.post {
  ...
  @nest .wrapper & {
    background: blue;
  }
}

The @nest rule allows us to do this, it only requires that a nesting selector be somewhere within the selection, it doesn't have to be at the beginning but again every selector must have a nesting selector still

๐Ÿšง Nesting Conditional Rules

Also, we can even nest conditional rules such as media queries generally, we'll see media queries toward the bottom of a style sheet where you then have to reference back to an earlier selector to change their styles at various screen sizes

.foo {
  display: grid;
}

@media (orientation: landscape) {
 .foo {
   grid-auto-flow: column;
 }   
}

Nesting allows us to put these right in the main selection but again these need to contain a nesting selector

.foo {
  display: grid;

  @media (orientation: landscape) {
    & {
      grid-auto-flow: column;
    }   
  }
}

๐Ÿงช PostCSS Nesting

Currently, browsers don't support native nesting in css yet but we're going to use a post css package called PostCSS Nesting

Here we have the following slider example that we're going to convert to use nested css, where I am going to use Vite to quickly set it up since Vite supports post css out of the box this is going to be easy

All we have to do in order to set up it is to follow these instructions:

  • Open your terminal and type
npm init @vitejs/app .
  • Type your project name, e.g. css-nesting
  • Select Vanilla as a framework
  • Select JavaScript as a variant
  • Install all packages
npm i
  • Install PostCSS Nesting
npm i postcss-nesting -D
  • Use the following HTML, CSS from the above CodePen in your index.html and style.css
<div class="slider">
  <i class="slider__image fa fa-codepen"></i>
  <div class="slider__content">
    <h2 class="slider__caption">codepen</h2>
    <p class="slider__txt">
      CodePen is a social development environment for 
      front-end designers and developers. Build
      and deploy a website, show off your work, build test cases to
    </p>
  </div>
</div>
.slider {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.slider__content {
  padding: 2rem;

}
.slider__image {
  color: #2196F3;
  font-size: 8rem;
}

.slider__caption {
  margin: 2rem 0 1rem;
  text-transform: uppercase;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
  font-weight: 500;
}

.slider__txt {
  max-width: 400px;
  color: #999;
}

๐Ÿงฐ PostCSS Configurations

All you have to do is to create a new file called postcss.config.js and add the following configurations, after that we already ready for nesting ๐ŸŽ‰

module.exports = {
  plugins: [require('postcss-nesting').default],
};

๐Ÿƒโ€โ™‚๏ธ Let's Nest!

After applying the nesting rules we already mentioned before, we will end up with the following result and it works ๐Ÿš€๐ŸŽ‰:

.slider {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;

  & .slider__image {
    color: #2196F3;
    font-size: 8rem;
  }

  & .slider__content {
    padding: 2rem;

    & .slider__caption {
      margin: 2rem 0 1rem;
      text-transform: uppercase;
      text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
      font-weight: 500;
    }

    & .slider__txt {
      max-width: 400px;
      color: #999;
    }
  }
}


๐Ÿ“” References

Thank you for reading, If you have reached so far so let me know what do you think about css having native nesting

ย