I have two divs. One needs to sit at the left, one at the right. A parent flexbox with justify-content: space-between works perfectly for this, except when the flex items wrap (which they should be able to do). After they wrap, they are left-aligned because there's only two items total.
How can I make rows with single items centre-aligned?
<div style="display: flex; justify-content: space-between; flex-wrap: wrap">
<div style="background: orange">
<strong>Canvas Prints</strong><br>
<span style="font-size: 14px; color: #ff0000">Create a masterpiece for any wall in your home!</span>
</div>
<div style="background: pink">
<img width="176" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTEAPU9xK-mE81DSwYqh_uMb_EUuqXT1yWzIvs9j7diGY-FHh6X">
</div>
</div>
(Or you can use the fiddle, because it's easier to squish the output pane of the fiddle than resize the whole SO window to see the divs wrap: https://jsfiddle.net/xv6oa418/1/)
Additional note: #KaranTewari suggested adding flex: 1 to the first child div, but I'd like text in the left div to not wrap until absolutely necessary (specifically, it should start wrapping only after the second flex item has wrapped onto the next line). The second div is actually going to be an image so I've updated my fiddle and snippet to reflect this.
I figured it out myself. I used flex-grow: 1 on the first/left div, and margin: auto on the second/right div. This makes the first div expand to take up all space so the auto margin of the second div doesn't get to do anything. Then when it wraps, the second div is no longer blocked by the first one and the auto margin takes over, centring the second div.
Like so:
<div style="display: flex; justify-content: space-between; flex-wrap: wrap">
<div style="background: orange; flex-grow: 1;">
<strong>Canvas Prints</strong><br>
<span style="font-size: 14px; color: #ff0000">Create a masterpiece for any wall in your home!</span>
</div>
<div style="background: pink; margin: auto">
<img width="176" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTEAPU9xK-mE81DSwYqh_uMb_EUuqXT1yWzIvs9j7diGY-FHh6X">
</div>
</div>
(And the fiddle: https://jsfiddle.net/xv6oa418/2/)
.parent {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.text {
background: orange;
padding:10px;
border-radius:10px;
}
.text:only-child {
background-color: green;
margin:0 auto;
}
<div class="parent">
<div class="text">
<strong>Canvas Prints</strong><br>
<span >Create a masterpiece for any wall in your home!</span>
</div>
<div class="img" >
<img width="176" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTEAPU9xK-mE81DSwYqh_uMb_EUuqXT1yWzIvs9j7diGY-FHh6X">
</div>
</div>
You can use :only-child selector and give margin:auto to the only-child element. Please see the snippet.
Try using
flex:1
This ensures you are using full available space, here jsfiddle edited
https://jsfiddle.net/karantewari/tfg0kymb/1/
Related
This question already has answers here:
Better way to set distance between flexbox items
(40 answers)
Closed 9 months ago.
I'm trying to manipulate divs without using float, using display: inline-block; in my css allows me to get the siblings next to each other within a container div, but with inline-block, I can't space them apart using margin-left: 20px;, margin-right :20px; ... and so on.
I'm sure there's a really simple solution, even if it doesn't involve using display: inline-block;, I just want to avoid floats and preferably avoid padding too.
you can try flex-box method to create space between two div which is inside a div (I conclude that from your question )
.parent{
border:2px solid red;
display:flex;
justify-content:space-around;
}
.parent div{
border:3px solid black;
}
<div class="parent">
<div class="child1">
child1
</div>
<div class="child2">
child2
</div>
</div>
you can also add many child div as you want , they will automatically make place in the parent container.
Here you can see below how i managed to do so without display:inline-block; and this will not break on any device unlike inline-block.
.box {
width: 200px;
height: 200px;
background: #F3F3F3;
color: #000;
display: flex;
align-items: center;
justify-content: center;
margin-left: 20px;
}
.container {
display: flex;
margin-bottom: 40px;
}
.container.two {
justify-content: space-between;
}
.container.three {
justify-content: space-evenly;
}
Margin 20px in between
<div class="container">
<div class="box">
BOX 1
</div>
<div class="box">
BOX 1
</div>
</div>
Align boxes on left and right according to width
<div class="container two">
<div class="box">
BOX 1
</div>
<div class="box">
BOX 1
</div>
</div>
Align even spacing on left and right
<div class="container three">
<div class="box">
BOX 1
</div>
<div class="box">
BOX 1
</div>
</div>
I'm working with formatting some divs with a flex box and thought that justify-content: space-between is the best way to do it. But, I'm running into an issue when the browser resolution changes the items become misaligned. For example if I shrink the browser size the items will wrap onto the next line which is fine since I have flex-wrap: wrap, but on the new line that is created the contents are spread between. Is it possible to remove the justify-content every time the items wrap? Sorry for the poor explanation, I'll provide a jsfiddle. Change the fiddle to 483px and the items will wrap and be placed on the next line, but instead of space between I want the items to be placed next to each other.
http://jsfiddle.net/xut5cqhw/46/
.container {
position: relative;
height: 150px;
width: 40%;
display: flex;
justify-content:space-between;
flex-wrap: wrap;
background-color: black;
}
.content {
height: 50px;
width: 50px;
margin-top: 10px;
background-color: yellow;
}
<div class = "container">
<div class="content">
</div>
<div class="content">
</div>
<div class="content">
</div>
<div class="content">
</div>
<div class="content">
</div>
</div>
I have this code and I want two items in the same row with a gap space between them, however this is not working. I want there to be the 12px gap in between the A's and B's. However I don't want to use old techniques like margin/padding.
https://codepen.io/sneaky666/pen/rNxdaOQ
<div class="container">
<div>
AAA
</div>
<div>
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
</div>
</div>
css
.container {
display:inline-flex;
flex-wrap:wrap;
gap:12px;
}
I'm following the tutorial from https://coryrylan.com/blog/css-gap-space-with-flexbox
Does anyone know?
Thanks
If you want to set a specific number of pixels for the gap, you would need to add a margin in between the items since gap is not currently supported. Example:
<div class="container">
<div class="first-item">
AAA
</div>
<div>
BBBBBBBBBBB
</div>
</div>
.container {
display: flex;
flex-direction: row;
}
.first-item {
margin-right: 12px;
}
However, if the size of the gap does not matter, you can use the flexbox alignment properties to spread out your divs in the row evenly. Example:
<div class="container">
<div class="first-item">
AAA
</div>
<div>
BBBBBBBBBBB
</div>
</div>
.container {
display: flex;
flex-direction: row;
justify-content: space-between;
}
#flex-container {
height: 200px;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
align-content: flex-end;
border: 2px solid;
}
#first-box {
background-color: gray;
width: 200px;
margin: 5px;
}
#second-box {
background-color: aqua;
width: 200px;
margin: 5px;
}
<div id="flex-container">
<div id="first-box">Box 1 </div>
<div id="second-box">Box 2</div>
</div>
Rule is: There must be multiple lines of items for this property to have any effect!
Why then have effect on displaying when there are not multiple lines of items?
Those two boxes should be centered on browser but there are on the bottom.
Rule is: There must be multiple lines of items for this property to have any effect!
The rule isn't exactly like that. There must be a multi-line flex container and this is not defined by the number of lines but by the flex-wrap property.
Read the below until the end to get the full explanation
From the specification:
The align-content property aligns a flex container’s lines within the flex container when there is extra space in the cross-axis .. Note, this property has no effect on a single-line flex container1.
and
Initial: stretch
So by default your one line is stretched to fill all the available space and the content is centred inside. If you select flex-end, your line will fit its content and will be placed at the bottom. The content is still centred inside but since the height is now defined by the content, the vertical centring is useless.
The trick here is to understand that centring in flexbox happen inside a line and not the container but in most of the case that line is stretched to fit the container height2. By changing align-content and flex-wrap it's no more the case.
flex-end
Lines are packed toward the end of the flex container. The cross-end edge of the last line is placed flush with the cross-end edge of the flex container, and each preceding line is placed flush with the subsequent line.
stretch
Lines stretch to take up the remaining space. If the leftover free-space is negative, this value is identical to flex-start. Otherwise, the free-space is split equally between all of the lines, increasing their cross size.
Some examples to better illustrate. The pink and yellow coloration represent the flexbox lines.
.box {
display: inline-flex;
vertical-align: top;
width: 100px;
height: 100px;
border: 1px solid;
align-items: center;
flex-wrap: wrap;
}
span {
width: 100%;
height: 10px;
margin: 5px;
background: red;
}
<div class="box" style="background:yellow;">
<span></span>
</div>
<div class="box" style="background:linear-gradient(yellow 50%,pink 50%);">
<span></span>
<span></span>
</div>
<div class="box" style="align-content:flex-end">
<span style="box-shadow:0 0 0 5px yellow"></span>
</div>
<div class="box" style="align-content:flex-end">
<span style="box-shadow:0 0 0 5px yellow"></span>
<span style="box-shadow:0 0 0 5px pink"></span>
</div>
1Now the tricky part is the use of flex-wrap
A single-line flex container (i.e. one with flex-wrap: nowrap) lays out all of its children in a single line, even if that would cause its contents to overflow.
A multi-line flex container (i.e. one with flex-wrap: wrap or flex-wrap: wrap-reverse) breaks its flex items across multiple lines, ...
If you specify wrap as flex-wrap, it's no more considered as single-line even if there is only one line thus align-content apply like described above.
If you keep it nowrap then nothing will happen because it's a single-line flexbox container and by default that line is always stretched to fill the space:
.box {
display: inline-flex;
vertical-align: top;
width: 100px;
height: 100px;
border: 1px solid;
align-items: center;
}
span {
width: 100%;
height: 10px;
margin: 5px;
background: red;
}
<div class="box" >
<span></span>
</div>
<div class="box" >
<span></span>
<span></span>
</div>
<div class="box" style="align-content:flex-end">
<span ></span>
</div>
<div class="box" style="align-content:flex-end">
<span ></span>
<span ></span>
</div>
2Note: Only multi-line flex containers ever have free space in the cross-axis for lines to be aligned in, because in a single-line flex container the sole line automatically stretches to fill the space.
If you go to the "try it" page for "CSS align-content Property" at w3schools.com you can insert your CSS and see exactly what it does. As far as I can see it is acting as expected and as Temani explains. You can also tweak the code until it does what you actually want.
have a css float problem that i'm not sure how to fix or best way to fix and can't seem to find anything in searches. I have a variable amount of items to show inside a div, using a css float left on all the inner boxes (1, 2, and 3 in pic) but the float breaks with variable lines of text. the developer outlines show that because box 1 is larger that box 2, box 3 doesn't float flush left like box 1 which screws up the flow. how do i keep the vertical height of box 1 and box 2 but make box 3 float left where it should be? Doing a float: right; does the same thing but just pushes 3 to the left is div 2 is larger than div 1
This is just an example, there could be a variable number of rows and columns so just doing an Nth div css rule won't work. (the containing div is a variable width based on a few conditions including responsive design)
Almost like i have to have a variable buffer at the bottom of each item in a row to match the height of the tallest one. I also don't want to use a min-height as on rows where the divs are the same height will result in extra white space where there shouldn't be. How would i get the tallest element in a row if the number of columns are variable?
A possible solution is to use the empty clearing div trick but again how do I get the number of divs in a row when columns are variable? I tried to force a nth child::after thing in the example but it didn't work
.item:nth-child(2)::after {
clear: both;
}
Search didn't show anything that works so if anyone has a post that does please let me know.
also have to stick with CSS2 if at all possible due to a bunch of users using older browsers that don't use CSS3
One solution is to use display:inline-block for the figures rather than float:left.
.figure {
display: inline-block;
vertical-align: top;
margin: 2px 1em;
border:1px solid grey;
}
.figcaption {
margin:1em;
}
<div class="section">
<div class="figure">
<img src="http://placehold.it/250x250" alt="#">
<div class="figcaption">
Line 1<br/>Line 2
</div>
</div>
<div class="figure">
<img src="http://placehold.it/250x250" alt="#">
<div class="figcaption">
Line 1
</div>
</div>
<div class="figure">
<img src="http://placehold.it/250x250" alt="#">
<div class="figcaption">
Line 1<br/>Line 2
</div>
</div>
</div>
You need to clear:both the 3rd element actually in this case.
See solution below.
img {
width:50%;
float:left;
}
img:nth-child(3) {
clear: both;
}
<img src="http://via.placeholder.com/350x160">
<img src="http://via.placeholder.com/350x150">
<img src="http://via.placeholder.com/350x150">
If you got some complex example please provide jsfiddle.
that's because your <div>s are styled with "float" and 3rd div has floated to 1st, because 1st is taller than others.
Possible solutions (not including the hardcoding - it's like a deadly sin):
Give equal height to each item in a set
.float {
background-color: #f90;
float: left;
height: 100px;
line-height: 100px;
margin: 10px;
text-align: center;
width: calc(50% - 20px);
}
<div class="float">float 1</div>
<div class="float">float 2</div>
<div class="float">float 3</div>
Use different approach, such as flexbox
.wrapper {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
.flex {
background-color: #f90;
height: 100px;
line-height: 100px;
margin: 10px;
text-align: center;
width: calc(50% - 20px);
}
<div class="wrapper">
<div class="flex" style="height: 120px;">flex 1</div>
<div class="flex">flex 2</div>
<div class="flex">flex 3</div>
</div>