I'd like to left align two items, and right align one when there is sufficient space but center on wrap.
On first wrap (too thin for right item to fit)
Right item should go to next line and be centered
Remainder remains left aligned
On Second Wrap (too thin for right + mid item to fit)
All three items are vertically stacked and centered
Tried having two layers of flex using justify-content: first with space-between, second with center.
.container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
}
.subcontainer {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.item {
border: 1px solid black;
height: 100px;
}
<div class="container">
<div class="subcontainer">
<div class="item">abc abc abc abc abc abc</div>
<div class="item">def def def def def def</div>
</div>
<div class="item">right right right</div>
</div>
http://jsfiddle.net/b3z18rLn/9/
Unfortunately, the right item does not center upon wrapping, and remains left aligned.
JSFiddle
You can wrap your third item inside another Flexbox container and use media queries:
/* flex-wrap will put right-subcontainer on a new row when you
decrease the viewport's width.*/
.container {
display: flex;
flex-wrap: wrap;
}
/* flex-grow of 1 will enable this container to take up the
entire row when the left and right subcontainers are
row by row.
flex-wrap is used to allow the second item to go onto a
new row at smaller widths. */
.left-subcontainer {
display: flex;
flex-grow: 1;
flex-wrap: wrap;
}
/* Again, flex-wrap is used to give the right subcontainer
the ability to take up the entire row.
flex-end changes the items from positioning left-to-right
to right-to-left.*/
.right-subcontainer {
display: flex;
flex-grow: 1;
justify-content: flex-end;
}
.item {
border: 1px solid black;
width: 300px;
height: 300px;
}
/* You will need to adjust the arguments for these media queries.
Also, if you do decide to use media queries for this approach,
I would suggest reversing the CSS logic by having the CSS
selectors tackle mobile design first and use media queries
to tackle design at larger screen sizes. */
/* The first wrap/breakpoint is at this width. I am telling the
right container to be center-aligned at the first breakpoint. */
#media only screen and (max-width: 925px) {
.right-subcontainer {
justify-content: center;
}
}
/* Then, I tell the left container to be center-aligned at the second
breakpoint. */
#media only screen and (max-width: 1320px) {
.left-subcontainer {
justify-content: center;
}
}
<div class="container">
<div class="left-subcontainer">
<div class="item">abc abc abc abc abc abc</div>
<div class="item">def def def def def def</div>
</div>
<div class="right-subcontainer">
<div class="item">right right right</div>
</div>
</div>
Related
I have a flexbox 2 column layout with 2 divs containing text.
Text in the left box is left aligned, text in the right box is right aligned.
However, when I shrink the viewport and the boxes wrap, I want the text in the box that was previously right to also be left-aligned.
Here is an example: JSFiddle
HTML
<div class="leftContainer">
This is my left aligned Text
</div>
<div class="rightContainer">
This is text that should be right aligned when the box doesn't wrap and left aligned when it does.
</div>
</div>
CSS
.mainContainer{
display: flex;
flex-direction: row;
justify-content: space-between;
flex-wrap: wrap;
}
.leftContainer{
text-align: left;
}
.rightContainer{
text-align: right;
}
This case is perfect - both containers are left/right and the texts are aligned accodingly
When the container breaks the text of "rightContainer" should be left aligned.
I tried to use media queries for it but sometimes the media query condition is satisfied but the row still doesn't break because the texts are not long.
Does anyone have an idea how to solve this?
use flex basis on columns along with media query.
.row {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
.left-column, .right-column{
flex: 0 0 100%;
padding: 10px 0;
}
.left-column, .right-column{
text-align: left;
}
#media screen and (min-width: 600px){
.left-column, .right-column{
flex: 0 0 48%;
}
.right-column{
text-align:right;
}
}
As shown in the image attached, there is a very large gap between each of my elements and I was to reduce that vertical gap. This is my code so far, but I'm not sure what to add to the CSS to fix the issue. Thanks
</div>
<div className="flex-container">
<Email username={username}/>
<Message username={username}/>
<Whatsapp username={username}/>
</div>
.flex-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 700px;
display: block; /* Make the buttons appear below each other */
}
current flex layout
I'm having a bit of trouble to produce the below with flex box. I'd like a centrally aligned "title" with some buttons to the right (2,3,4).
The code below gets me close, but it's not perfectly aligned and loses it when the window resizes.
Any suggestions?
.header {
display: flex;
height: 50px;
align-items: center;
justify-content: center;
}
.title {
width: 250px;
margin-left: auto;
margin-right: 15%;
}
.btn-group {
margin-right: 15%;
}
<div class="header">
<h1 class="title"></h1>
<div class="btn-group">
<button id="btn_1" class="selected">2</button>
<button id="btn_2">3</button>
<button id="btn_3">4</button>
</div>
</div>
Here's a clean and simple process to get you to your layout:
First, note that CSS pseudo-elements (i.e., ::before and ::after), when applied to flex containers, are treated as flex items.
Create a pseudo-element to serve as the first flex item in the container.
Make the pseudo consume all available space (i.e., set it to flex: 1)
Do the same with your button group (.btn-group) on the opposite end (i.e., set it to flex: 1)
Now, with the outer items pressuring from both sides, the title is pinned to the middle of the container.
Make the button group container a flex container.
Set that container to justify-content: center.
Now, the individual buttons are horizontally centered on the right side of the already centered title.
.header {
display: flex;
height: 50px;
align-items: center;
}
.header::before {
content: "";
flex: 1;
}
.btn-group {
flex: 1;
display: flex;
justify-content: center;
}
<div class="header">
<h1 class="title">1</h1>
<div class="btn-group">
<button id="btn_1" class="selected">2</button>
<button id="btn_2">3</button>
<button id="btn_3">4</button>
</div>
</div>
To better understand the concepts and methodology at work here, see this post:
Center and right align flexbox elements
Here are my suggestions when using flexbox layout. You do not need to set the width on the element because the width will resize dynamically. When you set display as flex in the container, the x-axis would change to row by default then use flex property for 'title' class to expand the width to double the width of 'btn-group'. As the result, the second div will push all the way to the right and you can add the width of margin-right as how much you want it to be. Also, I would create another div after header and give it a class name as 'title' instead of giving it on h1. That way you would have two children that allow you to control it. See below how I fixed it:
h1 {
text-align: center;
}
.header {
border: 1px solid red;
display: flex;
align-items: center;
justify-content: center;
}
.title {
flex: 1;
}
<div class="header">
<div class="title">
<h1>This is a title</h1>
</div>
<div class="btn-group">
<button id="btn_1" class="selected">2</button>
<button id="btn_2">3</button>
<button id="btn_3">4</button>
</div>
</div>
After some search, i don't find how to do the reverse of this,
I'll give a height, and the second div is under the first and the third div is on the right.
https://jsfiddle.net/qq3n52vg/
.wrapper {
border: 1px solid black;
width: 30px;
}
.left {
border: 1px solid red;
display: inline;
}
<div class="wrapper">
<div class="left">1</div>
<div class="left">2</div>
<div class="left">3</div>
</div>
Thanks
You can use a flexbox that wraps in the column flex-direction - see demo below:
.wrapper {
border: 1px solid black;
height: 40px;
display: flex; /* Define a flexbox*/
flex-wrap: wrap; /* Allow wrapping*/
flex-direction: column; /*Column direction*/
align-items: flex-start; /* Override default stretching*/
align-content: flex-start; /* aligning wrapping lines */
}
.left {
border: 1px solid red;
display: inline;
}
<div class="wrapper">
<div class="left">1</div>
<div class="left">2</div>
<div class="left">3</div>
</div>
More to kukkuz answer. For further reading about Flexbox
flex-direction
This establishes the main-axis, thus defining the direction flex items are placed in the flex container. Flexbox is (aside from optional wrapping) a single-direction layout concept. Think of flex items as primarily laying out either in horizontal rows or vertical columns.
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
row (default): left to right in ltr; right to left in rtl
row-reverse: right to left in ltr; left to right in rtl
column: same as row but top to bottom
column-reverse: same as row-reverse but bottom to top
This question already has answers here:
Keep the middle item centered when side items have different widths
(12 answers)
Closed 5 years ago.
I know flexbox offers a great solution for centering items. But I run into an issue when I have 3 items and I'd like the center (2nd) item to be centered with respect to the window, regardless of the size of the other 2 items.
In my pen you can see the second item "Client Index" is off-center because the content on the right is larger than the content on the left. How can I force it to center itself?
.flex {
display: flex;
align-items: center;
justify-content: space-between;
}
<div class="flex">
<span style="font-size:12px;">small</span>
<span style="font-size:20px;">Client Index</span>
<span style="font-size:18px;">Lots of content that moves the center</span>
</div>
My Codepen
One way would be to set flex-grow: 1; flex-basis: 0 so the 3 columns are distributed evenly, then you can center the text or the content in the middle one.
I'm using text-align to center the middle column. You could also use display: flex; justify-content: center; to do the same thing.
.flex {
display: flex;
align-items: center;
justify-content: space-between;
}
.flex > span {
flex: 1 0 0;
}
.flex > span:nth-child(2) {
text-align: center;
}
<div class="flex">
<span style="font-size:12px;">small</span>
<span style="font-size:20px;">Client Index</span>
<span style="font-size:18px;">Lots of content that moves the center</span>
</div>
Use nested flex containers and auto margins.
.flex-container {
display: flex;
}
.flex-item {
flex: 1;
display: flex;
justify-content: center;
}
.flex-item:first-child>span {
margin-right: auto;
}
.flex-item:last-child>span {
margin-left: auto;
}
/* non-essential */
.flex-item {
align-items: center;
border: 1px solid #ccc;
background-color: lightgreen;
height: 40px;
}
<div class="flex-container">
<div class="flex-item"><span>short</span></div>
<div class="flex-item"><span>medium</span></div>
<div class="flex-item"><span>lonnnnnnnnnnnnnnnnnnnng</span></div>
</div>
Here's how it works:
The top-level div is a flex container.
Each child div is now a flex item.
Each item is given flex: 1 in order to distribute container space equally.
Now the items are consuming all space in the row and are equal width.
Make each item a (nested) flex container and add justify-content: center.
Now each span element is a centered flex item.
Use flex auto margins to shift the outer spans left and right.
You could also forgo justify-content and use auto margins exclusively.
But justify-content can work here because auto margins always have priority. From the spec:
8.1. Aligning with auto
margins
Prior to alignment via justify-content and align-self, any
positive free space is distributed to auto margins in that dimension.