Adding flex-direction: column causes elements to vanish - css

It's my first time using flex-box. I am following a tutorial where this very example works.
I have 3 colo(u)red divs, side by side as is the default for flex-box, apparently.
When I add flex-direction: column; to the container of the divs, they no longer display (for me, although they do in the tutorial video).
I have prepared a Plunker. Just uncomment /*flex-direction: column;*/ to see my problem; here's the full code too.
Any idea what I'm doing wrong?
index.html
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="lib/style.css">
<script src="lib/script.js"></script>
</head>
<body>
<h1>Hello Plunker!</h1>
<section id="container">
<div id="child_1" class="child"></div>
<div id="child_2" class="child"></div>
<div id="child_3" class="child"></div>
</section>
</body>
</html>
style.css
#container{
display: flex; /* use flex-box */
width: 100%;
/*flex-direction: column;*/
}
.child{
/*width: 200px;*/
height: 200px;
width: 100px;
flex: 1; /* all available width (will be shared) */
}
#child_1{
/*height: 150px;*/
width: 100px;
background-color: red;
flex: 2; /* twice as wide as the others */
}
#child_2{
background-color: yellow;
}
#child_3{
background-color: blueviolet;
}

In your code, the flex: 1; and flex: 2; are messing with your heights. There is a reason for that:
in case both flex-basis (other than auto) and width (or height in case of flex-direction: column) are set for an element, flex-basis has priority.
Source: MDN - flex-basis
You could get rid of them, change them to flex-grow or change the flex-basis to see the div back.
#container{
display: flex; /* use flex-box */
width: 100%;
flex-direction: column;
}
.child{
/*width: 200px;*/
height: 200px;
width: 100px;
flex-grow: 1; /* all available width (will be shared) */
}
#child_1{
/*height: 150px;*/
width: 100px;
background-color: red;
flex-grow: 2; /* twice as wide as the others */
}
#child_2{
background-color: yellow;
}
#child_3{
background-color: blueviolet;
}
<h1>Hello Plunker!</h1>
<section id="container">
<div id="child_1" class="child"></div>
<div id="child_2" class="child"></div>
<div id="child_3" class="child"></div>
</section>

Related

How to exactly fill remaining vertical space with css [duplicate]

I need to fill the remaining vertical space of #wrapper under #first with #second div.
I need an only CSS solution.
#wrapper {
width: 300px;
height: 100%;
}
#first {
width: 300px;
height: 200px;
background-color: #F5DEB3;
}
#second {
width: 300px;
height: 100%;
background-color: #9ACD32;
}
<div id="wrapper">
<div id="first"></div>
<div id="second"></div>
</div>
You can use CSS Flexbox instead another display value, The Flexbox Layout (Flexible Box) module aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic.
Example
/* CONTAINER */
#wrapper
{
width:300px;
height:300px;
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
-ms-flex-direction: column;
-moz-flex-direction: column;
-webkit-flex-direction: column;
flex-direction: column;
}
/* SOME ITEM CHILD ELEMENTS */
#first
{
width:300px;
height: 200px;
background-color:#F5DEB3;
}
#second
{
width:300px;
background-color: #9ACD32;
-webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */
-moz-box-flex: 1; /* OLD - Firefox 19- */
-webkit-flex: 1; /* Chrome */
-ms-flex: 1; /* IE 10 */
flex: 1; /* NEW, */
}
jsfiddle Example
If you want to have full support for old browsers like IE9 or below, you will have to use a polyfills like flexy, this polyfill enable support for Flexbox model but only for 2012 spec of flexbox model.
Recently I found another polyfill to help you with Internet Explorer 8 & 9 or any older browser that not have support for flexbox model, I still have not tried it but I leave the link here
You can find a usefull and complete Guide to Flexbox model by Chris Coyer here
Using CSS Flexbox (MDN Web Docs).
html, body {
height: 100%;
}
.wrapper {
display: flex;
flex-direction: column;
width: 300px;
height: 100%;
}
.first {
height: 50px;
}
.second {
flex-grow: 1;
}
<div class="wrapper">
<div class="first" style="background:#b2efd8">First</div>
<div class="second" style="background:#80c7cd">Second</div>
</div>
You can do this with position:absolute; on the #second div like this :
FIDDLE
CSS :
#wrapper{
position:relative;
}
#second {
position:absolute;
top:200px;
bottom:0;
left:0;
width:300px;
background-color:#9ACD32;
}
EDIT : Alternative solution
Depending on your layout and the content you have in those divs, you could make it much more simple and with less markup like this :
FIDDLE
HTML :
<div id="wrapper">
<div id="first"></div>
</div>
CSS :
#wrapper {
height:100%;
width:300px;
background-color:#9ACD32;
}
#first {
background-color:#F5DEB3;
height: 200px;
}
If you can add an extra couple of divs so your html looks like this:
<div id="wrapper">
<div id="first" class="row">
<div class="cell"></div>
</div>
<div id="second" class="row">
<div class="cell"></div>
</div>
</div>
You can make use of the display:table properties:
#wrapper
{
width:300px;
height:100%;
display:table;
}
.row
{
display:table-row;
}
.cell
{
display:table-cell;
}
#first .cell
{
height:200px;
background-color:#F5DEB3;
}
#second .cell
{
background-color:#9ACD32;
}
Example
Have you tried changing the wrapper height to vh instead of %?
#wrapper {
width:300px;
height:100vh;
}
That worked great for me when I wanted to fill my page with a gradient background for instance...
If you don't want to have fix heights for your main-container (top, bottom, ....), you can simply use this css-file to get a flex-container which uses the remaining space incl. working!!! scrollbars
Fiddler
<!DOCTYPE html>
<html >
<head>
<title>Flex Container</title>
<link rel="stylesheet" href="http://demo.qooxdoo.org/5.0/framework/indigo-5.0.css">
<style>
.cont{
background-color: blue;
position: absolute;
height: 100%;
width: 100%;
}
.headerContainer {
background-color: green;
height: 100px;
width: 100%;
}
.mainContainer {
background-color: white;
width: 100%;
overflow: scroll
}
.footerContainer {
background-color: gray;
height: 100px;
width: 100%;
}
</style>
</head>
<body class="qx-flex-ready" style="height: 100%">
<div class="qx-vbox cont">
<div class="headerContainer">Cell 1: flex1</div>
<div class="mainContainer qx-flex3">
x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
</div>
<div class="footerContainer" >Cell 3: flex1</div>
</div>
</body>
</html>
All you need is a bit of improved markup. Wrap the second within the first and it will render under.
<div id="wrapper">
<div id="first">
Here comes the first content
<div id="second">I will render below the first content</div>
</div>
</div>
Demo
You can just add the overflow:auto option:
#second
{
width:300px;
height:100%;
overflow: auto;
background-color:#9ACD32;
}

Full-height flex item with height set to 0

I have the following code as working on development with flexbox.
#container {
display: flex;
justify-content: space-around;
width: 100%;
}
.content {
border: 1px solid black;
display: flex;
flex-direction: column;
height: 400px;
width: 400px;
}
#item1 {
background-color: red;
flex-grow: 1;
height: 0;
}
#item2 {
background-color: green;
flex-grow: 1;
height: 100px;
}
#item3 {
background-color: blue;
flex-grow: 1;
height: 900px;
}
<div id="container">
<div class="content">
<div id="item1"></div>
</div>
<div class="content">
<div id="item2"></div>
</div>
<div class="content">
<div id="item3"></div>
</div>
</div>
I know that setting flex-grow: 1 would take the remaining space of its parent. However, the property height seems to have no effect whatever its value is.
Reason being your flex-direction is set to column, which mean the flex-grow reacts from top to bottom, so the flex-grow responding to the height instead of width.
another question is, why flex-direction is column, but width is filled up, because it is a <div> displayed as block, the width is auto filled by display: block;
you are using flex-grow that’s why. have a look on this https://www.w3schools.com/cssref/css3_pr_flex-grow.asp
https://stackoverflow.com/a/64748435/1095913 (down here) is right, solution is: flex-grow: 0;
Here's another reference https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow

Flex item override max-width property

I am trying to make a flex container of divs in which all the divs will have the same width (two divs per line, 50% width of the container each of them).
I have set the divs inside the container with max-width: 50%; because I want them to be equals but it does not seem to respect this max-width when there is only one item in this line.
HTML:
<div id="container">
<div id="left" class="block">Left</div>
<div id="center" class="block">
<div class="flexContainer">
<div class="flexDiv"></div>
</div>
<div class="flexContainer">
<div class="flexDiv"></div>
</div>
<div class="flexContainer">
<div class="flexDiv"></div>
</div>
</div>
<div id="right" class="block">Right</div>
</div>
CSS:
html, body{
width: 100%;
height: 100%;
}
#container{
display: flex;
height: 100%;
background-color: blue;
}
.block{
flex: 1;
}
#left{
background-color: green;
}
#center{
display: flex;
flex: 1;
flex-wrap: wrap;
align-content: flex-start;
}
#right{
background-color: orange;
}
.flexContainer{
flex: 1;
min-width: 100px;
max-width: 50%;
height: 150px;
background-color: red;
padding: 10px;
}
.flexDiv{
width: 100%;
height: 100%;
background-color: yellow;
}
JSFiddle in which you can see how the width of the third element is bigger than the others.
Why the flex divs inside the container are not respecting max-width property?
Thanks in advance!
you can reset or switch box model to include padding within width calculation:
https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
https://www.w3.org/TR/css-ui-3/#box-sizing
.flexContainer{
flex: 1;
min-width: 100px;
max-width: 50%;
height: 150px;
background-color: red;
padding: 10px;
box-sizing:border-box;/* includes borders & padding within width calculation
}
https://jsfiddle.net/b5h9rjcd/1/

Flexbox: 3 divs, 2 columns

I'm new to flexbox, so please bear with me. My html:
<div class="container">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div>
With flexbox, I am trying to achieve the following layout:
.
What's the simplest way I can achieve this without setting a height for the container? .one is expected to change in height.
You can achieve this by setting flex-direction to column.
As requested, the width of the second div is static. I am using calc for the other 2 divs.
.container {
display: flex;
flex-wrap: wrap;
flex-direction: column;
height: 100px;
}
.one,
.three {
flex: 0 0 50%;
background: cyan;
width: calc(100% - 100px);
}
.two {
flex: 0 0 100%;
order: 1;
background: moccasin;
width: 100px;
}
.three {
background: tomato;
}
<div class="container">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div>
EDIT .... Late answer , iI leave it since approach looks a little different from other even that it i think it very similar .. but not much choice about the way flex is working :)
you may need to set an height to parent container and childs on first column. order will organize the flow of containers.
codepen to check behavior and how it breaks while windows is reduced or content increased
.one {
background: #A1EB88;
}
.two {
background: #E7AAF6
}
.three {
background: #F7F467
}
.container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 50vh;/* height is needed to force wrapping */
}
.one,
.three {
order: -1;/* bring them in front of other(s) */
height: 50%;/* share the height (if three of them, then put it down to 33.33% to share evenly height avalaible) */
}
.two {
flex: 1;/* equals height:100%; it will fill entire height */
width: 200px;/* here your fixed width */
}
<h1>test it also in full page mode </h1>
<div class="container">
<div class="one">one</div>
<div class="two">two</div>
<div class="three">three</div>
</div>

CSS Stick Footer to Bottom

Here is my code to stick the footer to bottom of the page:
#footer {
background-color: #0F2157;
width: 100%;
bottom: 0px;
min-height: 35px;
padding-top: 5px;
}
When I'm doing it with height it works perfectly fine, but when I'm trying to set the minimum height it leaves a little space under the footer. Any guess how to fix that?
First of all, the height of body, html and container (see element with class 'container') has to have height: 100%;
In this solution I have used flex box. It is supported by all modern browsers and IE11.
It's necessary to add the following properties to container:
display: flex;
flex-direction: column; /*the flex items are placed in column, by default it is in row*/
To move footer to bottom, just add to flex item
margin-top: auto; /* it grabs all free space between flex items and put it before this flex item */
html, body {
height: 100%;
}
.container {
height: 100%;
background-color: green;
display: flex;
flex-direction: column;
}
.header {
height: 20%;
background-color: yellow;
}
.content {
background-color: white;
}
.footer {
min-height: 20%;
background-color: blue;
margin-top: auto;
}
<div class="container">
<div class="header">Header</div>
<div class="content">It's content</div>
<div class="footer">Footer in bottom</div>
</div>
What about using Flexbox? It is supported by IE>=10.
To use that, you have to split your page at least in two separated elements: The "upper"-one (.content) with the whole content of your page and the footer.
The "upper"-one gets the value flex: 1, which is a shorthand for:
flex-grow: 1
flex-shrink: 1
flex-basis: auto
This means, that the "upper"-element could grow to the maximum, while the footer reserves only it's actually required space.
Code snippet
html {
height: 100%;
}
body {
min-height: 100%;
margin: 0;
display: flex;
flex-direction: column;
}
.content {
flex: 1;
}
<!doctype html>
<html>
<head>
</head>
<body>
<div class="content"></div>
<footer class="footer">
Hey footer!
</footer>
</body>
</html>
You used min height 35 px. I think your content's height inside of footer is more than 35px. So check the margin or padding of all footer elements.
It will be better, if you can make a jsfiddle demo.
[SOLVED]
I found this to be working for my example:
#footer {
position: absolute;
bottom: 0;
width: 100%;
}

Resources