Reputation: 24778
I have a quite simple layout but a hard problem.
In short
:before
:after
with position absolute but that fails when I use overflow-y
scroll on the containers.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>
Upvotes: 1
Views: 57
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
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