Flexbox 100% height Issue - html

I have found the following links... but it still doesn't help me...
how to make nested flexboxes work
Height 100% on flexbox column child
How to make flexbox children 100% height of their parent?
I need a full page that is responsive, like the following image:
With header and footer and the middle 5 columns filling the height equally in the remaining space, and then when I do media queries, fill the screen of the mobile device like so:
Here's the code I have so far...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
html,
body {
height: 100%;
margin: 0
}
.box {
display: flex;
flex-flow: column;
height: 100%;
}
.box .row {
border: 1px dotted grey;
}
.box .row.header {
flex: 0 1 auto;
/* The above is shorthand for:
flex-grow: 0,
flex-shrink: 1,
flex-basis: auto
*/
}
.box .row.content {
flex: 1 1 auto;
}
.box .row.footer {
flex: 0 1 40px;
}
.yellow-back {
background: #ffe001;
}
.red-back {
background: #e31e25;
}
.green-back {
background: #66af45;
}
.purple-back {
background: #954294;
}
.containerFull { position: relative; width: 100%; margin: 0 auto; padding: 0;}
.containerFull .column,
.containerFull .columns { float: left; display: inline; margin-left: 0px; margin-right: 0px; }
.containerFull .one-fifth.column { width: 20%; }
</style>
</head>
<body>
<div class="box">
<div class="row header">
<p><b>header</b>
<br />
<br />(sized to content)</p>
</div>
<div class="row content">
<div class="containerFull">
<div class="one-fifth column green-back">Here</div>
<div class="one-fifth column red-back">Here</div>
<div class="one-fifth column">Here</div>
<div class="one-fifth column yellow-back">Here</div>
<div class="one-fifth column purple-back">Here</div>
</div><!-- ContainerFull -->
</div>
<div class="row footer">
<p><b>footer</b> (fixed height)</p>
</div>
</div>
</body>
</html>
html,
body {
height: 100%;
margin: 0
}
.box {
display: flex;
flex-flow: column;
height: 100%;
}
.box .row {
border: 1px dotted grey;
}
.box .row.header {
flex: 0 1 auto;
/* The above is shorthand for:
flex-grow: 0,
flex-shrink: 1,
flex-basis: auto
*/
}
.box .row.content {
flex: 1 1 auto;
}
.box .row.footer {
flex: 0 1 40px;
}
.yellow-back {
background: #ffe001;
}
.red-back {
background: #e31e25;
}
.green-back {
background: #66af45;
}
.purple-back {
background: #954294;
}
.containerFull {
position: relative;
width: 100%;
margin: 0 auto;
padding: 0;
}
.containerFull .column,
.containerFull .columns {
float: left;
display: inline;
margin-left: 0px;
margin-right: 0px;
}
.containerFull .one-fifth.column {
width: 20%;
}
<div class="box">
<div class="row header">
<p><b>header</b>
<br />
<br />(sized to content)</p>
</div>
<div class="row content">
<div class="containerFull">
<div class="one-fifth column green-back">Here</div>
<div class="one-fifth column red-back">Here</div>
<div class="one-fifth column">Here</div>
<div class="one-fifth column yellow-back">Here</div>
<div class="one-fifth column purple-back">Here</div>
</div>
<!-- ContainerFull -->
</div>
<div class="row footer">
<p><b>footer</b> (fixed height)</p>
</div>
</div>

In addition to Michael Coker's answer, if you go all the way with Flexbox, you can cut down both your markup and CSS quite much and get this amazing result.
I also included the background image and media query you commented/asked about just to show how simple this can be done.
Made some notes in the CSS. When it comes to the header and footer, you can give them a height if you want, but is not needed for this to work, so I left them out so one can see how Flexbox excel in distributing the content...wish I had this technique 20 years ago :)
html, body {
margin: 0;
}
.box {
display: flex;
flex-direction: column;
height: 100vh; /* instead of using 100% all over, use viewport units once */
background-size: cover;
background: black url(http://lorempixel.com/500/500/nature/4/) no-repeat center;
}
.box .row.content,
.content .one-fifth.column {
flex: 1; /* fill the space equal, no matter row or column direction */
display: flex;
}
.box .row.header,
.box .row.footer { color: white; }
.box .row.content { background: #fff; }
.yellow-back { background: #ffe001; }
.red-back { background: #e31e25; }
.green-back { background: #66af45; }
.purple-back { background: #954294; }
#media screen and (max-width: 600px) {
/* smaller screens */
.box .row.content {
flex-direction: column; /* by simply swap direction it work on smaller screen */
}
}
<div class="box">
<div class="row header">
<p><b>header</b><br /><br />(sized to content)</p>
</div>
<div class="row content">
<div class="one-fifth column green-back">Here</div>
<div class="one-fifth column red-back">Here</div>
<div class="one-fifth column">Here</div>
<div class="one-fifth column yellow-back">Here</div>
<div class="one-fifth column purple-back">Here</div>
</div>
<div class="row footer">
<p><b>footer</b> (fixed height)</p>
</div>
</div>

I would make the column section a flex layout, too. You can set .content and .containerFull to display: flex, then .containerFull will "stretch" to fill the height of .content, and then you can use flex-basis on the columns to control the width.
html,
body {
height: 100%;
margin: 0
}
.box {
display: flex;
flex-flow: column;
height: 100%;
}
.box .row {
border: 1px dotted grey;
}
.box .row.header {
flex: 0 1 auto;
/* The above is shorthand for:
flex-grow: 0,
flex-shrink: 1,
flex-basis: auto
*/
}
.box .row.content {
display: flex;
}
.box .row.content {
flex: 1 1 auto;
}
.containerFull {
display: flex;
}
.box .row.footer {
flex: 0 1 40px;
}
.yellow-back {
background: #ffe001;
}
.red-back {
background: #e31e25;
}
.green-back {
background: #66af45;
}
.purple-back {
background: #954294;
}
.containerFull {
position: relative;
width: 100%;
margin: 0 auto;
padding: 0;
}
.containerFull .column,
.containerFull .columns {
margin-left: 0px;
margin-right: 0px;
}
.containerFull .one-fifth.column {
flex-basis: 20%;
}
<div class="box">
<div class="row header">
<p><b>header</b>
<br />
<br />(sized to content)</p>
</div>
<div class="row content">
<div class="containerFull">
<div class="one-fifth column green-back">Here</div>
<div class="one-fifth column red-back">Here</div>
<div class="one-fifth column">Here</div>
<div class="one-fifth column yellow-back">Here</div>
<div class="one-fifth column purple-back">Here</div>
</div><!-- ContainerFull -->
</div>
<div class="row footer">
<p><b>footer</b> (fixed height)</p>
</div>
</div>

Related

How can I put two <div> that has the same width and height next to each other without having to scroll?

I'm currently making a simple html page with two sections with content inside of each of them but the last content of the second div .right is going on the bottom of the page and make the page scrollable.
I tried making another div and put a flex-direction: column but it doesn't work:
body {
margin: 0;
}
.main-container {
display: flex;
flex-direction: column;
}
.left {
background: #ecece9;
width: 50%;
height: 100vh;
}
.right {
background: #ffffff;
width: 50%;
height: 100vh;
}
<div class="main-container">
<div class="left">
<h2>content</h2>
</div>
<div class="right">
<h2>content should be on top</h2>
</div>
</div>
How can I put two <div> that has the same width and height next to each other without having to scroll?
You need to use flex-direction: row and not flex-direction: column.
To avoid repeating width: 50%; height: 100vh; for both .left and .right, I would also create another class, such as .box, which is applied to both and contains these properties.
body {
margin: 0;
}
.main-container {
display: flex;
flex-direction: row;
}
.box {
width: 50%;
height: 100vh;
}
.left {
background: #ecece9;
}
.right {
background: #ffffff;
}
<div class="main-container">
<div class="left box">
<h2>content</h2>
</div>
<div class="right box">
<h2>content should be on top</h2>
</div>
</div>
Change the flex direction from column to row
body {
margin: 0;
}
.main-container {
display: flex;
flex-direction: row;
}
.left {
background: #ecece9;
width: 50%;
height: 100vh;
}
.right {
background: #ffffff;
width: 50%;
height: 100vh;
}
<div class="main-container">
<div class="left">
<h2>content</h2>
</div>
<div class="right">
<h2>content should be on top</h2>
</div>
</div>
Use CSS Grid to build Layouts it is very powerful. See I changed only two lines and the layout is ready.
.main-container {
display: grid;
grid-template-columns: 50% 50%
}
body {
margin: 0;
}
.main-container {
display: grid;
grid-template-columns: 50% 50%
}
.left {
background: #ecece9;
height: 100vh;
}
.right {
background: #ffffff;
height: 100vh;
}
<div class="main-container">
<div class="left">
<h2>content</h2>
</div>
<div class="right">
<h2>content should be on top</h2>
</div>
</div>
Try only display flex on large screen and and block on mobile
body {
margin: 0;
}
.main-container {
display: flex;
}
.left {
background: #ecece9;
width: 50%;
height: 100vh;
padding:20px;
}
.right {
background: #ddd;
width: 50%;
height: 100vh;
padding:20px;
}
/* For mobile screen
#media only screen and (max-width: 768px) {
.main-container{
display: block;
}
.left, .right{
width: 100%;
}
}
*/
<div class="main-container">
<div class="left">
<h2>content</h2>
</div>
<div class="right">
<h2>content should be on top</h2>
</div>
</div>

CSS Flex Overflow [duplicate]

This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 2 years ago.
I want to make a website with a list using bootstrap + css's flexbox, where the item list should have a height up to the screen's bottom not overflowing it.
I was able to get a working solution like this:
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
margin: 0;
}
body {
background-color: black;
}
.wrapper .content-wrapper .content {
flex: 1 1 1px;
}
.wrapper .content-wrapper .content {
display: flex;
flex-direction: column;
}
.wrapper .content-wrapper {
width: 100%;
}
.wrapper {
display: flex;
height: 100%;
}
.side {
background-color: blue;
display: flex;
flex-direction: column;
width: 224px;
}
.content-wrapper {
display: flex;
flex-direction: column;
}
.topbar {
height: 100px;
background-color: aqua;
}
.main {
flex: 1 1 1px;
background-color: pink;
overflow-y: scroll;
}
.item {
background-color: white;
border-style: solid;
height: 200px;
}
<html>
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="wrapper">
<div class="side"></div>
<div class="content-wrapper">
<div class="content">
<div class="topbar"></div>
<div class="main">
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
</div>
</div>
</div>
</div>
</body>
</html>
With the help from this link:
Prevent flex item from exceeding parent height and make scroll bar work
As you can see the scroll bar's bottom arrow is at the end of the screen. (Expected behaviour)
However, when I try to expand my main div into 2 more columns (using bootstrap + flex):
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
margin: 0;
}
body {
background-color: black;
}
.wrapper .content-wrapper .content {
flex: 1 1 1px;
}
.wrapper .content-wrapper .content {
display: flex;
flex-direction: column;
}
.wrapper .content-wrapper {
width: 100%;
}
.wrapper {
display: flex;
height: 100%;
}
.side {
background-color: blue;
display: flex;
flex-direction: column;
width: 224px;
}
.content-wrapper {
display: flex;
flex-direction: column;
}
.topbar {
height: 100px;
background-color: aqua;
}
.main {
flex: 1 1 1px;
background-color: pink;
display: flex;
}
.header {
background-color: yellow;
overflow-y: scroll;
height: 100%;
}
.details {
background-color: crimson;
}
.item {
background-color: white;
border-style: solid;
height: 200px;
}
<html>
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="wrapper">
<div class="side"></div>
<div class="content-wrapper">
<div class="content">
<div class="topbar"></div>
<div class="main">
<div class="header col-lg-4">
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
</div>
<div class="details col-lg-8"></div>
</div>
</div>
</div>
</div>
</body>
</html>
Now the item list overflow below the bottom of the screen. (see the bottom arrow of the scrollbar is missing)
Any help would be appreciated.
You have a couple of fixed lengths in your code, including:
.side {
width: 224px;
}
.topbar {
height: 100px;
}
These hard limits make the solution to overflow problems relatively simple, since the easiest way to trigger a scrollbar is to create an overflow condition, which is best accomplished with a fixed length.
In this case, the .topbar { height: 100px } is the key to the scrollbar on the sibling element.
(Note that you need to disable flex-shrink on these lengths for the values to always be respected.)
Here's a revised version of your code, with various adjustments for greater performance and efficiency.
body {
margin: 0;
background-color: black;
}
.wrapper {
display: flex;
height: 100vh;
}
.side {
/* width: 224px; */ /* will not be respected without adding `flex-shrink: 0` */
flex: 0 0 224px; /* new; flex-grow, flex-shrink, flex-basis */
background-color: blue;
display: flex;
flex-direction: column;
}
.content-wrapper {
flex: 1; /* consume remaining space */
display: flex;
flex-direction: column;
}
.wrapper .content-wrapper .content {
display: flex;
flex-direction: column;
}
.topbar {
flex: 0 0 100px;
/* height: 100px; */
background-color: aqua;
}
.main {
height: calc(100vh - 100px); /* new; sets overflow condition */
background-color: pink;
display: flex;
}
.header {
background-color: yellow;
overflow-y: scroll;
/* height: 100%; */
}
.details {
background-color: crimson;
}
.item {
background-color: white;
border-style: solid;
height: 200px; /* not a flex item, so no need to disable flex-shrink */
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="wrapper">
<div class="side"></div>
<div class="content-wrapper">
<div class="content">
<div class="topbar"></div>
<div class="main">
<div class="header col-lg-4">
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
</div>
<div class="details col-lg-8"></div>
</div>
</div>
</div>
</div>
jsFiddle demo

Resizing image within flexbox layout

I have a pay layout which works how I want to when using the .slides element has a background colour and height, it flexes as expected, however when I switch to filling it with an image this behaviour breaks as the images won't resize and I can't get my head around how to make them resize.
The idea is the left column of text remains fixed size, and the right column flexes up and down, eventually snapping under the left column at small sizes.
The reason for using an <img> and not a background image is because there is a image slide show that I want to put in here.
Can anyone help fix this issue?
body {
margin: 1em;
}
p {
margin: 0;
}
.container {
display: flex;
margin-top: 1em;
width: 100%;
flex-wrap: wrap;
}
.text {
flex: 0 0 auto;
width: 15em;
margin-right: 1em;
}
.images {
flex: 1 1 auto;
min-width: 15em;
max-width: 800px;
}
.caption {
margin-top: .25em;
}
<div class="header">
Title
</div>
<div class="container">
<div class="text">
<p>Something about this project is really interesting.</p>
</div>
<div class="images">
<div class="slides">
<img src="https://via.placeholder.com/800x800">
</div>
<div class="caption">
<p>Text about this project</p>
</div>
</div>
</div>
Changes made:
Enabled responsiveness for img elements
Commented out the flex-wrap: wrap
Set #media queries to define when the wrapping inside the .container div takes place
body {
margin: 1em;
}
p {
margin: 0;
}
img {
display: block; /* removes bottom margin/whitespace */
max-width: 100%; /* horizontally responsive */
max-height: 100vh; /* vertically responsive */
}
.container {
display: flex;
margin-top: 1em;
width: 100%;
/*flex-wrap: wrap;*/
}
.text {
flex: 0 0 auto;
width: 15em;
margin-right: 1em;
}
.images {
flex: 1 1 auto;
min-width: 15em;
max-width: 800px;
}
.caption {
margin-top: .25em;
}
#media (max-width: 33em) { /* 2 x 15em (.text & .images) + 2em (left & right margin of the body element) + 1em (.text margin-right) */
.container {flex-wrap: wrap}
}
<div class="header">
Title
</div>
<div class="container">
<div class="text">
<p>Something about this project is really interesting.</p>
</div>
<div class="images">
<div class="slides">
<img src="https://via.placeholder.com/800x800">
</div>
<div class="caption">
<p>Text about this project</p>
</div>
</div>
</div>
Do you mean something like this ?
body {
margin: 1em;
}
p {
margin: 0;
}
.container {
display: flex;
margin-top: 1em;
width: 100%;
flex-flow:row wrap;
}
.text {
flex: 0 0 auto;
width: 15em;
margin-right: 1em;
}
.images {
flex:1 0 15em;
min-width: 15em;
max-width:800px;
}
.slides {
display:flex;
}
.caption {
margin-top: .25em;
}
<div class="header">
Title
</div>
<div class="container">
<div class="text">
<p>Something about this project is really interesting.</p>
</div>
<div class="images">
<div class="slides">
<img src="https://via.placeholder.com/800x800" />
</div>
<div class="caption">
<p>Text about this project</p>
</div>
</div>
</div>

Flexbox layout - element width

How can I achieve with flexbox this?
.img should have 25% of width .info should have 75% of width .row
should have always 100% .half should have 50%
Here is my code http://codepen.io/anon/pen/zrBRgP
.wrap {display: flex;}
.row { width: 100%;}
.half {width: 50%;}
Why the row have not 100% of the div?
Use flex-basis instead of width.
You also need to apply flex layout to the rows.
This article is a great guide to flex.
.wrap {
display: flex;
flex-direction: column;
}
div {
border: 1px black dotted;
}
img {
width: 100%;
}
.img {
flex-basis: 25%;
}
.info {
flex-basis: 75%;
}
.half {
flex-basis: 50%;
}
.row {
display: flex;
flex-basis: 100%;
}
<div class="wrap">
<div class="row">
<div class="img">
<img src="http://41.media.tumblr.com/tumblr_lvrfnaXz651qibz0jo1_r1_500.png" />
</div>
<div class="info">
<h3>Hello How Are You</h3>
</div>
</div>
<div class="row">
<div class="half">1</div>
<div class="half">2</div>
</div>
<div class="row">
<div class="half">1</div>
<div class="half">2</div>
</div>
</div>
Update from Comment by #ZcelaAnonymní
* {
box-sizing: border-box;
}
.wrap {
display: flex;
flex-direction: column;
}
div {
border: 1px black dotted;
}
img {
width: 100%;
}
.img {
flex: 0 0 25%;
}
.info {
flex: 0 0 75%;
}
.half {
flex: 0 0 50%;
}
.row {
display: flex;
flex: 0 0 100%;
flex-wrap: wrap;
}
<div class="wrap">
<div class="row">
<div class="img">
<img src="http://41.media.tumblr.com/tumblr_lvrfnaXz651qibz0jo1_r1_500.png" />
</div>
<div class="info">
<h3>Hello How Are You</h3>
</div>
</div>
<div class="row">
<div class="half">1</div>
<div class="half">2</div>
<div class="half">1</div>
<div class="half">2</div>
</div>
</div>

some issue with margin in flex container

need some help. How to fix bug with .half-img2{ margin-top: 10px; }
http://prntscr.com/94uqok
These 2 imgs height must be equal to main-img
http://plnkr.co/edit/Dvj5HfG6hJqvYPxr0ljJ?p=preview
Html:
<style type="text/css">
.test{
display: flex;
}
.test>div{
flex: 1;
}
.test .main-img{
flex-grow: 2;
}
img{
width: 100%;
}
.half-img{
margin-left: 10px;
}
.half-img2{
margin-top: 10px;
}
</style>
<div class="test">
<div class="main-img">
<img src="http://fakeimg.pl/350x200/00CED1/FFF/?text=img+placeholder">
</div>
<div class="half-img">
<div class="half-img1">
<img src="http://fakeimg.pl/350x200/00CED1/FFF/?text=img+placeholder">
</div>
<div class="half-img2">
<img src="http://fakeimg.pl/350x200/00CED1/FFF/?text=img+placeholder">
</div>
</div>
</div>
I'll ignore the images sizes as these are not really relevant to the div layout issue.
A judicious use of margins and flex-column div layout seems to be required.
Layout would be something like this.
* {
box-sizing: border-box;
}
.test {
display: flex;
width: 80%;
margin: 1em auto;
border:1px solid green;
}
img {
display: block;
}
.test div {
}
.main-img {
flex:2;
margin-right: 10px;
background: lightblue;
}
.half-img {
display: flex;
flex-direction: column;
height: 250px;
}
.half-img {
flex:1;
display: flex;
flex-direction: column;
}
.half-img div {
flex:1;
background: lightblue;
}
.half-img1 {
margin-bottom: 5px;
}
.half-img2 {
margin-top: 5px;
}
<div class="test">
<div class="main-img">
</div>
<div class="half-img">
<div class="half-img1">
</div>
<div class="half-img2">
</div>
</div>
</div>