Left and right aligning flex items - css

I have 4 divs all in the same wrapper, I need the first 3 to align left (text) and the 4th to align right (an image).
There desired effect is as follows.
<one> <
<two> Four
<three> >
The html is basic literally just 4 divs in a wrapper and the css can just be display:flex on the wrapper.
I have partially achieved this by adding flex direction column onto the wrapper so all 4 then stack vertically but I need the 4th to align right as above.
Any help would be hugely appreciated.
Thanks

Using flexbox:
* {
box-sizing: border-box;
}
.container {
height: 500px;
border: 1px solid green;
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
.item {
flex: 1;
padding: .5rem;
border: 1px dashed lightblue;
}
.one, .two, .three {
flex-basis: 33.333333%;
}
<div class="container">
<div class="item one">1</div>
<div class="item two">2</div>
<div class="item three">3</div>
<div class="item four">4</div>
</div>
Using css-grid:
* {
box-sizing: border-box;
}
.container {
height: 500px;
border: 1px solid green;
display: grid;
}
.item {
padding: .5rem;
border: 1px dashed lightblue;
}
.four {
grid-column: 2;
grid-row: 1 / span 3;
}
<div class="container">
<div class="item one">1</div>
<div class="item two">2</div>
<div class="item three">3</div>
<div class="item four">4</div>
</div>

.wrapper {
display: flex;
flex-direction: row;
}
<div class="wrapper">
<div>
<div>one</div>
<div>two</div>
<div>three</div>
</div>
<div>
<div>four</div>
</div>
</div>

Related

How to move a flex container to the right?

I have a flex container that contains a varying number of other flex containers. I'm trying to get the outermost container to be justified to the right and only take up 60% of the available width. Then I want to have another flex container take up that space on the left. #Feed is the outermost container and the .tweets are its children. #friends is the independent flex container.
#feed {
display: flex;
flex-direction: column;
box-sizing: border-box;
width: 60%;
}
.tweet {
display: flex;
border: 2px solid red;
border-radius: 25px;
flex: 1;
flex-wrap: wrap;
}
#friends {
display: flex;
}
Here is an example of two flex items taking up 40% and 60% space.
#wrapper {
display: flex;
}
.column-40 {
width: 40%;
background: lightgray;
}
.column-60 {
width: 60%;
background: grey;
}
.tweet {
border: 1px solid blue;
}
<div id="wrapper">
<div class="column-40">
<div class="tweet">tweet</div>
<div class="tweet">tweet</div>
<div class="tweet">tweet</div>
</div>
<div class="column-60">
<div class="tweet">tweet</div>
<div class="tweet">tweet</div>
<div class="tweet">tweet</div>
</div>
</div>
When you just want the 60% wrapper to be aligned right you can remove the first column and justify the content to the end:
#wrapper {
display: flex;
justify-content: flex-end;
}
.column-60 {
width: 60%;
}
.tweet {
border: 1px solid blue;
}
<div id="wrapper">
<div class="column-60">
<div class="tweet">tweet</div>
<div class="tweet">tweet</div>
<div class="tweet">tweet</div>
</div>
</div>

Expand divs in column layout to match original height of parent

As the title specifies: I have a number of divs in a column layout, and I would like them to expand to match the original height of the parent.
The parent doesn't have a fixed height, as it is part of a flex-based page layout.
Is this possible? In the attached example, I would like both .child divs to be equal in height, and the same height as the original height of the parent.
I can believe that it is impossible based on the way that CSS works.
body {
margin: 0;
}
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.parent {
flex: 1;
}
.child {
border: 1px solid black;
}
<div class="container">
<div class="header">Header</div>
<div class="parent">
<div class="child">Child 1</div>
<div class="child">Child 2</div>
</div>
<div class="footer">Footer</div>
</div>
You may imbricate flex boxes.
body {
margin: 0;
}
.container ,.parent{
display: flex;
flex-direction: column;
min-height: 100vh;
}
.parent, .child {
flex: 1;
min-height:auto;
}
.child {
border: 1px solid black;
}
<div class="container">
<div class="header">Header</div>
<div class="parent">
<div class="child">Child 1</div>
<div class="child">Child 2</div>
</div>
<div class="footer">Footer</div>
</div>
For the other part of the question : the same height as the original height of the parent. sibblings or parent of .container looks like missing to visualize how height is applied or comes from.
Could be something alike:
body {
margin: 0;
}
.container,
.parent {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.parent {
flex: 1;
min-height: auto;
overflow: auto;
}
.child {
flex: 1;
min-height: 100%;
border: 1px solid black;
}
* {
box-sizing: border-box;
}
<div class="container">
<div class="header">Header</div>
<div class="parent">
<div class="child">Child 1</div>
<div class="child">Child 2</div>
</div>
<div class="footer">Footer</div>
</div>
edit , from comment
For chrome, A bit of js can used to set a usable min-height value for that browser (and others).
let MyParent = document.querySelector('.parent');
let MyParentH = MyParent.offsetHeight;
MyParent.style.setProperty("--MyHeight", MyParentH +"px");
body {
margin: 0;
}
.container,
.parent {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.parent {
flex: 1;
min-height: auto;
overflow: auto;
}
.child {
flex: 1;
min-height: 100%;/* where var css is not supported */
min-height:var(--MyHeight, 100%);
border: 1px solid black;
}
* {
box-sizing: border-box;
}
<div class="container">
<div class="header">Header</div>
<div class="parent">
<div class="child">Child 1</div>
<div class="child">Child 2</div>
</div>
<div class="footer">Footer</div>
</div>
give 100% of the parents width to its children.
.parent {
display: 'flex';
flex-direction: column;
height: 100%;
}
.child {
border: 1px solid black;
height: 100%;
}
Do you want something like that?
body {
margin: 0;
}
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.parent {
flex: 1;
display: flex;
}
.child {
border: 1px solid black;
}
<div class="container">
<div class="header">Header</div>
<div class="parent">
<div class="child">Child 1</div>
<div class="child">Child 2</div>
</div>
<div class="footer">Footer</div>
</div>
PS: Update my answer with comment advice
body {
margin: 0;
}
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.parent {
flex: 1;
display: flex;
flex-direction: column;
}
.child {
border: 1px solid black;
flex-grow: 1;
}
<div class="container">
<div class="header">Header</div>
<div class="parent">
<div class="child">Child 1</div>
<div class="child">Child 2</div>
</div>
<div class="footer">Footer</div>
</div>

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.

Flex box - arrange items in column with multiple elements on each row if space allows

I want to arrange some items of variable width in a column, where the column has a fixed width. But I want elements to stack up next to each other if the total width of a group of elements doesn't exceed the column width. In the snippet, I want to add CSS to the first container so that that the 2nd and 3rd divs will be next to each other, as they are in the second container. I don't know the element widths in advance so I can't just do this manually by putting divs around the elements that should be adjacent. I want to also accomplish with just flexbox, not CSS grids if that's also a solution.
.container {
width: 500px;
border: 1px solid red;
}
.flexcol {
display: flex;
flex-direction: column;
align-items: center;
}
.inlineblock > div {
display: inline-block;
}
.item {
border: 1px solid black;
font-size: 24pt;
text-align: center;
}
.item1, .item4 {
width: 400px;
}
.item2, .item3 {
width: 200px;
}
<div class="container flexcol">
<div class="item item1">
Item 1
</div>
<div class="item item2">
Item 2
</div>
<div class="item item3">
Item 3
</div>
<div class="item item4">
Item 4
</div>
</div>
<div class="container flexcol">
<div class="item item1">
Item 1
</div>
<div class="inlineblock">
<div class="item item2">
Item 2
</div>
<div class="item item3">
Item 3
</div>
</div>
<div class="item item4">
Item 4
</div>
</div>
Fiddle here of same code: https://jsfiddle.net/6ycer7b0/1/
You can do this with a row direction and enable the wrap to simulate a column behavior as the elements will stack above each other:
.container {
width: 500px;
border: 1px solid red;
}
.flexcol {
display: flex;
flex-direction: row;
flex-wrap:wrap;
justify-content: center;
}
.item {
border: 1px solid black;
font-size: 24pt;
text-align: center;
}
.item1, .item4 {
width: 400px;
}
.item2, .item3 {
width: 200px;
}
<div class="container flexcol">
<div class="item item1">
Item 1
</div>
<div class="item item2">
Item 2
</div>
<div class="item item3">
Item 3
</div>
<div class="item item4">
Item 4
</div>
</div>

Reorder columns in reverse order

I have a list of flex items within a flexbox. The order of the items matter, and for accessibility purposes, the items need to show up in the correct order in the dom.
[[itema][itemb][itemc]]
When the flexbox shrinks I would like to have the items wrap in reverse order, e.g. itema wraps first, etc. Is there any way to have the itema wrap first? Thanks!
Edit:
Here is the code
<div class="flex">
<div class="container">
<div class="item">item1</div>
<div class="item orange">item2</div>
<div class="item blue">item3</div>
</div>
<div class="last-item green">menu</div>
</div>
.flex {
display: flex;
background-color: yellow;
height: 80px;
overflow: hidden;
color: #fff;
}
.container {
display: flex;
flex: 1 1 auto;
flex-wrap: wrap;
}
.item {
flex: 0 0 auto;
background-color: red;
height: 80px;
padding: 0 40px;
}
.last-item {
width: 40px;
flex: 0 0 auto;
height: 80px;
}
JSFiddle
All the behavior is as desired except I want the first item to wrap first. Any ideas? Thanks!
You can use the flex-direction: column-reverse to get your solution.
#media (max-width: 768px) {
.flex-box {
display: flex;
flex-direction: column-reverse;
}
}
.first,
.second,
.third {
display: inline-block;
}
<div class="flex-box">
<div class="first">
<p>First Box</p>
<img src="http://placehold.it/300x300" />
</div>
<div class="second">
<p>Second Box</p>
<img src="http://placehold.it/300x300" />
</div>
<div class="third">
<p>Third Box</p>
<img src="http://placehold.it/300x300" />
</div>
</div>
JSfiddle Demo
To make item1 wrap first, you can use flex-wrap: wrap-reverse on your flex container.
Try this simplified version of you code:
<div class="container">
<div class="item">item1</div>
<div class="item orange">item2</div>
<div class="item blue">item3</div>
</div>
.container {
display: flex;
flex: 0 1 auto;
flex-wrap: wrap-reverse;
}
.item {
background-color: red;
height: 80px;
padding: 0 40px;
}
.orange {
background-color: orange;
}
.blue {
background-color: blue
}
See the MDN reference for browser support.

Resources