can you please tell me align-items : what is the difference between flex-start and Stretch?
.container {
height: 500px;
padding: 10px;
margin: 50px auto;
background: #eee;
display: flex;
align-items: flex-end
}
.container .box {
padding: 10px;
width: 200px;
height: 200px;
background-color: #fff;
}
<div class="container">
<div class="box"></div>
</div>
You will see no difference if you set a height to your element.
stretch
Flex items are stretched such that the cross-size of the item's margin box is the same as the line while respecting width and height constraints.ref
In your case, nothing will happen with stretch because of the height you set.
flex-start
The cross-start margin edges of the flex items are flushed with the cross-start edge of the line. ref
This is simply align the item on the top. Again, nothing will happen visually since it's somehow the default behavior (not the default value).
.container {
display:inline-flex;
width:200px;
height:200px;
border:2px solid;
}
.container > span {
width:100px;
height:100px;
background:red;
}
<div class="container" style="align-items:flex-start">
<span></span>
</div>
<div class="container" style="align-items:stretch">
<span></span>
</div>
Now remove the height constraint and you will see the difference:
.container {
display:inline-flex;
width:200px;
height:200px;
border:2px solid;
vertical-align:top;
}
.container > span {
width:100px;
min-height:100px;
background:red;
}
<div class="container" style="align-items:flex-start">
<span></span>
</div>
<div class="container" style="align-items:stretch">
<span></span>
</div>
Related
My goal is to use flexbox to implement a slider that has a given width and can grow as items(images) are added into it, until a specific width is reached. After that width is reached i want to show a scrollbar on the x axis. I also want the slider not to shrink bellow the min-width.
This is what i tried:
HTML:
<div class="wrapper">
<div class="thisDivAllowsSliderToGrowToMaxWidth">
<div class="slider">
<div class="image"></div>
...
</div>
</div>
</div>
CSS:
.wrapper {
height: 400px;
display: flex;
justify-content: center;
align-items:center
}
.slider {
display:flex;
justify-content:flex-start;
height:100px;
flex-basis: 250px;
min-width:200px;
max-width:350px;
overflow-x:auto;
}
.image {
flex-shrink:0;
height:100px;
width:50px;
}
The issue that pops out is that as soon as overflow-x is added to the slider, it does not grow anymore but shows the scrollbar as soon as flex-basis width is reached.
Interestingly, adding a simple wrapping div (.thisDivAllowsSliderToGrowToMaxWidth) around the slider somehow fixes the issue. You can find the example here.
Can anyone answer why is this happening and am I using the flex properties as intended?
To make the flex container grow based on the width of the flex items, you can set the flex-basis to content
content will automatically size based on the flex item's content
$(".add-slide").on("click",function(){
$(".slider").append('<div class="image"></div>');
});
.wrapper {
height: 300px;
border :1px solid red;
display: flex;
justify-content: center;
align-items:center
}
.slider {
display:flex;
border: 1px solid black;
height:100px;
flex-basis: content;
min-width:200px;
max-width:350px;
overflow-x:auto;
overflow-y:hidden;
}
.image {
flex-shrink: 0;
border: 1px solid green;
height:100px;
width:50px;
}
button {
margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="add-slide">add slide</button>
<div class="wrapper">
<div class="slider">
<div class="image"></div>
</div>
</div>
I am trying to keep my 3d element with full width of the flex container. but not getting the reuslt. any one suggest me the right way for ie11 here?
.parent{
border:1px solid red;
display:flex;
justify-content:space-between;
padding:0 40px;
}
.child{
flex:0 0 30%;
border:1px dashed green;
}
.child.last{
/* not working */
width:100%;
}
<div class="parent">
<div class="child">one</div>
<div class="child">two</div>
<div class="child last">three</div>
</div>
To enable for the last child to wrap and be 100% wide, add flex-wrap: wrap to parent and use flex-basis on last child.
.parent{
border:1px solid red;
display:flex;
flex-wrap: wrap;
justify-content:space-between;
padding:0 40px;
}
.child{
flex:0 0 30%;
border:1px dashed green;
}
.child.last{
flex-basis: 100%;
}
<div class="parent">
<div class="child">one</div>
<div class="child">two</div>
<div class="child last">three</div>
</div>
To make the last child 100%-width only after wrapping...
Use flex: 1:
The flex property specifies the length of the item, relative to the rest of the flexible items inside the same container. It makes the flex item flexible and sets the flex basis to zero, resulting in an item that receives the specified proportion of the remaining space.
.parent{
border:1px solid red;
display:flex;
justify-content:space-between;
padding:0 40px;
}
.child{
flex:0 0 30%;
border:1px dashed green;
}
.child.last{
width:100%;
/* SOLUTION */
flex: 1;
}
<div class="parent">
<div class="child">one</div>
<div class="child">two</div>
<div class="child last">three</div>
</div>
I'm using flexbox to align my child elements. What I'd like to do is center one element and leave the other aligned to the very left. Normally I would just set the left element using margin-right: auto. The problem is that pushes the center element off center. Is this possible without using absolute positioning?
HTML & CSS
#parent {
align-items: center;
border: 1px solid black;
display: flex;
justify-content: center;
margin: 0 auto;
width: 500px;
}
#left {
margin-right: auto;
}
#center {
margin: auto;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
</div>
Add third empty element:
<div class="parent">
<div class="left">Left</div>
<div class="center">Center</div>
<div class="right"></div>
</div>
And the following style:
.parent {
display: flex;
}
.left, .right {
flex: 1;
}
Only left and right are set to grow and thanks to the facts that...
there are only two growing elements (doesn't matter if empty) and
that both get same widths (they'll evenly distribute the available space)
...center element will always be perfectly centered.
This is much better than accepted answer in my opinion because you do not have to copy left content to right and hide it to get same width for both sides, it just magically happens (flexbox is magical).
In action:
.parent {
display: flex;
}
.left,
.right {
flex: 1;
}
/* Styles for demonstration */
.parent {
padding: 5px;
border: 2px solid #000;
}
.left,
.right {
padding: 3px;
border: 2px solid red;
}
.center {
margin: 0 3px;
padding: 3px;
border: 2px solid blue;
}
<div class="parent">
<div class="left">Left</div>
<div class="center">Center</div>
<div class="right"></div>
</div>
EDIT: See Solo's answer below, it is the better solution.
The idea behind flexbox is to provide a framework for easily aligning elements with variable dimensions within a container. As such, it makes little sense to provide a layout where the width of one element is totally ignored. In essence, that is exactly what absolute positioning is for, as it takes the element out of the normal flow.
As far as I know, there is no nice way of doing this without using position: absolute;, so I would suggest using it... but If you REALLY don't want to, or can't use absolute positioning then I suppose you could use one of the following workarounds.
If you know the exact width of the "Left" div, then you could change justify-content to flex-start (left) and then align the "Center" div like this:
#center {
position: relative;
margin: auto;
left: -{half width of left div}px;
}
If you do not know the width, then you could duplicate "Left" on the right side, use justify-content: space-between;, and hide the new right element:
Just to be clear, this is really, really ugly... better to use absolute positioning than to duplicate content. :-)
#parent {
align-items: center;
border: 1px solid black;
display: flex;
justify-content: space-between;
margin: 0 auto;
width: 500px;
}
#right {
opacity: 0;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
<span id="right">Left</span>
</div>
.parent {
display: flex;
}
.left {
flex: 1;
}
.parent::after {
flex: 1;
content: '';
}
<div class="parent">
<div class="left">Left</div>
<div>Center</div>
</div>
I have another solution. In my opinion, Adding an empty block to the center element is fine but code-wise it bit ugly.
Since this is 4 years old I figured I'd update this with a much easier CSS Grid solution.
#parent {
display: grid;
grid-template-columns: repeat(3, 1fr);
border: 1px solid black;
margin: 0 auto;
width: 500px;
}
#center {
text-align: center;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
</div>
If you don't want to rely on positioning, the only way I've found that makes it truly centered is to use a combination of auto margin and negative margin prevent the centered element to getting pushed over by the left aligned element. This requires that you know the exact width of the left aligned element though.
.container {
height: 100px;
border: solid 10px skyblue;
display: flex;
justify-content: center;
}
.block {
width: 120px;
background: tomato;
}
.justify-start {
margin-right: auto;
}
.justify-center {
margin-right: auto;
margin-left: -120px;
}
<div class="container">
<div class="block justify-start"></div>
<div class="block justify-center"></div>
</div>
As far as I know this is possible with the following code.
https://jsfiddle.net/u5gonp0a/
.box {
display: flex;
justify-content: center;
background-color: green;
text-align: left;
}
.left {
padding: 10px;
background-color: pink;
}
.center {
padding: 10px;
background-color: yellow;
margin: 0 auto;
}
<div class="box">
<div class="left">left</div>
<div class="center">center</div>
</div>
Try this no hacks :)
CSS
.container{
width: 500px;
margin: 0 auto;
}
.box{
display: flex;
align-items: center;/* just in case*/
justify-content: space-between;
}
.box p:nth-child(2){
text-align: center;
background-color: lime;
flex: 1 1 0px;
}
HTML
<div class="container">
<div class="box">
<p>One</p>
<p>Two</p>
</div>
</div>
http://codepen.io/whisher/pen/XpGaEZ
If you have a grid system you can use it to do what you want without "extra" css.
Below with bootstrap (V 4.X)
Note: It uses flex under the hood
<div class="row">
<div class="col text-left">left</col>
<div class="col text-center">center</col>
<div class="col text-right">right</col>
</div>
Doc bootstrap: https://getbootstrap.com/docs/4.6/layout/grid/
Et voilĂ ! :)
Solution 1: give 50% width to center element and use justify-content:space-between
#parent {
display: flex;
justify-content: space-between;
}
#center {
flex-basis: 50%;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
</div>
Solution 2: Add one dummy element and hide it.
#parent {
display: flex;
justify-content: space-between;
}
#right {
visibility:hidden;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
<span id="right">Right</span>
</div>
I'm using flexbox to align my child elements. What I'd like to do is center one element and leave the other aligned to the very left. Normally I would just set the left element using margin-right: auto. The problem is that pushes the center element off center. Is this possible without using absolute positioning?
HTML & CSS
#parent {
align-items: center;
border: 1px solid black;
display: flex;
justify-content: center;
margin: 0 auto;
width: 500px;
}
#left {
margin-right: auto;
}
#center {
margin: auto;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
</div>
Add third empty element:
<div class="parent">
<div class="left">Left</div>
<div class="center">Center</div>
<div class="right"></div>
</div>
And the following style:
.parent {
display: flex;
}
.left, .right {
flex: 1;
}
Only left and right are set to grow and thanks to the facts that...
there are only two growing elements (doesn't matter if empty) and
that both get same widths (they'll evenly distribute the available space)
...center element will always be perfectly centered.
This is much better than accepted answer in my opinion because you do not have to copy left content to right and hide it to get same width for both sides, it just magically happens (flexbox is magical).
In action:
.parent {
display: flex;
}
.left,
.right {
flex: 1;
}
/* Styles for demonstration */
.parent {
padding: 5px;
border: 2px solid #000;
}
.left,
.right {
padding: 3px;
border: 2px solid red;
}
.center {
margin: 0 3px;
padding: 3px;
border: 2px solid blue;
}
<div class="parent">
<div class="left">Left</div>
<div class="center">Center</div>
<div class="right"></div>
</div>
EDIT: See Solo's answer below, it is the better solution.
The idea behind flexbox is to provide a framework for easily aligning elements with variable dimensions within a container. As such, it makes little sense to provide a layout where the width of one element is totally ignored. In essence, that is exactly what absolute positioning is for, as it takes the element out of the normal flow.
As far as I know, there is no nice way of doing this without using position: absolute;, so I would suggest using it... but If you REALLY don't want to, or can't use absolute positioning then I suppose you could use one of the following workarounds.
If you know the exact width of the "Left" div, then you could change justify-content to flex-start (left) and then align the "Center" div like this:
#center {
position: relative;
margin: auto;
left: -{half width of left div}px;
}
If you do not know the width, then you could duplicate "Left" on the right side, use justify-content: space-between;, and hide the new right element:
Just to be clear, this is really, really ugly... better to use absolute positioning than to duplicate content. :-)
#parent {
align-items: center;
border: 1px solid black;
display: flex;
justify-content: space-between;
margin: 0 auto;
width: 500px;
}
#right {
opacity: 0;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
<span id="right">Left</span>
</div>
.parent {
display: flex;
}
.left {
flex: 1;
}
.parent::after {
flex: 1;
content: '';
}
<div class="parent">
<div class="left">Left</div>
<div>Center</div>
</div>
I have another solution. In my opinion, Adding an empty block to the center element is fine but code-wise it bit ugly.
Since this is 4 years old I figured I'd update this with a much easier CSS Grid solution.
#parent {
display: grid;
grid-template-columns: repeat(3, 1fr);
border: 1px solid black;
margin: 0 auto;
width: 500px;
}
#center {
text-align: center;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
</div>
If you don't want to rely on positioning, the only way I've found that makes it truly centered is to use a combination of auto margin and negative margin prevent the centered element to getting pushed over by the left aligned element. This requires that you know the exact width of the left aligned element though.
.container {
height: 100px;
border: solid 10px skyblue;
display: flex;
justify-content: center;
}
.block {
width: 120px;
background: tomato;
}
.justify-start {
margin-right: auto;
}
.justify-center {
margin-right: auto;
margin-left: -120px;
}
<div class="container">
<div class="block justify-start"></div>
<div class="block justify-center"></div>
</div>
As far as I know this is possible with the following code.
https://jsfiddle.net/u5gonp0a/
.box {
display: flex;
justify-content: center;
background-color: green;
text-align: left;
}
.left {
padding: 10px;
background-color: pink;
}
.center {
padding: 10px;
background-color: yellow;
margin: 0 auto;
}
<div class="box">
<div class="left">left</div>
<div class="center">center</div>
</div>
Try this no hacks :)
CSS
.container{
width: 500px;
margin: 0 auto;
}
.box{
display: flex;
align-items: center;/* just in case*/
justify-content: space-between;
}
.box p:nth-child(2){
text-align: center;
background-color: lime;
flex: 1 1 0px;
}
HTML
<div class="container">
<div class="box">
<p>One</p>
<p>Two</p>
</div>
</div>
http://codepen.io/whisher/pen/XpGaEZ
If you have a grid system you can use it to do what you want without "extra" css.
Below with bootstrap (V 4.X)
Note: It uses flex under the hood
<div class="row">
<div class="col text-left">left</col>
<div class="col text-center">center</col>
<div class="col text-right">right</col>
</div>
Doc bootstrap: https://getbootstrap.com/docs/4.6/layout/grid/
Et voilĂ ! :)
Solution 1: give 50% width to center element and use justify-content:space-between
#parent {
display: flex;
justify-content: space-between;
}
#center {
flex-basis: 50%;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
</div>
Solution 2: Add one dummy element and hide it.
#parent {
display: flex;
justify-content: space-between;
}
#right {
visibility:hidden;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
<span id="right">Right</span>
</div>
What I'm trying to achieve is to have items one below another in same starting line but to be centered in div. This is my fiddle: https://jsfiddle.net/7vdbLcL9/
<div class="container">
<div id="wrapper">
<div id="inner1">Zmaja od Bosne 5</div>
<div id="inner2">71 000 Sarajevo</div>
<div id="inner3">Bosnia and Herzegovina</div>
</div>
</div>
And the CSS:
.container{
width:40%;
border:1px solid black;
}
#wrapper{
margin-left:auto;
margin-right:auto;
height:auto;
width:auto;
text-align:center
}
I want to get this :
----------------------------------
Zmaja od Bosne 5
71 000 Sarajevo
Bosnia and Herzegovina
----------------------------------
You mean like this? https://jsfiddle.net/7vdbLcL9/1/
Your .container gets text-align:center,
and the #wrapper gets display:inline-block (so that it will be only as wide as needed, and can be centered via text-align of the parent) and text-align:left to counter the effect of center on the parent element.
Just use a flexbox:
.container {
display: flex;
flex-direction: column;
align-items: center;
width:40%;
border:1px solid black;
}
#wrapper { }
DEMO
Flexbox benefits:
minimal code; very efficient
centering, both vertically and horizontally, is simple and easy
equal height columns are simple and easy
multiple options for aligning flex items
it's responsive
it's the future of CSS layouts
Note that flexbox is supported by all major browsers, except IE 8 & 9. Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes. For a quick way to add all the prefixes you need, post your CSS in the left panel here: Autoprefixer.
.container{
width:40%;
border:1px solid black;
display:flex;
}
#wrapper{
margin-left:auto;
margin-right:auto;
height:auto;
width:auto;
text-align:center
display:flex;
}
Are you looking for something like this?
#wrapper {
display: block;
text-align: center;
line-height: 0;
font-size: 0;
margin-bottom: 20px;
}
#wrapper div {
display: inline-block;
width: auto;
}
#wrapper2 {
display: table;
}
#wrapper2 div {
display: table-cell;
width: 1%;
}
div div {
width: 200px; line-height: 100px; background: lightseagreen; font-size: 12px;
border: 1px solid yellow;
text-align: center;
padding: 0 1em;
}
<div id="wrapper">
<div id="inner1">Zmaja od Bosne 5</div>
<div id="inner2">71 000 Sarajevo</div>
<div id="inner3">Bosnia and Herzegovina</div>
</div>
<div id="wrapper2">
<div id="inner1">Zmaja od Bosne 5</div>
<div id="inner2">71 000 Sarajevo</div>
<div id="inner3">Bosnia and Herzegovina</div>
</div>