Flexbox grow div to take up remaining height - html

versions of this have been asked before and these questions helped me so far as to have a flex item that grows in height. However, it grows too much :)
Please see the code pen or the code here
https://codepen.io/surf-n-code/pen/wvwrbKW
Basically I have this Code
html,
body {
height: 100%;
}
.container {
height: 100%;
min-height: 100%;
display: flex;
flex-direction: column;
}
.box {
text-align: center;
color: white;
font-family: sans-serif;
font-size: 36px;
padding: 20px;
display: flex;
flex-direction: column;
justify-content: center;
}
.box-1 {
background-color: green;
height: 60px;
}
.box-2 {
background-color: blue;
flex: 1;
}
.box-3 {
background-color: red;
height: 60px;
}
<body>
<header>
<div class="box box-0">Header - sticks to top</div>
</header>
<main class="full-height">
<div class="nd_container">
<div class="box box-1">content</div>
<div class="box box-2">Flex grow</div>
</div>
</main>
<footer>
<div class="box box-4">Footer - stick to bottom</div>
</footer>
</body>
I would expect the box-2 to increase in size just enough such that the footer sticks exactly to the bottom of the page. I do not want any scrolling due to the created whitespace.
Any help is much appreciated :)

I hope this is what you expecting check out my answer.
NOTE:CHECK OUT MY ANSWER IN FULL SCREEN MODE
box-2 to increase in size just enough such that the footer sticks exactly to the bottom of the page.
html,
body {
height: 100%;
margin: 0;
height: 100vh;
display: flex;
flex-flow: column;
}
.nd_container {
height: 100%;
min-height: 100%;
display: flex;
flex-flow: column;
}
.nd_container .box {
text-align: center;
color: white;
font-family: sans-serif;
font-size: 36px;
padding: 20px;
justify-content: center;
}
.nd_container .box-1 {
background-color: green;
flex: 0 1 60px;
}
.nd_container .box-2 {
background-color: red;
flex: 1 1 auto;
}
.box {
text-align: center;
color: white;
font-family: sans-serif;
font-size: 36px;
display: flex;
flex-direction: column;
justify-content: center;
}
.box.box-0 {
background-color: #03a9f4;
height: 100%;
}
.box.box-4 {
background-color: #0c5460;
height: 100%;
}
header {
flex: 0 1 155px;
}
main {
flex: 1 1 auto;
}
footer {
flex: 0 1 155px;
}
<body>
<header>
<div class="box box-0">Header - sticks to top</div>
</header>
<main class="full-height">
<div class="nd_container">
<div class="box box-1">content</div>
<div class="box box-2">Flex grow</div>
</div>
</main>
<footer>
<div class="box box-4">Footer - stick to bottom</div>
</footer>
</body>

Related

How do I divide blocks in my page with flexbox?

I'm facing this problem where I want to have a header, sidebar and content with flexbox. I can't get to a solution to divide these 3 childs. I've been trying to use flex-grow and flex-direction:row but I'm having a problem.
Image of the website
How I want it to be
<style>
.parent {
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
height: 100vh;
border: 20px solid black;
display: flex;
flex-direction: column;
}
.header {
width: 200px;
height: 200px;
background: cornflowerblue;
}
.side {
width: 200px;
height: 200px;
background: rgb(219, 133, 133);
}
.content {
width: 200px;
height: 200px;
background: rgb(115, 202, 180);
}
.text {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 190px;
color: #fff;
}
</style>
<div class="parent">
<div class="header">
<h2 class="text">Header</h2>
</div>
<div class="side">
<h2 class="text">Side</h2>
</div>
<div class="content">
<h2 class="text">Content</h2>
</div>
</div>
You need to create two containers, one for all your elements and one for your header and content.
<div class="parent"> <!-- Container 1 -->
<div class="side">
<h2 class="text">Side</h2>
</div>
<div class="container"> <!-- Container 2 -->
<div class="header">
<h2 class="text">Header</h2>
</div>
<div class="content">
<h2 class="text">Content</h2>
</div>
</div>
</div>
Then, you can treat each container as a separate flex-box. the parent will have a flex-direction: row; and the container will have flex-direction: column;.
You also want to set values in percentages, not absolute values as you have right now (200px, 20rem..).
.parent {
box-sizing: border-box;
margin: 0;
padding: 0;
height: 100vh;
border: 20px solid black;
display: flex;
flex-direction: row;
}
.header {
height: 30%;
background: cornflowerblue;
}
.side {
width: 30%;
height: 100%;
background: rgb(219, 133, 133);
}
.content {
height: 70%;
background: rgb(115, 202, 180);
}
.text {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 190px;
color: #fff;
}
.container {
display: flex;
flex-direction: column;
width: 70%;
height: 100%;
}
JSFiddle
Images to illustrate the separation:
You have to wrap your header & content section inside another div. Something like this below example. However, The best way to achieve this layout is using a CSS grid. Here is the complete CSS grid guide
.parent {
display: flex;
height: 100vh;
background: #000;
padding: 5px;
margin: 0;
}
.side {
border: 1px solid #000;
width: 30vw;
display: flex;
justify-content: center;
align-items: center;
background: #fff;
margin-right: 5px;
}
.main-body {
border: 1px solid #000;
width: 70vw;
}
.header,
.content {
display: flex;
justify-content: center;
background: #fff;
}
.header {
height: 25vh;
margin-bottom: 5px;
}
.content {
align-items:center;
height: 70vh;
}
<div class="parent">
<div class="side">
<h2 class="text">Side</h2>
</div>
<div class="main-body">
<div class="header">
<h2 class="text">Header</h2>
</div>
<div class="content">
<h2 class="text">Content</h2>
</div>
</div>
</div>
I don't think that you deeply understand how flexbox work. You should read more about it. I advice you to read a book called CSS-in Depth. You can download it online from a website called Z-lib. Try to understand the code that I posted for you.
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.parent {
height: 100vh;
border: 20px solid black;
display: flex;
background: pink;
}
.main {
display: flex;
backgound-color: green;
flex-direction: column;
flex: 2
}
.header {
background: cornflowerblue;
}
.side {
flex: 1;
background: rgb(219, 133, 133);
}
.content {
background: rgb(115, 202, 180);
flex: 1
}
.text {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 190px;
color: #fff;
}
</style>
<div class="parent">
<div class="side">
<h2 class="text">Side</h2>
</div>
<div class="main">
<div class="header">
<h2 class="text">Header</h2>
</div>
<div class="content">
<h2 class="text">Content</h2>
</div>
</div>
</div>

Text inside FlexBox with CSS not Appearing

Goal: I have a main flex box with row display. Within each of these flexbox I will have card with text inside. When I create the card inside the flexbox I place p tags inside the card with the text, but it does not reflect. I want the text to dsiplay within each card.
Code
.flex-container {
display: flex;
flex-direction: row;
background-color: DodgerBlue;
}
.flex-container>div {
background-color: #f1f1f1;
margin: 10px;
/*text-align: center;*/
line-height: 70vh;
font-size: 30px;
}
.funds-card {
display: flex;
flex-direction: column;
width: 200px;
}
.transaction-card {
width: 700px
}
.amount-card {
width: 70%;
height: 70px;
max-width: 100px;
border-radius: 5px;
margin: 5px auto 0 auto;
padding: 1.5em;
background-color: green;
text-align: center;
}
<body>
<h1>The flex-direction Property</h1>
<p>The "flex-direction: row;" stacks the flex items horizontally (from left to right):</p>
<div class="flex-container">
<div class="funds-card">
<div class="amount-card">
<p>Hello</p>
</div>
</div>
<div class="transaction-card">
2
</div>
</div>
</body>
Remove line-height: 70vh; property from the .flex-container>div
.flex-container {
display: flex;
flex-direction: row;
background-color: DodgerBlue;
}
.flex-container>div {
background-color: #f1f1f1;
margin: 10px;
/*text-align: center;*/
/*line-height: 70vh;*/
font-size: 30px;
}
.funds-card {
display: flex;
flex-direction: column;
width: 200px;
}
.transaction-card {
width: 700px
}
.amount-card {
width: 70%;
height: 70px;
max-width: 100px;
border-radius: 5px;
margin: 5px auto 0 auto;
padding: 1.5em;
background-color: green;
text-align: center;
}
<body>
<h1>The flex-direction Property</h1>
<p>The "flex-direction: row;" stacks the flex items horizontally (from left to right):</p>
<div class="flex-container">
<div class="funds-card">
<div class="amount-card">
<p>Hello</p>
</div>
</div>
<div class="transaction-card">
2
</div>
</div>
</body>

Height 100% inside flex item

I have a layout that is mainly divided into 3 parts and the middle one should take a full height. And it does.
However, I need an additional div which will play a role of the backdrop and here the problem comes. The child doesn't want to take 100% height.
Here .body is a div that is being stretched when there is not enough content and .bg-gray is the one I want to take its parent full height.
Is there a way achieve this without using relative + absolute positioning?
Also, I'm looking for the answer to my question: why is this happening that way.
html, body {
padding: 0;
margin: 0;
}
.container {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: stretch;
}
.header {
height: 50px;
background-color: #e6e6e6;
}
.footer {
height: 50px;
background-color: #aaa444;
}
.body {
flex: 1;
}
.bg-gray {
background-color: #eee;
min-height: 100%;
flex: 1;
}
<div class="container">
<div class="header">
</div>
<div class="body">
<div class="bg-gray">
<div>
asdasd
</div>
</div>
</div>
<div class="footer">
</div>
</div>
Apply flexbox to the .body div.
.body {
flex: 1;
display: flex;
flex-direction: column;
}
html,
body {
padding: 0;
margin: 0;
}
.container {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: stretch;
}
.header {
height: 50px;
background-color: #e6e6e6;
}
.footer {
height: 50px;
background-color: #aaa444;
}
.body {
flex: 1;
display: flex;
flex-direction: column;
}
.bg-gray {
background-color: darkgrey;
min-height: 100%;
flex: 1;
}
.bg-gray div {
background: lightblue;
}
<div class="container">
<div class="header">
</div>
<div class="body">
<div class="bg-gray">
<div>
asdasd
</div>
</div>
</div>
<div class="footer">
</div>
</div>

Issue with flexbox

I'm new to flexbox and I created the following in order to have a top-navigation, with three columns below the top-navigation. When I open my HTML file the top-navigation is 80px tall but the three columns are only 50%, less the 80px for the header. I don't understand what is going on? Should the three columns not just fill in the difference?
body {
font: 24px Helvetica;
background: #999999;
}
.layout {
min-height: 100vh;
display: flex;
flex-flow: row;
flex-wrap: wrap;
}
.top-navigation {
width: 100vw;
height: 80px;
background: #cc2936;
}
.left-sidebar {
width: 25%;
background: #dcdcdc;
flexgrow: 1;
}
.main-outlet {
width: 50%;
background: #ffffff;
flexgrow: 1;
}
.right-sidebar {
width: 25%;
background: #dcdcdc;
flexgrow: 1;
}
<div class="layout">
<div class="box top-navigation"></div>
<div class="box left-sidebar"></div>
<div class="box main-outlet"></div>
<div class="box right-sidebar"></div>
</div>
I think you need to change your layout a little bit. You can then set the wrapping div to have flex-direction: column and align-content: stretchto the three columns like this:
body {
font: 24px Helvetica;
background: #999999;
margin: 0;
}
.layout {
min-height: 100vh;
display: flex;
flex-direction: column;
flex-flow: row;
flex-wrap: wrap;
align-content: stretch;
}
.top-navigation {
width: 100vw;
height: 80px;
background: #cc2936;
}
.left-sidebar {
width: 25%;
background: #dcdcdc;
}
.main-outlet {
width: 50%;
background: #ffffff;
}
.right-sidebar {
width: 25%;
background: #dcdcdc;
}
<div class="box top-navigation"></div>
<div class="layout">
<div class="box left-sidebar"></div>
<div class="box main-outlet"></div>
<div class="box right-sidebar"></div>
</div>

Prevent flexbox items from overflowing into siblings

I am trying to make a one-pager site, which is working quite well. I have three sections that need to be fullscreen, that works. But when I resize the window to 500px width and make the height also shorter, the title from the second page comes up on the first page. Same thing happens with the title on the third page, this one displays on the second page.
Here is the codepen: http://codepen.io/anon/pen/jWaxMK
HTML:
<section>
<h2>Title 1</h2>
<div class="box">
</div>
<div class="box">
</div>
</section>
<section>
<h2 class="blue">Title 2</h2>
<div class="box circle"></div>
<div class="box circle"></div>
<div class="box circle"></div>
</section>
<section>
<h2 class="white">Title 3</h2>
</section>
CSS:
html,
body,main {
height: 100%;
margin: 0;
padding: 0;
}
section {
position: relative;
width: 100%;
height: 100%;
color: #ececec;
text-align: center;
display: flex; /* default: row nowrap */
flex-flow:row wrap;
justify-content: center;
align-items: center;
align-content: center;
}
section:nth-child(1) {
background: #06a2cb;
}
section:nth-child(2) {
background: #ececec;
}
section:nth-child(3) {
background: #F5E5D8;
}
h2{
margin-top:0;
font-family: 'Lobster';
margin: 1em;
flex: 0 0 100%;
color: black;
}
.box{
width: 250px;
height: 250px;
display: inline-block;
background-color: #ececec;
border-radius: 10px;
flex: 0 0 250px;
}
.circle{
border-radius: 50%;
background-color: white;
}
Any help is appreciated, thanks!
You can solve the problem by making all the section elements flex items, and giving them a minimum height.
Add this to your CSS:
body {
display: flex;
flex-direction: column;
}
section {
min-height: 100%; /* alternatively, try `min-height: 100vh` */
flex-shrink: 0;
}
Revised Codepen