Multiple, nested containers with CSS

Pasquale Vitiello - Feb 3 '20 - - Dev Community

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;
  }
}
. . . . . . . . . .
Terabox Video Player