Multiple, nested containers with CSS
Tags: css, tutorial, webdev, beginners
Published: 2020-02-03 15:14:05

Almost every CSS framework provides one container utility class only, but I like the idea of having **multiple container sizes** in my CSS toolkit.

When I started building the CSS framework for the [**Cruip templates**](https://cruip.com), I came up with the decision of including 3 different container classes:

* `container`, for larger containers (1080px)
* `container-sm`, for smaller containers (896px)
* `container-xs`, for extra-small containers (620px)

Since we are not using a grid system, having multiple container widths might come in handy to have more control and more width options.

![x-ray of Cruip containers](https://dev-to-uploads.s3.amazonaws.com/i/lmaxd1l8c2qncuoldf53.png)
*Containers in use on [Surface template](https://cruip.com/surface/)*

Let's start from the beginning:
```scss
$container--width:      1080px;
$container--width-sm:   896px;
$container--width-xs:   620px;
$container--padding:    16px;

.container,
.container-sm,
.container-xs {
  width: 100%;
  margin: 0 auto;
  padding-left: $container--padding;
  padding-right: $container--padding;
}

.container {
  max-width: $container--width + ( $container--padding * 2 );
}

.container-sm {
  max-width: $container--width-sm + ( $container--padding * 2 );
}

.container-xs {
  max-width: $container--width-xs + ( $container--padding * 2 );
}
```
Normally, a container has some padding or margin on left and right sides, and when you try nesting a container into another one, that will result in **misalignment issues** below a certain breakpoint.
{% codepen https://codepen.io/pasqualevitiello/pen/abzgOKg %}
First thing to do is reset the padding of nested containers.
```scss
.container,
.container-sm,
.container-xs {

  .container,
  .container-sm,
  .container-xs {
    padding-left: 0;
    padding-right: 0;
  }
}
```
Seems easy - and it is indeed - but we need to adjust the containers width as well.
```scss
.container {

  .container-sm {
    max-width: $container--width-sm;
  }

  .container-xs {
    max-width: $container--width-xs;
  }
}

.container-sm {

  .container-xs {
    max-width: $container--width-xs;
  }
}
```
Everything is on the right track but code is still perfectible. Due to the presence of multiple containers, outputted CSS will be a bit verbose. Let's [*DRY*](https://en.wikipedia.org/wiki/Don't_repeat_yourself) things a little!

Above code can be refactored using the [[attribute*=value] selector](https://www.w3schools.com/cssref/sel_attr_contain.asp).
```scss
[class*=container] {

  [class*=container] {
    padding-left: 0;
    padding-right: 0;
  }

  .container-sm {
    max-width: $container--width-sm;
  }

  .container-xs {
    max-width: $container--width-xs;
  }
}
```
And here is the result:
{% codepen https://codepen.io/pasqualevitiello/pen/YzPoGqO %}
Final CSS code:
```scss
$container--width:      1080px;
$container--width-sm:   896px;
$container--width-xs:   620px;
$container--padding:    16px;

.container,
.container-sm,
.container-xs {
  width: 100%;
  margin: 0 auto;
  padding-left: $container--padding;
  padding-right: $container--padding;
}

.container {
  max-width: $container--width + ( $container--padding * 2 );
}

.container-sm {
  max-width: $container--width-sm + ( $container--padding * 2 );
}

.container-xs {
  max-width: $container--width-xs + ( $container--padding * 2 );
}

[class*=container] {

  [class*=container] {
    padding-left: 0;
    padding-right: 0;
  }

  .container-sm {
    max-width: $container--width-sm;
  }

  .container-xs {
    max-width: $container--width-xs;
  }
}
```