flexbox vertical align child top, center another - css

I've got the following markup:
.row {
display: flex;
align-items: stretch;
margin: -16px;
background: #ddd;
}
.row .col {
display: flex;
flex-direction: column;
justify-content: center;
flex: 1;
margin: 16px;
background: #fff;
}
.header, .content, .footer {
padding: 16px;
background: red;
}
<div class="row">
<div class="col">
<div class="header">Header #1</div>
<div class="content">Lorem Ipsum<br />Dolor<br />Sit Amet</div>
<div class="footer">Footer</div>
</div>
<div class="col">
<div class="header">Header #2</div>
<div class="content">Lorem Ipsum<br />Dolor</div>
</div>
</div>
Unfortunatly the second header isn't align vertically to the top. Is there a way to archive this with flexbox? I need the ".header" to be aligned the the top and the ".content" to be centered within the rest of the box.
Greetings!

No, not really, not without another wrapper which is a flex-container.
As flexbox is, to a certain extent based on manipulting margins, there is no method (AFAIK, although I'd be interested to find out if there is) to justify-content: center and then align-self a child element to somewhere else other than center.
I'd go with something like this: Add a wrapper to the "content" div, give it flex:1 to fill the remaining space below the header, then make that wrapper display:flex with justify-content:center.
This seems to be the most logical method
.col {
height: 150px;
width: 80%;
margin: 1em auto;
border: 1px solid grey;
display: flex;
flex-direction: column;
}
.header {
background: lightblue;
}
.content {
background: orange;
}
.flexy {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
background: plum;
}
<div class="col">
<div class="header">Header #2</div>
<div class="flexy">
<div class="content">Lorem Ipsum
<br />Dolor</div>
</div>
</div>
Codepen Demo

Flexbox opens up all sorts of opportunities with margin: auto; this is one of them. Setting margin to auto along the flex axis (vertical in this case) will absorb any extra space before dividing it up between the flex items. Finally it's possible to vertically center stuff without creating a div soup.
.row {
display: flex;
align-items: stretch;
margin: -16px;
background: #ddd;
}
.row .col {
display: flex;
flex-direction: column;
flex: 1;
margin: 16px;
background: #fff;
}
.header, .content, .footer {
padding: 16px;
background: red;
}
.content {
margin-top: auto;
margin-bottom: auto;
}
<div class="row">
<div class="col">
<div class="header">Header #1</div>
<div class="content">Lorem Ipsum<br />Dolor<br />Sit Amet</div>
<div class="footer">Footer</div>
</div>
<div class="col">
<div class="header">Header #2</div>
<div class="content">Lorem Ipsum<br />Dolor</div>
</div>
</div>

Related

Jutifying content in flex after wrap

I'm having a situation where I'm having a page title on the left side and rating number and stars on the right side. I'm trying to align all items centered once flexbox wraps. Once "Longer Page Title" reaches rating and stars and flexbox wraps, they should all be center aligned.
.flex-container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.title,
.ratings-and-stars {
border: 3px solid red;
}
.ratings-and-stars {
text-align: right;
}
<div class="flex-container">
<div class="title">Longer Page Title</div>
<div class="ratings-and-stars">
<div class="ratings">10</div>
<div class="stars">**********</div>
</div>
</div>
EDIT: I need to horizontally center content on mobile once flexbox wraps
The closest to your description i can think about is to play with margin & text-align and flex-grow for the title.
Below is an average demo.
However , you will need a mediaquerie set at a fixed breakpoint to decide when to wrap. See second snippet for a possible option
.flex-container {
display: flex;
flex-wrap: wrap;
}
.title {
flex: 1;
}
.title,
.ratings-and-stars {
border: 3px solid red;
margin: auto;
text-align:center;
text-align-last:left;
}
.ratings-and-stars {
text-align: right;
}
<div class="flex-container">
<div class="title">Longer Page Title ////////////////////long_string_for_demo\\\\\\\\\\\\\\\\\\\\\\\\ .</div>
<div class="ratings-and-stars">
<div class="ratings">10</div>
<div class="stars">**********</div>
</div>
</div>
Compromise with a mediaquerie (here set at 600px, use your own breakpoint)
.flex-container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
text-align: center;
}
.title,
.ratings-and-stars {
border: 3px solid red;
}
.ratings-and-stars {
text-align: right;
}
#media (max-width:600px) {
.title {
min-width: 100%;
}
.flex-container {
justify-content: center;
}
}
<div class="flex-container">
<div class="title">Longer Page Title</div>
<div class="ratings-and-stars">
<div class="ratings">10</div>
<div class="stars">**********</div>
</div>
</div>
white-space is also a possibility for an average result:
.flex-container {
display: flex;
flex-wrap: wrap;
justify-content:center;
}
.title {
white-space:prewrap;
margin:auto auto auto 0;
}
.title,
.ratings-and-stars {
border: 3px solid red;
text-align:center;
}
.ratings-and-stars {
text-align: right;
}
<div class="flex-container">
<div class="title">Longer Page Title //////////////////// long_string_for_demo \\\\\\\\\\\\\\\\\\\\\\\\ .</div>
<div class="ratings-and-stars">
<div class="ratings">10</div>
<div class="stars">**********</div>
</div>
</div>
You are missing align-items: center more info
.flex-container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center
}
.title,
.ratings-and-stars {
border: 3px solid red;
}
.ratings-and-stars {
text-align: right;
}
<div class="flex-container">
<div class="title">Longer Page Title</div>
<div class="ratings-and-stars">
<div class="ratings">10</div>
<div class="stars">**********</div>
</div>
</div>

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>

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 Flexbox, Push right, Align Left and different widths

left side Easy, is done.
but what about right section RESPONSIVE PUSHED right but align left, small box included.. see the image:
Any flexbox easy idea?
Try this:
.container {
display: flex;
justify-content: space-between;
}
.container > div {
display: flex;
flex-direction: column;
}
.right {
align-items: flex-start;
}
.left {
align-items: flex-end;
}
.box {
height: 40px;
width: 100px;
border: 1px solid blue;
margin-bottom: 5px;
}
.wide {
width: 200px;
}
<div class="container">
<div class="left">
<div class="box wide"></div>
<div class="box"></div>
</div>
<div class="right">
<div class="box wide"></div>
<div class="box"></div>
</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