Since flexbox alignment involves the distribution of free space in the container, margin-top: auto won't work in this case because there's no counterweight on the other side.
Therefore, one method for centering the box and bottom-aligning the text involves creating a duplicate of the text element and placing it on the opposite side of the box. This will create a counterweight.
With equal balance on both ends, flex alignment properties (including auto margins) can work.
In this case, even justify-content: space-between would work.
Of course, you'll need to apply visibility: hidden to the duplicate element.
.container {
background: lightblue;
width: 300px;
height: 300px;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
padding: 10px;
}
.box {
background: goldenrod;
height: 30px;
width: 30px;
margin: auto 0; /* or instead use justify-content: space-between on .container */
}
span:first-child {
visibility: hidden;
}
<div class="container">
<span>Text</span>
<div class="box"></div>
<span>Text</span>
</div>
OR, instead of a duplicate element, use a pseudo-element.
A less intrusive and more semantically proper method would use a pseudo-element as the duplicate. However, for this method to work, you would need to know the height of the actual element, because you would need to match it precisely.
Something like this will work to create equal balance:
.container::before {
content: "";
height: 15px; /* must match actual element's height */
}
.container {
background: lightblue;
width: 300px;
height: 300px;
display: flex;
justify-content: space-between;
flex-direction: column;
align-items: center;
padding: 10px;
}
.box {
background: goldenrod;
height: 30px;
width: 30px;
}
span {
height: 15px;
}
.container::before {
content: "";
height: 15px;
}
<div class="container">
<div class="box"></div>
<span>Text</span>
</div>