Don't stretch one element in a CSS Flex box with complex layout
I'm trying to create a nested flex layout that distributes all columns correctly (vertically). This seems to work pretty well, except for stretching one element inside the nested layout.
|---------------------------------------------|
|Header |
|---------------------------------------------|
||--------------------------------|----------||
||TITLE IS THE ISSUE! |Right ||
||--------------------------------|Aside ||
||Left |Content | ||
||Aside | | ||
|| | | ||
|| | | ||
|| | | ||
||--------|-----------------------|----------||
|---------------------------------------------|
|Footer |
|---------------------------------------------|
The problem I am facing is that if the Right Aside becomes larger than the other content, the title will stretch vertically. If I try to override the Title attribute align-self to stop it from stretching, nothing happens.
A plunker that clearly shows the problem. Look at the gray space (Header - Shouldn't Grow): http://plnkr.co/edit/9VBSOKi0ipAy1QDpNAKb?p=preview
Thank...
source to share
From scratch - building a layout from the inside
There are 3 nested flex containers in this layout.
# 1 - Two inner columns
These columns are wrapped in their own Flex parent called .flex-inner-columns
. The element <main>
might be a good choice for this parent.
Html
<main class="flex-inner-columns">
<div class="column-left">
column-left
</div>
<div class="column-right">
column-right
</div>
</main>
CSS
.flex-inner-columns {
display: flex;
}
.column-left {
flex: 1;
}
.column-right {
flex: 2;
}
# 2 - Adding a Title
The header and inner parent post are wrapped in another floppy parent .flex-inner
. The element <section>
might be a good choice for this parent.
Html
<section class="flex-inner">
<header class="inner-title">
<h1>inner-title</h1>
</header>
<main class="flex-inner-columns">
<!-- columns are here -->
</main>
</section>
CSS
The flex direction for this flex parent is set to column
. The header is assigned flex: 0 1 150px
and will not grow, but will reduce its height by default to 150 pixels if necessary. The flex container is flex specified flex: 1
, so it will grow and shrink.
.flex-inner {
display: flex;
flex: 2;
flex-direction: column;
}
.inner-title {
flex: 0 1 150px;
width: 100%;
}
.flex-inner-columns {
display: flex;
flex: 1; /* the inner columns flex parent is now given flex 1*/
}
# 3 - final layout; adding outer flex parent
Everything is wrapped in one final outer container that controls the right column. .flex-inner
given flex: 2
, but .outer-right
indicated aside flex: 1
.
Complete example
body {
margin: 0;
}
.top-header,
footer {
height: 10vh;
background: #E91E63;
}
.flex-outer {
display: flex;
height: 80vh;
}
.outer-right {
flex: 1;
background: #F48FB1;
}
.flex-inner {
display: flex;
flex: 2;
background: #333;
flex-direction: column;
}
.inner-title {
background: #9C27B0;
flex: 0 1 150px;
align-self: center;
width: 100%;
}
.flex-inner-columns {
display: flex;
flex: 1;
}
.column-left {
flex: 1;
background: #CE93D8;
}
.column-right {
flex: 2;
background: #AB47BC;
}
<header class="top-header">Header</header>
<div class="flex-outer">
<section class="flex-inner">
<header class="inner-title">
<h1>inner-title</h1>
</header>
<main class="flex-inner-columns">
<div class="column-left">
column-left
</div>
<div class="column-right">
column-right
</div>
</main>
</section>
<aside class="outer-right">
right outer
</aside>
</div>
<footer>Footer</footer>
source to share