Prevent flex items from rendering side to side
I'm using flexbox to center some items in a block, but I want each item inside to be in its own row. For example, I want the orange square to be above the text, but after using flex it's moved it to the side of the text - does anyone know a way around this please?
.container {
height: 200px;
width: 200px;
background: cornflowerblue;
position: relative;
}
.inner {
height: 100%;
position: absolute;
left: 0;
width: 100%;
top: 0;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
align-items: center;
justify-content: center;
}
.square {
width: 30px;
height: 30px;
background: tomato;
display: block;
}
<div class="container">
<div class="inner">
<div class="square"></div>
<p>some text</p>
</div>
</div>
Add this style:
.inner {
flex-direction: column;
}
That tells the flexbox to display its children in rows instead of columns. (I know, weird, right?)
Updated Snippet:
.container {
height: 200px;
width: 200px;
background: cornflowerblue;
position: relative;
}
.inner {
height: 100%;
position: absolute;
left: 0;
width: 100%;
top: 0;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.square {
width: 30px;
height: 30px;
background: tomato;
display: block;
}
<div class="container">
<div class="inner">
<div class="square"></div>
<p>some text</p>
</div>
</div>
An initial setting of a flex container is flex-direction: row
. This means that whenever you give an element display: flex
or display: inline-flex
, all children of that element will, by default, line up horizontally.*
You can override this default with flex-direction: column
:
.container {
height: 200px;
width: 200px;
background: cornflowerblue;
position: relative;
}
.inner {
height: 100%;
position: absolute;
left: 0;
width: 100%;
top: 0;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column; /* NEW */
}
.square {
width: 30px;
height: 30px;
background: tomato;
display: block;
}
<div class="container">
<div class="inner">
<div class="square"></div>
<p>some text</p>
</div>
</div>
OR, you can stay in flex-direction: row
by adding flex-wrap: wrap
to the container and giving the children a large enough width (e.g. width: 100%
) to force only one item per row.
.container {
height: 200px;
width: 200px;
background: cornflowerblue;
position: relative;
}
.inner {
height: 100%;
position: absolute;
left: 0;
width: 100%;
top: 0;
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap; /* NEW */
align-content: center; /* NEW */
}
.square {
width: 30px;
height: 30px;
background: tomato;
display: block;
}
/* NEW */
p {
flex: 0 0 100%;
text-align: center;
}
<div class="container">
<div class="inner">
<div class="square"></div>
<p>some text</p>
</div>
</div>
* Note the term "children". Descendants beyond the children do not participate in flex layout.