I need the element cnt-right to be height 100% of its sibling.
It doesn't have a parent element, only siblings.
Is it possible to accomplish this with CSS? Or do I have to use javascript?
I have this estructure: jsFiddle
.column {
display: block;
min-height: 50px;
background-color: #ccc;
text-align: center;
float: left;
}
.decktop-12 {
width: 100%;
}
.decktop-8 {
width: 66%;
}
.decktop-4 {
width: 33%;
}
.cnt {
background-color: #995595;
}
.cnt-right {
background-color: #559959;
}
<div class="mobile-12 decktop-12 cnt-top column">
Content top
</div>
<div class="mobile-12 decktop-8 cnt column">
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
</div>
<div class="mobile-12 decktop-4 cnt-right column">
Content - right
</div>
<div class="mobile-12 decktop-12 cnt-bottom column">
Content bottom
</div>
You can use only CSS creating a grid layout, javascript is not necessary: https://css-tricks.com/snippets/css/complete-guide-grid/
This is an example of what you could do:
.grid{
display: grid;
grid-template-columns: 2fr 1fr;
grid-template-areas:
"header header"
"content right"
"footer footer"
}
.header {
grid-area: header;
}
.content {
grid-area: content;
background-color: #995595;
}
.right {
grid-area: right;
background-color: #559959;
}
.footer {
grid-area: footer;
}
.header, .footer{
min-height: 50px;
background-color: #ccc;
}
.grid > * {
text-align: center;
}
<div class="grid">
<div class="header">
Content top
</div>
<div class="content">
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
</div>
<div class="right">
Content - right
</div>
<div class="footer">
Content bottom
</div>
</div>
You can use css grid or flex displays.
I recommand you to have a look at :
https://css-tricks.com/snippets/css/complete-guide-grid/
https://css-tricks.com/snippets/css/a-guide-to-flexbox
And also at how Bootstrap 4 implemented their grid using flex :
https://getbootstrap.com/docs/4.0/layout/grid/
You will have more control over how your grid behaves and possibilities than with float.
I made you an example with using flex. In this example flex evens the columns height by default and looks similar to code written with float :
<div class="row">
<div class="mobile-12 desktop-12 column c1">
Content top
</div>
<div class="mobile-12 desktop-8 column c2">
Content - main
<br><br><br>
</div>
<div class="mobile-12 desktop-4 column c3">
Content - right
</div>
<div class="mobile-12 desktop-12 column c1">
Content bottom
</div>
</div>
<style>
.row {
display: flex;
flex-wrap: wrap; /* Allow multi-line */
}
.column {
flex-grow: 0; /* Prevents column from auto growing */
flex-shrink: 0; /* Prevents column from auto shrinking */
}
.mobile-12 {
flex-basis: 100%;
}
.desktop-8 {
flex-basis: 66.66666%;
}
.desktop-4 {
flex-basis: 33.33333%;
}
.c1 { background-color: grey; }
.c2 { background-color: purple; }
.c3 { background-color: green; }
</style>
Related
I'm stacked with CSS, trying to give to an absolute positioned <div> the remaining height from where it starts.. Let me explain better with this snippet:
#main {
background-color: yellow;
}
#container {
display: grid;
position: relative;
grid-template-rows: auto auto;
}
#child_1 {
background-color: red;
grid-row: 1 / 2;
height: 100px; // this can vary
}
#child_2 {
background-color: green;
grid-row: 2 / 3;
height: 77px; // this can vary
}
#child_3 {
width: 100%;
position: absolute;
top: 100%;
background: lightblue;
}
<div id="main">
<div id="container">
<div id="child_1">CHILD 1</div>
<div id="child_2">CHILD 2</div>
<div id="child_3">CHILD 3<br /> CHILD 3</div>
</div>
<div id="something-else">
Something that is <br />
behind <br />
the absoolute <br />
div <br />
</div>
</div>
As you can see, div#child_3 starts right after div#child_2 (this is a constraint, I do want this), and I also want it to be position: absolute because it must cover anything else that may be on the screen (basically, I will have a JS handler that show/hide div#child_3, and when it is shown, it should cover #something-else).
What I would like to achieve is that div#child_3 takes all the height, from where it starts, to the end of the viewport.. To make it clearer, look at this image:
The difficult part is that.. I would like to achieve this only with CSS!
Because the only solution I've found so far is to set a fixed height to div#child_3, by granting him (100vh - div#child_3.getBoundingBoundRect().Top), and setting a ResizeObserver to cover the case in case in which the window got resized.
By the way, notice I cannot set a fixed height: calc(100vh - 177px) because, as written in CSS code, the div#child_1 and div#child_2 heights may vary.
Moreover, the div#main should not be touched: I can only work on div#container and its children, because they are part of a separate component (this example is simplified).
If there is no reason for any of the children to have their position set to absolute then this layout could be achieved with flexbox. Please see the snippet below for an example:
.parent {
height: 100vh;
/* Important styles below */
display: flex;
flex-flow: column wrap;
}
.child {
background: blue;
}
.child:nth-of-type(even) {
background: red;
}
.child--large {
/* Important styles below */
flex: 1;
}
<div class="parent">
<div class="child">
1
</div>
<div class="child">
2
</div>
<div class="child">
3
</div>
<div class="child child--large">
4
</div>
</div>
Use CSS flex-box. It's much more flexible and responsive than grid.
#main {
background-color: yellow;
}
#container {
display: flex;
flex-direction: column;
height: 100vh;
}
#child_1 {
background-color: red;
flex-grow: 1;
}
#child_2 {
background-color: green;
flex-grow: 1;
}
#child_3 {
background-color: lightBlue;
flex-grow: 2;
}
<div id="main">
<div id="container">
<div id="child_1">CHILD 1</div>
<div id="child_2">CHILD 2</div>
<div id="child_3">CHILD 3<br /> CHILD 3</div>
</div>
<div id="something-else">
More<br>elements<br>down<br>here...
</div>
</div>
Edited: It seems the original answer I deliver below is not what you want. The another idea I come up with when try on my own local machine (instead of Stackoverflow's the snippet editor) is to wrap the #child_3 inside another div called #child_3_wrapper and then position #child_3 relative to #child_3_wrapper instead of #container.
Here is the full code:
#main {
background-color: yellow;
}
#container {
display: grid;
height: 100vh; /*added this, try 100%, 98vh(or *padding:0;margin:0,...etc) to get the result desired*/
grid-template-rows: auto auto 1fr; /*added 1fr*/
}
#child_1 {
background-color: red;
grid-row: 1 / 2;
height: 100px;
}
#child_2 {
background-color: green;
grid-row: 2 / 3;
height: 77px;
}
/* changed the code below */
#child_3_wrapper {
position: relative;
}
#child_3 {
position: absolute;
top: 0; /* change top to 0 - relative to the wrapper, not the grid any more*/
width: 100%;
height: 100%;
background: lightblue;
}
<div id="main">
<div id="container">
<div id="child_1">CHILD 1</div>
<div id="child_2">CHILD 2</div>
<div id="child_3_wrapper">
<div id="child_3">CHILD 3<br /> CHILD 3</div>
</div>
</div>
<div id="something-else">
Something that is <br />
behind <br />
the absoolute <br />
div <br />
</div>
</div>
The old answer
Is this what you want? I tried tweaking around with it to get the result.
Added height: 100%; to #container and #child_3
#main {
background-color: yellow;
}
#container {
display: grid;
height: 100%; /* add this */
position: relative;
grid-template-rows: auto auto;
}
#child_1 {
background-color: red;
grid-row: 1 / 2;
height: 100px; // this can vary
}
#child_2 {
background-color: green;
grid-row: 2 / 3;
height: 77px; // this can vary
}
#child_3 {
width: 100%;
position: absolute;
top: 100%;
height: 100%; /* add this */
background: lightblue;
}
<div id="main">
<div id="container">
<div id="child_1">CHILD 1</div>
<div id="child_2">CHILD 2</div>
<div id="child_3">CHILD 3<br /> CHILD 3</div>
</div>
<div id="something-else">
Something that is <br />
behind <br />
the absoolute <br />
div <br />
</div>
</div>
I have two divs (div1 and div2) side by side and I would like to place a third div (div3) under div2.
I've tried adding a margin to div3 to try and line it up, but div1 width is dynamic. I've also tried floating div3 to the right but then the content is too far and doesn't line up with the start of div2 like in the image above
.row {
display: flex;
}
.div1 {
margin-right: 1em;
}
<div class="row">
<div class="div1">
<p> some content with unknown width</p>
</div>
<div class="div2">
<p> some content </p>
</div>
</div>
<div class="div3">
<p> some content that should be under div2 </p>
</div>
The default behaviour is div3 being under div1. I am trying to put div3 below div 2
You can do this with below:
.wrapper {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
}
.div {
flex-basis: 50%;
min-height: 100px;
}
.div1 {
background: red;
}
.div2 {
background: blue;
}
.div3 {
background: aqua;
}
<div class="wrapper">
<div class="div div1">div1</div>
<div class="div div2">div2</div>
<div class="div div3">div3</div>
</div>
And here is a codepan
Use float and inline-block:
[class*="div"] {
display:inline-block;
border:2px solid;
}
.div1 {
float:left;
margin-right: 1em;
margin-bottom:10px; /*mandatory margin to push the div3*/
}
<div class="row">
<div class="div1">
<p> some content with unknown width</p>
</div>
<div class="div2">
<p> some content </p>
</div>
</div>
<div class="div3">
<p> some content that should be under div2 </p>
</div>
You can make use of the CSS Grid structure. In this way you can have all child elements inside a single parent container.
.row {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr);
grid-column-gap: 5px;
grid-row-gap: 5px;
}
.div1 {
grid-area: 1 / 1 / 2 / 2;
}
.div2 {
grid-area: 1 / 2 / 2 / 3;
}
.div3 {
grid-area: 2 / 2 / 3 / 3;
}
/* Snippet styling */
.row > div {
background: #6A67CE;
color: white;
text-align: center;
text-transform: capitalize;
font-family: sans-serif;
}
<div class="row">
<div class="div1">
<p> some content with unknown width</p>
</div>
<div class="div2">
<p> some content </p>
</div>
<div class="div3">
<p> some content under div2 </p>
</div>
</div>
Here is a flex solution, you can use the slider to change the width of the left box to see that the width doesn't matter.
In case you are not familiar with flex, here is what happens.
display: flex; tells the container to act as a flex container, flex is just another display behavior just like float.
flex-flow: row wrap;, now that the container is flex, tells the children to display in a row, and wrap if necessary, not in this case.
That is all, after adding two boxes in the right div, and set some demo width and height, we are done.
window.addEventListener('DOMContentLoaded', e => {
let left = document.querySelector('.left')
let range = document.querySelector('.range')
range.addEventListener('input', e => {
left.style.width = e.target.value + 'px'
})
})
div {
border: 3px solid green;
}
.container,
.right {
border: none;
}
.container {
display: flex;
flex-flow: row wrap;
}
.left,
.one,
.two {
min-width: 50px;
min-height: 50px;
}
.left {
margin-right: 1em;
}
.one {
min-width: 80px;
}
.two {
margin-top: 1em;
}
<div class="container">
<div class="left"></div>
<div class="right">
<div class="one"></div>
<div class="two"></div>
</div>
</div>
<input class="range" type="range" min="50" max="300"></input>
Since div do not share the same parent , you could use display:contents and set a grid-layout one level upper , unfortunately, display:contents is not yet supported every where .
here is an example (body is the wrapper and .row not seen anymore)
body {
display: grid;
grid-template-columns: auto 1fr;
grid-gap: 10px;
}
.row {
display: contents;
/* removed from the tree */
}
div {
border: solid;
/* show me */
grid-column: 2;
/* make it the defaut column position */
width: max-content;
}
.div1 {
grid-column: 1;
/*a single reset enough here */
}
#supports (display:grid) {
.disclaimer {
display: none;
}
}
<div class="row">
<div class="div1">
<p> some content with unknown width</p>
</div>
<div class="div2">
<p> some content </p>
</div>
</div>
<div class="div3">
<p> some content that should be under div2 </p>
</div>
<p class="disclaimer">Your browser do not support <code>display:contents</code>.</p>
Another possibility is the table-layout algorythm
example with display:table (widely supported) , but every cell of each columns are of the same width.
body {
display: table;
border-spacing: 10px;
}
.div3,
.row {
display: table-row;
}
.row>div,
.div3>p,
.div3::before {
display: table-cell;
border: solid;
}
.div3::before {/* it stands in column 1 */
content: '';
border: none;
}
<div class="row">
<div class="div1">
<p> some content with unknown width</p>
</div>
<div class="div2">
<p> some content </p>
</div>
</div>
<div class="div3">
<p> some content that should be under div2 </p>
</div>
Nothing is perfect ;)
hi i coded this if that helps
.first-container {
display: flex;
flex-direction: row;
}
.first-container div{
margin: 10px;
}
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
<div class="container">
<div class="first-container">
<div class="first">first</div>
<div class="second">second</div>
</div>
<div class="third">third</div>
</div>
So lets say I have 3 components: Header, Intro, and MainContent
if I have something like:
<div className='homepage'>
<div id='top'>
<Header />
<Intro />
</div>
<div id='bottom'>
<MainContent />
</div>
</div>
How would I be able to style this so that the header and the intro take up the entirety of the screen on load, and then you have to scroll to reach the MainContent component?
I could I just set bottom padding of the #top to a percentage but that doesn't work for every device, correct?
We can use vh units with Flexbox to easily achieve this. The basic idea is to give the #top a height of 100vh (the full height of the viewport), and then use Flexbox to have the <Intro /> fill the remaining space not taken up by the <Header />. Like this:
#top {
height: 100vh;
display: flex;
flex-direction: column;
}
.intro {
flex-grow: 1;
}
/* Styling CSS - not relevant to solving the issue */
html,
body {
margin: 0;
font-family: Arial;
}
.header {
background-color: black;
color: white;
}
.intro {
background-color: lightgray;
}
.header,
.intro,
.main {
padding: 0.5rem;
}
#bottom {
min-height: 400px;
}
<div className='homepage'>
<div id='top'>
<div class="header">Header</div>
<div class="intro">Intro</div>
</div>
<div id='bottom'>
<div class="main">Main Content</div>
</div>
</div>
So I was trying to get a header and some content to fit into the screen by having a div #main with height: 100% as a flexbox, just like this:
#main {
height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
display: flex;
flex-direction: column;
}
.header {
flex: 0 1 auto;
border: 2px solid #aa0000;
}
.content {
flex: 1 1 auto;
border: 2px solid #00aa00;
}
.scrollable {
overflow-y: scroll;
}
<html>
<body>
<div id="main" class="flexbox">
<div class="header">
HEADER
</div>
<div class="content scrollable">
CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
</div>
</div>
</body>
</html>
So now if #content overflows the height of #main, #content's scrollbar will take over, and the header stays visible. Works like a charm so far.
My problem is now that I need to nest another combination of header and screen fitting content into the outer content, which I tried to solve with another nested flexbox:
#main {
height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
display: flex;
flex-direction: column;
}
.header {
flex: 0 1 auto;
border: 2px solid #aa0000;
}
.content {
flex: 1 1 auto;
border: 2px solid #00aa00;
}
.scrollable {
overflow-y: scroll;
}
<html>
<body>
<div id="main" class="flexbox">
<div class="header">
HEADER
</div>
<div class="content flexbox">
<div class="header">
HEADER
</div>
<div class="content scrollable">
CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
</div>
</div>
</div>
</body>
</html>
So basically I want both headers to stay up top now, and have only the inner content box scroll once it overflows. But when it does, the content stretches beyond (?!) #main's height, triggering the browser pages's scrollbar instead of its own one. I suppose the problem may be caused by the outer content box, whose height is only defined by the outer flexbox.
I already had tried a solution where the headers would have absolute positions, but this doesn't quite work out for what I need it. Flexboxes would be just perfect if it wasn't for this problem.
Can anyone help me fix this?
What you ask for is already happening in Chrome. Which makes me think you're developing with FF.
As a side-note, I believe that's a mistake, simply because you're developing for less than 15% of your target audience to only fix browser differences for another 65% of your audience. Luckily for you, they both keep tight to standards and differences are quite few these days.
Another reason why you might prefer Chrome over FF as a development tool is that FF has consistently been 6 months behind regarding dev tools for at least 4 years now. Don't get me wrong, I'm not a big Chrome fan and I fully welcome using FF as browsing device of choice. But, as a development tool, it's just not the best available. And they're both free.
Back to your question, adding overflow-y:auto to .flexbox seems to fix it in FF, too:
#main {
height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
display: flex;
flex-direction: column;
overflow-y: auto;
}
.header {
flex: 0 1 auto;
border: 2px solid #aa0000;
}
.content {
flex: 1 1 auto;
border: 2px solid #00aa00;
}
.scrollable {
overflow-y: scroll;
}
<html>
<body>
<div id="main" class="flexbox">
<div class="header">
HEADER
</div>
<div class="content flexbox">
<div class="header">
HEADER
</div>
<div class="content scrollable">
CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
</div>
</div>
</div>
</body>
</html>
Note: of course, you'd need to run your code through a prefixer for a wider browser coverage. Mind the "filter" box below it. Set to > 0% for maximum cross-browser compatibility.
This issue affects not only Firefox, also Edge and IE11 overflow the parent.
It's caused by the fact that flex item's min-height* defaults to auto, and as such can't be smaller than its content. (Chrome tries to fix this by itself, hence it works on it, though, IMHO, it shouldn't)
* Very well explained here: The Implied Minimum Size of Flex Items
The affected element is the <div class="content flexbox">, which will overflow because if this.
The solution is to change its min-height to 0, and with that will allow it to shrink past content.
For IE11, see notes/sample below.
Stack snippet
#main {
height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
display: flex;
flex-direction: column;
}
.header {
/*flex: 0 1 auto; default, so not needed */
border: 2px solid #aa0000;
}
.content {
flex: 1 1 auto;
border: 2px solid #00aa00;
min-height: 0; /* Firefox, Edge */
}
.scrollable {
overflow-y: scroll;
}
<div id="main" class="flexbox">
<div class="header">
HEADER
</div>
<div class="content flexbox">
<div class="header">
HEADER
</div>
<div class="content scrollable">
CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
<br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
<br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
<br>CONTENT<br>CONTENT<br>CONTENT<br>
</div>
</div>
</div>
As IE11 being a lot buggier, the above isn't enough, and there is 2 ways to fix it:
Using flex: 1 1 0%, which will make IE11 believe there is no content, hence will only grow as big as the available space in its parent.
#main {
height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
display: flex;
flex-direction: column;
}
.header {
/*flex: 0 1 auto; default, so not needed */
border: 2px solid #aa0000;
}
.content {
flex: 1 1 0%; /* IE11, changed from "auto" to "0%" */
border: 2px solid #00aa00;
min-height: 0; /* Firefox, Edge */
}
.scrollable {
overflow-y: scroll;
}
<div id="main" class="flexbox">
<div class="header">
HEADER
</div>
<div class="content flexbox">
<div class="header">
HEADER
</div>
<div class="content scrollable">
CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
<br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
<br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
<br>CONTENT<br>CONTENT<br>CONTENT<br>
</div>
</div>
</div>
Using overflow: hidden (see note at the end)
#main {
height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
display: flex;
flex-direction: column;
}
.header {
/*flex: 0 1 auto; default, so not needed */
border: 2px solid #aa0000;
}
.content {
flex: 1 1 auto;
border: 2px solid #00aa00;
/*min-height: 0; not needed, as overflow has same effect */
overflow: hidden; /* Firefox, Edge, IE11 */
}
.scrollable {
overflow-y: scroll;
}
<div id="main" class="flexbox">
<div class="header">
HEADER
</div>
<div class="content flexbox">
<div class="header">
HEADER
</div>
<div class="content scrollable">
CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
<br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
<br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
<br>CONTENT<br>CONTENT<br>CONTENT<br>
</div>
</div>
</div>
Note, using overflow with a value other than visible (its default), will have the same effect as min-height, where hidden is considered more safe than auto, avoiding future change in behavior to render a scrollbar.
You can fix this by using two height: 0 on the main box and the content box.
html,
body {
height: 100%;
}
.topheader {
background: orange;
width: 90%;
}
#container {
display: flex;
flex-direction: column;
height: 100%;
width: 50%;
background: red;
}
.subcontainer {
display: flex;
flex-direction: column;
flex: 1 1 auto;
height: 0;
width: 90%;
background: blue;
}
#container header {
background-color: gray;
}
#container article {
flex: 1 1 auto;
overflow-y: auto;
height: 0;
opacity: 0.5;
}
#container footer {
background-color: gray;
}
<section id="container">
<div class="topheader">
Top Header
</div>
<div class="subcontainer">
<header id="header">This is a header</header>
<article id="content">
This is the content that
<br />
With a lot of lines.
<br />
With a lot of lines.
<br />
This is the content that
<br />
With a lot of lines.
<br />
<br />
This is the content that
<br />
With a lot of lines.<br />
With a lot of lines.
<br />
This is the content that
<br />
With a lot of lines.
<br />
<br />
This is the content that
<br />
With a lot of lines<br />
With a lot of lines.
<br />
This is the content that
<br />
With a lot of lines.
<br />
<br />
This is the content that
<br />
With a lot of lines
<br />
<br />
This is the content that
<br />
With a lot of lines.
<br />
</article>
<footer id="footer">This is a footer</footer>
</div>
</section>
In the code below, how do I make the article container auto grow to consume the remaining vertical space below it, but the scroll bar to remain only for that element.
In other words, I want only the inside of article to scroll and not the entire browser window.
Is there a pure css solution? Or do I need javascript to detect the size of the browser window and adjust the height property of article dynamically?
html, body {
//height: 100%;
}
#outer_container {
display: flex;
flex-direction: row;
}
#outer2 {
flex: 1 0 auto;
}
#outer2 {
flex: 1 0 auto;
}
#container {
display: flex;
flex-direction: column;
height: 100%;
width: 50%;
background-color: red;
}
#container header {
background-color: gray;
}
#container article {
flex: 1 1 auto;
overflow-y: auto;
height: 0px;
}
#container footer {
background-color: gray;
}
<div id="outer_container">
<div id="outer1">
<h2>Outer 1</h2>
</div>
<section id="container">
<header id="header">This is a header</header>
<article id="content">
This is the content that
<br />With a lot of lines.
<br />With a lot of lines.
<br />This is the content that
<br />With a lot of lines.
<br />
<br />This is the content that
<br />With a lot of lines.
<br />
<br />This is the content that
<br />With a lot of lines.
<br />
</article>
<footer id="footer">This is a footer</footer>
</section>
<div id="outer2">
<h2>Outer 2</h2>
</div>
</div>
http://jsfiddle.net/ch7n6/907/
It was originally based on the answer to this question:
Flexbox and vertical scroll in a full-height app using NEWER flexbox api
You can try setting position:fixed to your outer container (http://jsfiddle.net/ch7n6/909/):
#outer_container{
display:flex;
flex-direction:row;
top:0;
bottom:0;
position:fixed;
}
If it doesn't work for your design, you can change the container dimensions using window.onresize event.
In your code you commented out:
html, body {
//height: 100%;
}
But I think you were on the right track.
By uncommenting that rule, and adding height: 100% to .outer_container, your layout may be complete.
Try this:
html, body {
height: 100%; /* uncommented */
margin: 0; /* removes default margin */
}
#outer_container {
height: 100%; /* new; see details below */
display: flex;
flex-direction: row;
}
#outer2 {
flex: 1 0 auto;
background-color: lightblue; /* just for demo */
}
#outer1 { /* correction to duplicate ID */
flex: 1 0 auto;
background-color: lightgreen; /* just for demo */
}
#container {
display: flex;
flex-direction: column;
height: 100%;
width: 50%;
background-color: red;
}
#container header {
background-color: gray;
}
#container article {
flex: 1 1 auto;
overflow-y: auto;
height: 0px;
}
#container footer {
background-color: gray;
}
<div id="outer_container">
<div id="outer1">
<h2>Outer 1</h2>
</div>
<section id="container">
<header id="header">This is a header</header>
<article id="content">
This is the content that
<br />With a lot of lines.
<br />With a lot of lines.
<br />This is the content that
<br />With a lot of lines.
<br />
<br />This is the content that
<br />With a lot of lines.
<br />
<br />This is the content that
<br />With a lot of lines.
<br />
</article>
<footer id="footer">This is a footer</footer>
</section>
<div id="outer2">
<h2>Outer 2</h2>
</div>
</div>
jsFiddle
To understand how this solution works, and what may have held you up, take a look at these posts:
Working with the CSS height property and percentage values
Chrome / Safari not filling 100% height of flex parent