问题
I'm trying to vertically center some text inside a div. Sounds easy but I can't get it. Here's the code, sorry for the bad formatting and practices, it's something whipped up fast and dirty:
<div id="container" style="text-align:center ;border: 5px solid blue; display:flex; flex-direction:row ; justify-content:center; height:100px">
<div id="first" style=" min-height:100px; min-width:200px; background-color:green">
<div style="vertical-align:middle">
first box
</div>
</div>
<div id="second" style=" min-height:100px; min-width:200px; background-color:yellow">
<div style="vertical-align:middle">
second box
</div>
</div>
<svg version="1.1" id="SVG" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 300 300" preserveAspectRatio="xMidYMid meet" height="100%" width: "auto">
<!--snipped away svg code-->
</svg>
<div id="third" style="min-height:100px; min-width:200px; background-color:red">
<div style="">
third box
</div>
</div>
<div id="fourth" style="min-height:100px; min-width:200px; background-color:cyan; vertical-align:middle ">
<p>
fourth box
</p>
</div>
</div>
As you can see, there's four boxes around a central svg image. Horizontally centering the elements inside the "container" div was easy, vertically centering the text inside each of those elements is not. Not at all.
I've tried various solutions, none of which worked like intended (the text just goes up to the top of the box). Am I missing something obvious or am I trying to do something impossible?
I'm looking for a flexible solution, something that can work without knowing the exact height in pixels of the boxes nor the container.
回答1:
Since you are using flexbox, you don't need to use vertical-align
.
Here are two things to consider:
When you create a flex container only the child elements become flex items. Any descendant elements beyond the children are not flex items and flex properties don't apply to them.
Your
div
boxes wrapping your text are not flex items. They are children of flex items (#first
,#second
, etc.) and flex properties don't apply.If you want to apply flex properties to the children of flex items, you need to make the flex item a flex container, as well.
Try this:
#first { display: flex; justify-content: center; align-items: center; } #second { display: flex; justify-content: center; align-items: center; }
#first {
display: flex;
justify-content: center;
align-items: center;
}
#second {
display: flex;
justify-content: center;
align-items: center;
}
<div id="container" style="text-align:center ;border: 5px solid blue; display:flex; flex-direction:row ; justify-content:center; height:100px">
<div id="first" style=" min-height:100px; min-width:200px; background-color:green">
<div style="vertical-align:middle">first box</div>
</div>
<div id="second" style=" min-height:100px; min-width:200px; background-color:yellow">
<div style="vertical-align:middle">
second box
</div>
</div>
<svg version="1.1" id="SVG" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 300 300" preserveAspectRatio="xMidYMid meet" height="100%" width: "auto">
<!--snipped away svg code-->
</svg>
<div id="third" style="min-height:100px; min-width:200px; background-color:red">
<div style="">
third box
</div>
</div>
<div id="fourth" style="min-height:100px; min-width:200px; background-color:cyan; vertical-align:middle ">
<p>
fourth box
</p>
</div>
</div>
Re: vertical-align
The reason vertical-align: middle wasn't working for you is because this property centers within the inline dimension. So it actually was vertically centering the text... within its line-height
. To get the behavior you expect, specify a line-height
equal to the container height.
#third {
vertical-align: middle;
line-height: 100px;
}
#first {
display: flex;
justify-content: center;
align-items: center;
}
#second {
display: flex;
justify-content: center;
align-items: center;
}
#third {
vertical-align: middle;
line-height: 100px;
}
<div id="container" style="text-align:center ;border: 5px solid blue; display:flex; flex-direction:row ; justify-content:center; height:100px">
<div id="first" style=" min-height:100px; min-width:200px; background-color:green">
<div style="vertical-align:middle">first box</div>
</div>
<div id="second" style=" min-height:100px; min-width:200px; background-color:yellow">
<div style="vertical-align:middle">
second box
</div>
</div>
<svg version="1.1" id="SVG" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 300 300" preserveAspectRatio="xMidYMid meet" height="100%" width: "auto">
<!--snipped away svg code-->
</svg>
<div id="third" style="min-height:100px; min-width:200px; background-color:red">
<div style="">
third box
</div>
</div>
<div id="fourth" style="min-height:100px; min-width:200px; background-color:cyan; vertical-align:middle ">
<p>
fourth box
</p>
</div>
</div>
回答2:
This code will center all the text:
#container div div, #container div p {
position: relative;
top: 50%;
transform: translateY(-50%);
margin: 0;
}
Expand this live demo to see it in action:
#container {
text-align:center;
border: 5px solid blue;
display:flex;
flex-direction:row;
justify-content:center;
height:100px;
}
#first {
min-height:100px;
min-width:200px;
background-color:green;
}
#second {
min-height:100px;
min-width:200px;
background-color:yellow;
}
#third {
min-height:100px;
min-width:200px;
background-color:red;
}
#fourth {
min-height:100px;
min-width:200px;
background-color:cyan;
}
#container div div, #container div p {
position: relative;
top: 50%;
transform: translateY(-50%);
margin: 0;
}
<div id="container">
<div id="first">
<div>first box</div>
</div>
<div id="second">
<div>second box</div>
</div>
<svg version="1.1" id="SVG" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 300 300" preserveAspectRatio="xMidYMid meet" height="100%" width: "auto">
<!--snipped away svg code-->
</svg>
<div id="third">
<div>third box</div>
</div>
<div id="fourth">
<p>fourth box</p>
</div>
</div>
Normally just the first three properties are required, but your fourth element was a <p>
element, which has top and bottom margins, so I added margin: 0;
to cancel those out. This is the most reliable way to center elements vertically regardless of markup unless you can use flexbox.
来源:https://stackoverflow.com/questions/33334732/vertically-center-text-inside-a-div