Jens Törnell
Jens Törnell

Reputation: 24778

Css centered layout with background spaning outside element

I have a quite simple layout but a hard problem.

In short

html,
body {
padding: 0;
margin: 0;
height: 100%;
}

.wrap {
  width: 100%;
  height: 100%;
  background: #eee;
}

main {
  margin: 0 auto;
  width: 600px;
  background: #ddd;
  height: 100%;
  display: flex;
}

aside {
  background: #ccc;
  height: 100%;
  width: 100px;
  overflow-y: auto;
}

.content {
  flex: 1;
  overflow-y: auto;
}

section {
  display: block;
  width: 100%;
}

section.blue {
  background: blue;
 }
 
 section.yellow {
  background: yellow;
 }
 
 section.green {
  background: green;
 }
<div class="wrap">
  <main>
    <aside>Aside</aside>
    <div class="content">
      <section class="blue">Blue</section>
      <section class="yellow">Yellow</section>
      <section class="green">Green</section>
    </div>
  </main>
</div>

Image of how the result should look like

enter image description here

Upvotes: 1

Views: 57

Answers (2)

kukkuz
kukkuz

Reputation: 42352

A solution using CSS Grid layout - maybe it's a bit of a verbose explanation, but there you go:

  • place the aside and content into the second and third columns of 4-column grid (using grid-template-columns: 1fr 100px 500px 1fr),

  • extend the second column (aside) to the first using negative margins and padding:

    margin-left: calc(-50vw + 300px);
    padding-left: calc(50vw - 300px);
    
    

    (note that 50vw - 300px is the width of the leftmost and rightmost columns after the second and third occupy 600px)

  • similarly extend the third column (content) using:

    margin-right: calc(-50vw + 300px);
    padding-right: calc(50vw - 300px);
    
  • the content is a column flexbox with a pseduo element that takes care of the background (if this is needed),

  • the blue, yellow and green section backgrounds are extended now using padding-right: calc(50vw - 300px).

See demo below:

html,
body {
  padding: 0;
  margin: 0;
  height: 100%;
}

.wrap {
  width: 100%;
  height: 100%;
  background: #eee;
}

main {
  background: #ddd;
  display: grid; /* grid container */
  grid-template-columns: 1fr 100px 500px 1fr; /* 4 columns */
  height: 100%;
}

aside {
  background: #ccc;
  height: 100%;
  width: 100px;
  overflow-y: auto;
  grid-column: 2; /* place in second column */
  /* extend to first column */
  margin-left: calc(-50vw + 300px);
  padding-left: calc(50vw - 300px);
}

.content {
  grid-column: 3; /* place in thrid column */
  /* extend to fourth column */
  margin-right: calc(-50vw + 300px);
  padding-right: calc(50vw - 300px);
  /* column flexbox for the sections */
  display: flex; 
  flex-direction: column;
  overflow-y: auto;
}

.content:after { /* serves as background*/
  flex: 1;
  content: '';
  background: #bbb;
}

section { /* extend sections to fourth column*/
  width: 100%;
  padding-right: calc(50vw - 300px);
}

section.blue {
  background: blue;
}

section.yellow {
  background: yellow;
}

section.green {
  background: green;
}
<div class="wrap">
  <main>
    <aside>Aside - some text here some text here some text here some text here some text here some text here some text here </aside>
    <div class="content">
      <section class="blue">Blue - some text here some text here some text here some text here some text here some text here some text here some text here </section>
      <section class="yellow">Yellow - some text here some text here some text here some text here some text here some text here some text here some text here some text here </section>
      <section class="green">Green - some text here some text here some text here some text here some text here some text here some text here some text here some text here </section>
    </div>
  </main>
</div>

Upvotes: 1

Temani Afif
Temani Afif

Reputation: 273389

You can do it like below using CSS grid and some padding tricks:

html,
body {
padding: 0;
margin: 0;
height: 100%;
}

.wrap {
  height: 100%;
  background:#eee;
}

main { 
  background: linear-gradient(#ddd,#ddd) center/600px 100% no-repeat;  /*Color only 600px */
  height: 100%;
  display: grid;
  grid-template-areas:"aside aside content content";
  grid-template-columns:1fr 100px 500px 1fr
}

aside {
  background: #ccc;
  height: 100%;
  grid-area:aside;
  padding-left: calc(100% - 100px); /*the content inside only 100px on the right*/
  overflow-y: auto;
}

.content {
  overflow-y: auto;
  grid-area:content;
}

section {
  padding-right:calc(100% - 500px); /*the content inside only 500px on the left*/
}

section.blue {background: blue;}
section.yellow {background: yellow;}
section.green {background: green;}
<div class="wrap">
  <main>
    <aside>Aside</aside>
    <div class="content">
      <section class="blue"> Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue</section>
      <section class="yellow">Yellow</section>
      <section class="green">Green</section>
    </div>
  </main>
</div>

Another idea with the same trick using flexbox:

html,
body {
padding: 0;
margin: 0;
height: 100%;
}

.wrap {
  height: 100%;
  background:#eee;
}

main { 
  background: linear-gradient(#ddd,#ddd) center/600px 100% no-repeat;  /*Color only 600px */
  height: 100%;
  display: flex;
}

aside {
  background: #ccc;
  height: 100%;
  flex-basis:100px; /* main width */
  flex-grow:1; 
  overflow-y: auto;
}
aside div {
    padding-left: calc(100% - 100px); /*the content inside only 100px on the right*/
}

.content {
  overflow-y: auto;
  flex-basis:500px; /* main width */
  flex-grow:1;
}

section {
  padding-right:calc(100% - 500px); /*the content inside only 500px on the left*/
}

section.blue {background: blue;}
section.yellow {background: yellow;}
section.green {background: green;}
<div class="wrap">
  <main>
    <aside><div>Aside</div></aside>
    <div class="content">
      <section class="blue"> Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue Blue</section>
      <section class="yellow">Yellow</section>
      <section class="green">Green</section>
    </div>
  </main>
</div>

Upvotes: 1

Related Questions