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>
Related
This question already has answers here:
Percentage Height HTML 5/CSS
(7 answers)
Make a div fill the height of the remaining screen space
(42 answers)
Closed 1 year ago.
I am trying to use flexbox to have fixed height container ( two ) to be stuck to the bottom of the page and then have the other container take up the available space (flex-grow) . This is not giving me the desired effect so I'm not sure what I'm missing
<div class="container">
<div class="one">One</div>
<div class="two">Two</div>
</div>
.container {
height: 100%;
display: flex;
flex-direction: column;
background: black;
}
.one {
flex-grow: 1;
background: green
}
.two {
height: 90px;
background:pink;
}
Your block is limited to the place it occupies. You have to use the entire viewport in this case. Add this in your CSS :
html, body {
height: 100%;
}
The main thing that would help is height:100vh. Apart from that, to avoid scrollbar, you'll need to remove default margin and padding from html & body.
The vh unit is pretty convenient when you want the container tag to fill the available screen space without introducing vertical scrollbar.
html,
body {
margin: 0;
padding: 0;
}
.container {
height: 100vh;
display: flex;
flex-direction: column;
background: black;
}
.one {
flex-grow: 1;
background: green;
}
.two {
height: 90px;
background: pink;
}
<html>
<body>
<div class="container">
<div class="one">One</div>
<div class="two">Two</div>
</div>
</body>
</html>
Height (%) is used to define a height relative to parent's height. It depends on parent element height so you also need to set height:100% to html/body.
body, html{
height: 100%;
}
.container {
height: 100%;
display: flex;
flex-direction: column;
background: black;
}
.one {
flex-grow: 1;
background: green
}
.two {
height: 90px;
background:pink;
}
<div class="container">
<div class="one">One</div>
<div class="two">Two</div>
</div>
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
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 typical Header/Content/Footer Layout in CSS with Flexbox. Header and Footer should have a fixed size. The Content should scale with the wrapper, so I thought I give it a flex property of 1.
Works pretty well, but I want to have a img in the Content div that scales up to 100% in height of the div.
For small Images it works but when it exceets the size of the content div, the div scales to the img??
I modeled the Problem:
.wrapper{
display: flex;
flex-direction: column;
height:200pt;
background: grey;
}
.a{
height:50pt;
background: blue;
}
.b{
flex: 1;
background: red;
}
.b img{
height:100%;
}
.c{
height:50pt;
background: green;
}
<div class="wrapper">
<div class="a"></div>
<div class="b">
<!--
With Small Image it works!
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/85/WLE_Austria_Logo_%28no_text%29.svg/50px-WLE_Austria_Logo_%28no_text%29.svg.png">
-->
<img src="https://i.chzbgr.com/full/7006036736/h52434C0A/computer-says-no">
</div>
<div class="c"></div>
</div>
The reason why this happens with flex is that the flex container by default cannot be smaller than its content. So even if you set its height to 100%, the moment you put more content in it than fits, it will expand.
The solution for that is using min-height: 0 on this flex container.
.wrapper {
display: flex;
flex-direction: column;
height: 200pt;
background: grey;
}
.a {
height: 50pt;
background: blue;
}
.b {
flex: 1;
background: red;
min-height: 0;
}
.b img {
height: 100%;
}
.c {
height: 50pt;
background: green;
}
<div class="wrapper">
<div class="a"></div>
<div class="b">
<img src="https://i.chzbgr.com/full/7006036736/h52434C0A/computer-says-no">
</div>
<div class="c"></div>
</div>
I think the best solution would be to not use the fixed height for the wrapper to allow the wrapper to scale based on its content. Also, give image display block to get rid of unnecessary spacing:
.b img{
display: block;
}
.wrapper{
min-height:200pt;
}
I am just wondering if it's possible in flexbox (without javascript or positioning or css grid) to change the layout like this. On desktop
and on phone it should look like below
I am using bootstrap 4, and there is option to change order but even that is not able to fulfill the expectation.
i am able to achieve the functionality using float
<div class="container">
<div class="float-none float-lg-left col-lg-6">1</div>
<div class="float-none float-lg-right">2</div>
<div class="float-none float-lg-left col-lg-6">3</div>
</div>
I know i'm a bit late to the question, not entirely Bootstrap 4 flexbox either - but you can do this with display:flex and a media query. You just need to set a height on the parent (in this case .wrapper), so that boxes 1 and 3 are '50%' of this height.
View the snippet full screen to see the switch of the boxes:
.wrapper {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 200px;
}
.box1 {
background: #31d1d3;
}
.box2 {
background: #bce9e2;
}
.box3 {
background: #62b1b7;
}
#media screen and (min-width:797px) {
.box2 {
order: 3;
}
.box1,
.box3 {
flex: 0 0 50%;
width: 50%;
}
.box2 {
flex: 0 0 100%;
width: 50%;
}
}
<div class="container">
<div class="wrapper">
<div class="box1">1</div>
<div class="box2">2</div>
<div class="box3">3</div>
</div>
</div>
Without CSS grid it is possible BUT Column 2 MUST be smaller than Column 1 and Column 3 combined.
* {
box-sizing: border-box;
}
.box {
border: 1px solid grey;
}
#media (min-width: 576px) {
.wrapper {
padding-right: 50%;
position: relative;
}
.box--2 {
position: absolute;
height: 100%;
right: 0;
top: 0;
width: 50%;
}
}
<div class="wrapper">
<div class="box">Column 1</div>
<div class="box box--2">Column 2</div>
<div class="box">Column 3</div>
</div>
The size of .wrapper would be calculated from the height of the elements in flow (Column 1 and Column 3). If Column 2 is taller than those two, it will overflow out of the wrapper and there's nothing you can do to fix that without JavaScript.
Honestly, using CSS Grid (with IE fallbacks) is the better solution.
Is it possible to "clear" element in a "display: flex" container?
I want to achieve something like this:
20 elements in a row on a big screen
10 elements in a row on a smaller screen
5 elements in a row on a small screen
With floats, I could "clear" after each 5th element with proper media queries...
You can add flex-wrap: wrap; to the container and set the width of the elements inside.
Then you should have the control to decide on which elements the floating will stop.
Demo: http://codepen.io/imohkay/pen/gpard
You can try to add a width with percentages to the elements inside the container, along with the property flex-wrap: wrap. Then, with a media query, you manipulate the width of said elements given a breaking point. Here is an example:
.container {
display: flex;
flex-wrap: wrap;
}
.element {
width: calc(25% - 20px);
height: 100px;
margin: 10px;
background-color: red;
}
#media(max-width: 800px) {
.element {
width: calc(50% - 20px);
}
}
<div class="container">
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
</div>
As # BoltClock suggested you can "resize your flex container to accommodate the number of items on each line and let them wrap organically".
If you want to actually clear a line similar to using floats you can set a margin in the direction you want to clear.
element{
margin-right: calc( 100% - widthOfelement);
}
*{
box-sizing: border-box;
}
.parent{
display: flex;
width: 600px;
height: auto;
flex-wrap: wrap;
border: 1px grey dashed;
}
.child{
width: 100px;
height: 50px;
border: 1px orangered solid;
background-color: skyblue;
}
/*add "clear" after first child*/
.child:nth-child(1){
margin-right: calc(100% - 100px);
}
/*add "clear" after third child*/
.child:nth-child(3){
margin-right: calc(100% - 200px);
}
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
<div class="child">6</div>
</div>