Imarc

How-to guide for creating edge-to-edge color bars that work with a grid

Marcel Moreau, Lead UX Engineer
Posted on Jun 16, 2020

Here’s how to reliably create column background colors without the need for images or pseudo-elements.

Faux background colors using linear-gradient()

See the demo

Variation in color helps orient users to different parts of a user interface. Sidebars, also called asides, often hold supplementary content, links, and filtering functionality. Giving these sidebars a background color can reinforce to the user that it’s important, but separate from the main content.

Ns1 resources
NS1 uses a light gray color for its Resources page sidebar.
Ssc layer
SecurityScorecard’s contact form is surrounded by color to help visually separate it from adjacent content.

Column grids, wide screens, and edge-to-edge

Column grids have been prevalent on the web for a long time. It’s a win for everyone. Designers can create proper content hierarchy, engineers have more control and structure over how interfaces are built, and users can digest information with greater ease.

Widescreen monitors and contemporary laptops have a wide display resolution, eclipsing the max-widths of common grid container sizes. As of this writing, the largest default grid container widths for Bootstrap, Foundation and TailwindCSS are 1140px, 1200px, and 1280px, respectively.

How can we ensure that background-colors assigned to our columns can gracefully extend in an “edge-to-edge” fashion? Previous solutions included using a large, absolutely positioned pseudo-element (::before, ::after), or vertically repeating background-images. Both have limitations. Let’s make this easier on ourselves.

Abb bundle detail
An Atlantic Broadband design composition includes a right rail that extends beyond its site container.

Using linear-gradient() and some simple math

I will be using Bootstrap’s grid system in my demo, but this can be adapted to any.

For this exercise, you can think of the linear-gradient() CSS property as one color turning into another, running from the left to the right side of the screen. We can control where the first color stops and where the second one continues.

For example, if we want two columns of color split evenly on a screen, we can use a 50% color-stop value in a linear-gradient(). This divides our colored columns in half on any screen width. In this codepen, change 50% to 75% or 90% or even a pixel value to better understand color stops.

This is great, but more often than not we will need our color stops to align with a site’s grid system. How can we do that but also have an edge-to-edge appearance? Let’s combine some linear-gradient(), calc(), and some math in a Sass mixin.

What do we need to know?

Our Sass mixin will need to know some baseline items. You can declare these with Sass variables.

Grid container size
$container: 1140px;

We are matching Bootstrap’s 1140px default with our $container variable.

Grid column amount
$gridColumns: 12;

How many columns does your grid system contain in total?

When called, our mixin will expect two arguments, with additional optional arguments:

  1. $cols: how many columns wide should the first color be?
  2. $colorTwo: the second color in our left-to-right gradient.
  3. $colorOne(optional): the first color in our left-to-right gradient. (we will defaults to transparent, since we will often only want a sidebar color)
  4. $colSelector(optional): the column class your grid system uses (this example defaults to Bootstrap’s)
  5. $rowSelector(optional): the row class your grid system uses (this example defaults to Bootstrap’s)

Our mixin performs some division to find out what percentage $cols is of $gridColumns. Then we multiply our $container by this percentage to find where our first color stop should be.

$colPercent:$cols / $gridColumns;

$colWidth: $colPercent * $container;

Let’s call the mixin with some arguments and look at Sass, using plain english during both to better understand what is going on.

Let’s name our mixin fauxColumns. Remember our important arguments:

@mixin fauxColumns($cols, $colorTwo, $colorOne: transparent)

Let’s call the mixin and pass some values.

@include fauxColumns(9, #ff675b, #d2e6ea);

“I would like edge-to-edge colors, please. #d2e6ea should take up 9 of my grid’s 12 columns. #ff675b should take up the rest.”


@mixin fauxColumns(
        $cols, 
        $colorTwo, 
        $colorOne: transparent, 
        $colSelector: 'col-', 
        $rowSelector: 'row'
        ) {
            
    $colPercent: $cols / $gridColumns;
    $colWidth: $colPercent * $container;

    .#{$rowSelector} > [class^='#{$colSelector}']:nth-child(1) {
        background-image: 
            linear-gradient(
                to bottom, 
                $colorOne, 
                $colorOne
            );
    }
    
    .#{$rowSelector} > [class^='#{$colSelector}']:nth-child(2)
        {
        background-image: 
            linear-gradient(
                to bottom, 
                $colorTwo, 
                $colorTwo
            );
    }

    @media (min-width: 768px) {
        .#{$rowSelector} 
        > [class^="#{$colSelector}"]:nth-child(n) {
            background-image: none;
        }
        background-image: 
            linear-gradient(
                to right, 
                $colorOne percentage($colPercent), 
                $colorTwo 1%
            );
    }

    @media (min-width: 1140px) {
        background-image: 
            linear-gradient(
                to right, 
                $colorOne calc((50% - (#{$container} / 2) + #{$colWidth})), 
                $colorTwo 1%
            );
    }
}
More Thoughts