Search code examples
htmlcsscss-grid

Span background color across viewport width


I am trying to build a responsive navigation bar with CSS Grid layout that spans across the viewport width, but the inner items should be centred and aligned with other container elements on the page.

The result that I want is displayed in the code below, however, I don't feel that this is an elegant solution as I used 2 separate <div> elements stacked on top of each other.

One <div> is for having the items centred and the second <div> is to cover the background-color across the viewport width.


Is there a better way of doing this using the CSS Grid layout?

[EDIT] I am looking for a way to make the technique reusable on multiple elements.


Please expand the code snippet to full page so the layout appears correctly

.container {
  display: grid;
  grid-template-columns: 1fr repeat(4, minmax(min-content, 150px)) 1fr;
  border: 2px solid black;
  height: 100vh;
}

.nav {
  grid-area: 1 / 2 / 1 / span 4;
  height: 50px;
  background-color: grey;
  border: 1px solid red;
  position: relative;
}

.nav-underlay {
  background-color: grey;
  grid-area: 1 / 1 / 1 / span 7;
  height: 50px;
}

.content {
  grid-area: 2 / 2 / 2 / span 4;
  height: 200px;
  background-color: grey;
  border: 1px solid red;
}
<body class="container">
  <div class="nav">this box should stay aligned with the content box</div>
  <div class="nav-underlay"></div>
  <div class="content">Content box</div>
</body>


Solution

  • Since the background area you're looking to expand is for decorative purposes only (i.e., you're not using that area to convey content), then you can use CSS pseudo-elements instead of an actual HTML element.

    Pseudo-elements become grid items when applied to a grid container (read more).

    .container {
      display: grid;
      grid-template-columns: 1fr repeat(4, minmax(min-content, 150px)) 1fr;
      border: 2px solid black;
      height: 100vh;
    }
    
    .nav {
      grid-area: 1 / 2 / 2 / span 4;
      height: 50px;
      background-color: grey;
      border: 1px solid red;
      position: relative;
    }
    
    .container::before {
      grid-area: 1 / 1 / 2 / 2;
      content: "";
      background-color: grey;
      height: 50px;
    }
    
    .container::after {
      grid-area: 1 / -1 / 2 / -2;
      background-color: grey;
      height: 50px;
      content: "";
    }
    
    .content {
      grid-area: 2 / 2 / 2 / span 4;
      height: 200px;
      background-color: grey;
      border: 1px solid red;
    }
    <body class="container">
      <div class="nav">this box should stay aligned with the content box</div>
      <div class="content">Content box</div>
    </body>

    jsFiddle demo