DEV Community

Cover image for Multiple, nested containers with CSS
Pasquale Vitiello for Cruip

Posted on

Multiple, nested containers with CSS

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, 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
Containers in use on Surface template

Let's start from the beginning:

$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.

First thing to do is reset the padding of nested containers.

.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.

.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 things a little!

Above code can be refactored using the [attribute*=value] selector.

[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:

Final CSS code:

$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;
  }
}

Top comments (0)