Align 3 divs in one container (flex column) [duplicate] - css

This question already has answers here:
Force flex item to span full row width
(2 answers)
Closed 2 years ago.
I have one div, which contains 3 divs, in flex-direction column.
Is there any way, I can make the bottom two red divs, sit next to each other (side by side). And not on top of each other? Like this:
I know I can store these two red divs in another row and set the direction to row.
But I wondered if this can be achieved, specifically with this html structure:
Thanks,
.main {
display: flex;
flex-direction: column;
width: 200px;
border: 1px solid black;
}
.top {
background-color: blue;
color: red;
width: 100%;
height: 50px;
}
.bottom {
background-color: red;
color: white;
width: 50%;
height: 50px;
}
<div class="main">
<div class="box top">Box 1</div>
<div class="box bottom">Box 2</div>
<div class="box bottom">Box 3</div>
</div>
<div class="main">
<div class="box top">Box 1</div>
<div class="box bottom">Box 2</div>
<div class="box bottom">Box 3</div>
</div>

Validate if this is what you want.
I removed the orientation and worked on the flex property values.
I also added the flex-wrap property to the container.
The flex-wrap property is a sub-property of the Flexible Box Layout module. It defines whether the flex items are forced in a single line or can be flowed into multiple lines
values definition:
/* Three values: flex-grow | flex-shrink | flex-basis */
flex: 0 1 100%;`
You can read the documentation here.
.main {
display: flex;
flex-wrap: wrap;
width: 200px;
border: 1px solid black;
}
.top {
flex: 0 1 100%;
background-color: blue;
color: red;
height: 50px;
}
.bottom {
flex: 1;
background-color: red;
color: white;
height: 50px;
}
<div class="main">
<div class="box top">Box 1</div>
<div class="box bottom">Box 2</div>
<div class="box bottom">Box 3</div>
</div>

You could wrap your bottom boxes in a new container with display: flex and flex-direction: row. Since you have your main wrapper as flex column, the children will align themselves as a column regardless of their width. You are basically giving in this instance a child to main which sets itself in the column layout that has in its turn children that set themselves in a row layout :)
.main {
display: flex;
flex-direction: column;
width: 200px;
border: 1px solid black;
}
.box-bottom-wrapper {
display: flex;
flex-direction: row;
}
.box-top {
background-color: blue;
color: red;
width: 100%;
height: 50px;
}
.box-bottom {
background-color: red;
color: white;
width: 50%;
height: 50px;
}
<div class="main">
<div class="box-top">Box 1</div>
<div class=box-bottom-wrapper>
<div class="box-bottom">Box 2</div>
<div class="box-bottom">Box 3</div>
</div>
</div>

Related

Positioning of elements in a flex layout [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I need help laying out my html with css flexbox (I hope this is doable with flexbox).
I have a Container with a variable amount of images. Image can be either landscape or portrait orientation. If image is landscape (Image 1) - it will occupy one 'row'. If image is portrait - there are two cases:
If there is one portrait image in a 'row' (either it's the last image, or the next one is landscape) - then Image 2 should be centered on the 'row'.
If there are two successive portrait images - I'd like them to both fit into one 'row'
Pls note, that the 'rows' are an abstract notion here. I don't want to use css grid (unless there are absolutely no other options).
Using a flexbox in combination with the justify-content: center; and flex-wrap: wrap; should achieve the exact effect you are looking for.
Please see the two code snippets below for the two examples. I have used multiple coloured div with a width and height to simulate the horizontal and vertical image types you referred to.
.flex {
display: flex;
flex-wrap: wrap;
width: 100px;
border: 2px black solid;
padding: 1em;
justify-content: center;
}
.horizontal {
background: yellow;
width: 100px;
height: 50px;
margin-bottom: 1em;
}
.vertical {
background: green;
width: 50px;
height: 100px;
}
<div class="flex">
<div class="horizontal">Image 1</div>
<div class="vertical">Image 2</div>
</div>
.flex {
display: flex;
flex-wrap: wrap;
width: 100px;
border: 2px black solid;
padding: 1em;
justify-content: center;
}
.horizontal {
background: yellow;
width: 100px;
height: 50px;
margin-bottom: 1em;
}
.vertical {
background: green;
width: 50px;
height: 100px;
}
#blue {
background: blue;
}
<div class="flex">
<div class="horizontal">Image 1</div>
<div class="vertical">Image 2</div>
<div class="vertical" id="blue">Image 3</div>
</div>
This can be done with align-items: center and flex-wrap:wrap:
.flex{
width: 220px;
display:flex;
align-items: center;
flex-wrap:wrap;
}
.flex img{
border: solid 4px #efefef;
box-sizing:border-box;
margin: 0 auto;
}
<h3>Example 1</h3>
<div class="flex">
<img src="https://placekitten.com/220/60">
<img src="https://placekitten.com/110/120">
</div>
<h3>Example 2</h3>
<div class="flex">
<img src="https://placekitten.com/220/60">
<img src="https://placekitten.com/100/120">
<img src="https://placekitten.com/100/120">
</div>
You can easily achieve this using the same grid system as Bootstrap using class like container, row, col:
.container {
display: flex;
flex-direction: column;
}
.row {
display: flex;
}
.align-center {
align-items: center;
justify-content: center;
}
.image1 {
width: 500px;
height: 300px;
background-color: red;
}
.image2,
.image3 {
width: 250px;
height: 500px;
}
.image2 {
background-color: yellow;
}
.image3 {
background-color: blue;
}
.image1,
.image2,
.image3 {
border: solid #000 2px;
}
<div class="container align-center">
<div class="row">
<div class="col image1">
<h1>image1</h1>
</div>
</div>
<div class="row align-center">
<div class="col image2">
<h1>image2</h1>
</div>
</div>
</div>
<div class="container align-center">
<div class="row">
<div class="col image1">
<h1>image1</h1>
</div>
</div>
<div class="row align-center">
<div class="col image2">
<h1>image2</h1>
</div>
<div class="col image3">
<h1>image3</h1>
</div>
</div>
</div>

Flex box grid that fits to parent [duplicate]

This question already has answers here:
Make container shrink-to-fit child elements as they wrap
(4 answers)
CSS when inline-block elements line-break, parent wrapper does not fit new width
(2 answers)
Closed 3 years ago.
I'm trying to have a list of items that wrap to the container size. I want the container to have a different background colour than the page background.
The code below isn't doing what I want.
An image is going to say so much more. This is what I'm after:
body {
background-color: grey;
margin: 0;
font-family: Arial;
}
.text { color: white; }
.wrapper {
display: flex;
justify-content: center;
}
.content {
padding: 10px;
background-color: green;
}
.listings {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
}
.item {
width: 100px;
padding: 15px;
height: 100px;
background-color: lightblue;
border: 1px solid black;
margin: 15px;
}
<body>
<div class="wrapper">
<div class="content">
<div class="text">Just some text that should wrap and resize. More text blah blah.</div>
<div class="listings">
<div class="item">Listing 1</div>
<div class="item">Listing 2</div>
<div class="item">Listing 3</div>
<div class="item">Listing 4</div>
<div class="item">Listing 5</div>
</div>
</div>
</div>
</body>
If it's a grid layout, why not just use grid instead?
body {
background-color: grey;
margin: 0;
font-family: Arial;
}
.text { color: white; }
.wrapper {
display: flex;
justify-content: center;
}
.content {
padding: 10px;
background-color: green;
}
.listings {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.item {
padding: 15px;
height: 100px;
background-color: lightblue;
border: 1px solid black;
margin: 15px;
}
<body>
<div class="wrapper">
<div class="content">
<div class="text">Just some text that should wrap and resize. More text blah blah.</div>
<div class="listings">
<div class="item">Listing 1</div>
<div class="item">Listing 2</div>
<div class="item">Listing 3</div>
<div class="item">Listing 4</div>
<div class="item">Listing 5</div>
</div>
</div>
</div>
</body>

CSS flex-wrap how to make the height do not stretch [duplicate]

This question already has answers here:
CSS-only masonry layout
(4 answers)
Closed 3 years ago.
There are big gaps between box3, box1 and box4, box6 How to get rid of the gap? so each box could have the dynamic height?
.wrap {
display: flex;
align-items: baseline;
align-content:flex-start;
justify-content: space-between;
flex-wrap: wrap;
background-color: lightblue;
}
.box {
display: flex;
background-color: tomato;
box-sizing: border-box;
border: 1px solid #C4C4C4;
height: 100px;
width: 45%;
margin-top: 15px;
}
.box1, .box4 {
height: 20px;
}
<div class="wrap">
<div class="box box1">box1</div>
<div class="box box2">box2</div>
<div class="box box3">box3</div>
<div class="box box4">box4</div>
<div class="box box5">box5</div>
<div class="box box6">box6</div>
</div>
Here is the desired layout. Thanks
The default direction of flex is row, and when you use flex-wrap: wrap push overflowed element downed to another row, and the row height will default always equal to the highest element of that row, that why you seeing the element having that gap.
This can be done if you change the flex direction to column and give the wrap element a fixed height so it push overflowed element to it right, from top to bottom.
.wrap {
/*Added these*/
height: 300px;
flex-direction: column;
/*-----------*/
display: flex;
align-items: baseline;
align-content: space-around;
flex-wrap: wrap;
background-color: lightblue;
}
.box {
display: flex;
background-color: tomato;
box-sizing: border-box;
border: 1px solid #C4C4C4;
height: 100px;
width: 45%;
margin-top: 15px;
}
.box1, .box5 {
height: 20px;
}
<div class="wrap">
<div class="box box1">box1</div>
<div class="box box2">box2</div>
<div class="box box3">box3</div>
<div class="box box4">box4</div>
<div class="box box5">box5</div>
<div class="box box6">box6</div>
</div>
Since FlexBox is going to attempt to line the boxes up in rows, you have to create two separate FlexBoxes with flex-flow: column set. You can achieve this affect with about the same amount of CSS though:
.outer{
display: flex;
padding: 15px 0;
background-color: lightblue;
}
.wrap {
display: flex;
flex-flow: column;
flex-grow: 1;
}
.wrap:nth-child(2){
align-items: flex-end;
}
.box {
background-color: tomato;
box-sizing: border-box;
border: 1px solid #C4C4C4;
height: 100px;
width: 90%;
margin-top: 15px;
}
.box1, .box4{
margin-top: 0;
}
.box1, .box5 {
height: 20px;
}
<div class="outer">
<div class="wrap">
<div class="box box1">box1</div>
<div class="box box2">box2</div>
<div class="box box3">box3</div>
</div>
<div class="wrap">
<div class="box box4">box4</div>
<div class="box box5">box5</div>
<div class="box box6">box6</div>
</div>
</div>
You could instead use a CSS grid layout depending on your browser support requirements.
Great resource on CSS Grid: https://css-tricks.com/snippets/css/complete-guide-grid/
Browser support: https://caniuse.com/#feat=css-grid
.wrap {
display: grid;
background-color: lightblue;
grid-template-columns: 50% 50%;
grid-template-rows: repeat(14, 20px);
background-color: lightblue;
}
.box {
background-color: tomato;
box-sizing: border-box;
border: 1px solid #C4C4C4;
height: 100px;
width: 90%;
margin-top: 15px;
}
.box1 {
grid-row: 1/2;
}
.box2 {
grid-row: 1/5;
}
.box3 {
grid-row: 3/8;
}
.box4 {
grid-row: 7/8;
}
.box5, .box6 {
grid-row: 9/14;
}
.box1, .box4 {
height: 20px;
}
<div class="wrap">
<div class="box box1">box1</div>
<div class="box box2">box2</div>
<div class="box box3">box3</div>
<div class="box box4">box4</div>
<div class="box box5">box5</div>
<div class="box box6">box6</div>
</div>
Flex is always going to create a grid which is why you're seeing big spaces. Neither flex:row or flex:column will achieve the order that you have specified. Flex column will be able to achieve the layout that you're after like Ethan Vu suggested but that main caveat in that solution is a mandatory fixed height container which you may not want.
If you want a layout like that and don't want a fixed height then you can try using css columns or go for a javascript solution and use a 2 column masonry layout.

Flexbox item does not shrink when only one item [duplicate]

This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 3 years ago.
In flexbox, if you set flex-flow: column nowrap and the elements inside have non-zero value of flex shrink, they should shrink down to all fit inside the flex container.
I have found that if you have only one item in this container and it has content bigger than the flex-container then it will not shrink down. But if other elements are included in the container (if it is not the only item) then it will shrink down.
Best visualized in this CodePen.
Here is the same code from the CodePen.
.container {
padding: 10px;
height: 100px;
width: 100px;
background: red;
margin: 5px 20px;
display: flex;
flex-flow: column nowrap;
align-items: center;
}
.item {
width: 80px;
height: 40px;
background: blue;
margin: 5px;
/* same as
flex: 1 1 40px;
*/
}
.super.item {
height: 200px;
}
.item div {
width: 10px;
height: 150px;
background: black;
}
body {
margin: 0;
display: flex;
}
<div class='container'>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'>
</div>
</div>
<div class='container'>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'>
<div></div>
</div>
</div>
<div class='container'>
<div class='item super'>
</div>
</div>
<div class='container'>
<div class='item super'>
<div></div>
</div>
</div>
Is there an explanation on why that last div does not shrink to fit the flex container?
What about making the height of those contents inherit their parent's one?
.super.item {
height: inherit;
}
.item div {
width: 10px;
height: inherit;
background: black;
}
Snippet below, is that what you're trying to achieve? :
.container {
padding: 10px;
height: 100px;
width: 100px;
background: red;
margin: 5px 20px;
display: flex;
flex-flow: column nowrap;
align-items: center;
}
.item {
width: 80px;
height: 40px;
background: blue;
margin: 5px;
/* same as
flex: 1 1 40px;
*/
}
.super.item {
height: inherit;
}
.item div {
width: 10px;
height: inherit;
background: black;
}
body {
margin: 0;
display: flex;
}
<div class='container'>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'>
</div>
</div>
<div class='container'>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'>
<div></div>
</div>
</div>
<div class='container'>
<div class='item super'>
</div>
</div>
<div class='container'>
<div class='item super'>
<div></div>
</div>
</div>
I don't know if you are talking about it or not.
Your div is taking width and height as item.
so whenever you add another div it will add height of 150px.
.item div{
width: 10px;
height: 150px;
background: black;
}
Very simple rule for items of a flexbox:
Items grow value is 0 and shrink is 1 and the base-case is auto.
flex: 0 1 auto
So
.item{
width: 80px;
height: 40px; # will be used as base-case
background: blue;
margin: 5px;
/* same as
flex: 1 1 40px;
*/
}
Why does second container's item shrink? Easy. base-case is 40px or on the other hand it dose not have the class .super. Add .super and see what happens.
<div class='container'>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'> # flex's item height: 40px;
<div></div> # regular div
</div>
</div>
Why the third container that has the class .super does shrink? while height: 200px and it should overflow? Easy. it is the same as: flex: 0 1 200px (this is not quite right, see the comment below, what #TemaniAfif has pointed out)
try it:
.super.item{
/* height: 200px; */
flex: 0 1 200px; # equal to height: 200px
}
now try this:
.super.item{
/* height: 200px; */
flex: 0 0 200px; # turn off auto grow / shrink
}
Why the fourth overflows?. Easy. the item has a child that is a regular div
<div class='container'>
<div class='item super'> # flex's item
<div></div> # regular div
</div>
</div>
and the height of this div is 150px
.item div{
width: 10px;
height: 150px; # remove this one, it shrinks
background: black;
}

How to make a css grid grow to contain a flexbox when using grid-auto-rows?

In the following codepen you will see that there is a flexbox inside of a css grid. As you can see, the contents of the flexbox div are overflowing under other parts of the grid.
If I remove the CSS grid-auto-rows:100px; then the flexbox contents no longer overflow. However, I really want the other css grid items to be 100px tall, unless their contents are too tall to be contained within 100px.
How can I have all the css grid items default to 100px tall while having any items whose contents are taller than 100px grow to hold all of the contents?
* {box-sizing: border-box;}
.wrapper {
display: grid;
grid-auto-rows: 100px;
}
.wrapper > div {
border: 2px solid #ffa94d;
border-radius: 5px;
background-color: #ffd8a8;
padding: 1em;
color: #d9480f;
}
.box2 {
display:flex;
flex-direction: column;
}
.box2 > div{
border: 2px solid #ffa999;
border-radius: 5px;
background-color: #ffd899;
padding: 1em;
color: #d94899;
}
<div class="wrapper">
<div class="box1">Box 1</div>
<div class="box2">
Box 2
<div class="flex1">Flex One</div>
<div class="flex2">Flex One</div>
<div class="flex3">Flex One</div>
<div class="flex4">Flex One</div>
</div>
<div class="box3">Box 3</div>
</div>
Use the minmax(min, max) function.
* {box-sizing: border-box;}
.wrapper {
display: grid;
grid-auto-rows: minmax(100px, auto);
}
.wrapper > div {
border: 2px solid #ffa94d;
border-radius: 5px;
background-color: #ffd8a8;
padding: 1em;
color: #d9480f;
}
.box2 {
display:flex;
flex-direction: column;
}
.box2 > div{
border: 2px solid #ffa999;
border-radius: 5px;
background-color: #ffd899;
padding: 1em;
color: #d94899;
}
<div class="wrapper">
<div class="box1">Box 1</div>
<div class="box2">
Box 2
<div class="flex1">Flex One</div>
<div class="flex2">Flex One</div>
<div class="flex3">Flex One</div>
<div class="flex4">Flex One</div>
</div>
<div class="box3">Box 3</div>
</div>

Resources