Misha Moroshko
Misha Moroshko

Reputation: 171321

How to make a grid item inside a max-width container to span the full width?

CSS grid is located on a page with a max-width:

enter image description here

body {
  outline: 1px solid black;
}

.max-width {
  max-width: 400px;
  margin: 0 auto;
}

.grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}

.first-grid-item {
  grid-column: 1 / -1;
  background-color: #ccc;
}

.second-grid-item {
  grid-column: 1 / -1;
  background-color: tomato;
}

@media (min-width: 576px) {
  .max-width {
    max-width: 500px;
  }
  .first-grid-item {
    grid-column: 1 / 9;
  }
  .second-grid-item {
    grid-column: 9 / 13;
  }
}
<div class="max-width">
  <div class="grid">
    <div class="first-grid-item">First</div>
    <div class="second-grid-item">Second</div>
  </div>
</div>

On smaller screens, the layout changes and the second grid item is placed below the first one:

enter image description here

Now, a new requirement comes in to add a full-width background color to the second item on the smaller screens so it looks like this:

enter image description here

How would you achieve this?


Notes:

Upvotes: 5

Views: 2663

Answers (3)

Temani Afif
Temani Afif

Reputation: 272589

On small screen you don't really need a grid.

Here is my try:

body {
  outline: 1px solid black;
}

.first-grid-item{
  max-width: 400px; /* Only restrict the first item */
  margin: 0 auto;
}

.first-grid-item {
  background-color: #ccc;
}

.second-grid-item {
  background-color: tomato;
  padding:0 calc(50% - 200px); /* to have the content inside the 400px (remove this if not)*/
}

@media (min-width: 576px) {
  .max-width {
    max-width: 500px;
    margin: 0 auto;
  }
  /* only here we need the grid */
  .grid {
    display: grid; 
    grid-template-columns: repeat(12, 1fr);
  }
  /**/
  .first-grid-item {
    grid-column: 1 / 9;
    margin:0; /* reset margin */
    max-width: 100%; /* reset max-width */
  }
  .second-grid-item {
    grid-column: 9 / 13;
    background-color: lightblue;
    padding:0; /* reset padding */
  }
}
<div class="max-width">
  <div class="grid">
    <div class="first-grid-item">First</div>
    <div class="second-grid-item">Second</div>
  </div>
</div>

You can also do it like below:

body {
  outline: 1px solid black;
}

.max-width {
  max-width: 500px;
  margin: 0 auto;
}

.grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}

.first-grid-item {
  grid-column: 1 / 9;
  background-color: #ccc;
}

.second-grid-item {
  grid-column: 9 / 13;
  background-color: lightblue;
}

@media (max-width: 576px) {
  .max-width {
    max-width: 100%;
  }
  .grid {
    display: block;
  }
  .first-grid-item {
    max-width: 400px;
    margin: 0 auto;
  }
  .second-grid-item {
    background-color: tomato;
    padding: 0 calc(50% - 200px);
  }
}
<div class="max-width">
  <div class="grid">
    <div class="first-grid-item">First</div>
    <div class="second-grid-item">Second</div>
  </div>
</div>

To have the different coloration, mutliple background can easily do it

body {
  outline: 1px solid black;
}

.max-width {
  max-width: 500px;
  margin: 0 auto;
}

.grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}

.first-grid-item {
  grid-column: 1 / 9;
  background-color: #ccc;
}

.second-grid-item {
  grid-column: 9 / 13;
  background: 
    linear-gradient(lightblue,lightblue) content-box,
    tomato;
}

@media (max-width: 576px) {
  .max-width {
    max-width: 100%;
  }
  .grid {
    display: block;
  }
  .first-grid-item {
    max-width: 400px;
    margin: 0 auto;
  }
  .second-grid-item {
    padding: 0 calc(50% - 200px);
  }
}
<div class="max-width">
  <div class="grid">
    <div class="first-grid-item">First</div>
    <div class="second-grid-item">Second</div>
  </div>
</div>

Upvotes: 2

user7148391
user7148391

Reputation:

Why not Simply move the width constraint to the grid ?

body {
  outline: 1px solid black;
}


/* Became .wrapper */


/* .max-width {
  max-width: 400px;
  margin: 0 auto;
} */

.grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}

.first-grid-item {
  grid-column: 1 / -1;
  background-color: #ccc;
}

.second-grid-item {
  grid-column: 1 / -1;
  background-color: tomato;
}

@media (min-width: 576px) {
  /* Became .wrapper */
  /* .max-width {
    max-width: 500px;
  } */
  .first-grid-item {
    grid-column: 1 / 9;
  }
  .second-grid-item {
    grid-column: 9 / 13;
  }
}


/* New */

.grid {
  max-width: 400px;
  margin: 0 auto;
}

.wrapper {
  background: linear-gradient(orange, orange) 0 100% / 100% 50% no-repeat;
}

@media (min-width: 576px) {
  .grid {
    max-width: 500px;
  }
  .wrapper {
    background: none;
  }
}
<p>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam.
</p>
<div class="wrapper">
  <div class="grid">
    <div class="first-grid-item">First</div>
    <div class="second-grid-item">Second</div>
  </div>
</div>
<p>
  There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable.
</p>

Upvotes: 0

disinfor
disinfor

Reputation: 11532

The only way I can think of to do this is using a ::before and ::after element on the second-grid-item and overflowing the body. You would need to essentially set overflow: hidden on the body for this to work so it doesn't set horizontal scrolling:

body {
  outline: 1px solid black;
  overflow: hidden;
}

.max-width {
  max-width: 400px;
  margin: 0 auto;
}

.grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}

.first-grid-item {
  grid-column: 1 / -1;
  background-color: #ccc;
}

.second-grid-item {
  grid-column: 1 / -1;
  background-color: tomato;
  position: relative;
}

.second-grid-item::before,
.second-grid-item::after {
  content: '';
  display: block;
  position: absolute;
  left: -50%;
  top: 0;
  width: calc( 100% - 200px);
  height: 100%;
  background: powderblue;
}

.second-grid-item::after {
  left: auto;
  right: -50%;
}

@media (min-width: 576px) {
  .first-grid-item {
    grid-column: 1 / 9;
  }
  .second-grid-item {
    grid-column: 9 / 13;
  }
  .second-grid-item::before,
  .second-grid-item::after {
    display: none;
  }
}
<div class="max-width">
  <div class="grid">
    <div class="first-grid-item">First</div>
    <div class="second-grid-item">Pharetra eros mi eros accumsan dui. Pellentesque ipsum iaculis. Mi neque in nonummy venenatis vestibulum. Class egestas adipiscing nisl tellus quam ut in amet. Nostra nunc leo lorem eget ipsum elit eget metus nam sed pede. Nam nibh risus sit dui nullam.
      Consequat luctus tempus.
    </div>
  </div>
</div>

Here's a codepen: https://codepen.io/chrislafrombois/pen/qBOMopG

Upvotes: 0

Related Questions