Reputation: 2785
I know there are many ways to center things with CSS. Centering anything horizontally is quite straight forward. However, if you are going to center anything vertically, it is a whole new story. I just want to know why we can't just say bottom-align:auto; top-align:auto; as we do when we want something centered horizontally? Why does something which seems as simple as centering something seem so hard when centering something horizontally is that simple? I know there are many ways, but let's just say you have an element of an unknown size you want to center inside another element of unknown size.
I have been sitting with this for almost two days without finding a good question on this answer, we have tons of different ways to center items horizontally, but why has not one single CSS standard come up with a way to center this vertically? Is it a bad thing to do? Does it make people cry or randomly go into labor? Does it melt down nuclear reactors?
We live in 2014. It seems unnecessary to have to use Javascript in order to do something as simple as to center something inside another element.
Edit: Code sample of what I mean: http://jsfiddle.net/VsakD/
CSS:
div.parentbox
{
width:500px;
height:500px;
border-style:solid;
}
div.childbox
{
width:300px;
height:300px;
border-style:solid;
margin-left:auto;
margin-right:auto;
margin-top:auto;
margin-bottom:auto;
}
HTML:
<div class="parentbox">
<div class="childbox">
I shall be in the middle of parentbox regardless of its size!
</div>
</div>
Upvotes: 2
Views: 845
Reputation: 99494
Can someone please highlight exactly why I can't just say
margin-top:auto; margin-bottom:auto;
to vertical align, which would be logical to assume would work since you domargin-left:auto; margin:right:auto;
to horizontally align?
According to Spec (10.6.2):
Inline replaced elements, block-level replaced elements in normal flow, 'inline-block' replaced elements in normal flow and floating replaced elements
If 'margin-top', or 'margin-bottom' are 'auto', their used value is 0.
That's why using top/bottom margin
is this case, doesn't make a change.
By the way, in order to align a div element (with unknown dimensions) vertically inside a container, you could follow this approach:
.parentbox {
text-align: center; /* Align inline elements center horizontally */
font: 0/0 a; /* <-- remove the gap between inline(-block) elements */
}
.parentbox:before {
content: ' ';
display: inline-block;
vertical-align: middle;
height: 100%;
}
.childbox {
display: inline-block;
vertical-align: middle;
font: 1rem/1 Arial, sans-serif; /* <-- Reset the font */
}
Upvotes: 2
Reputation: 108
The best way I have achieved the technique you desire is by using table
display
rules.
<div class="parent-container'>
<div class="child-container">
This is vertically centered text!
</div>
</div>
The trick is in the CSS
.parent-container {
display: table;
width: 100%;
height: 300px;
background-color: #ff0000;
}
.child-container {
display: table-cell;
vertical-align: middle;
}
By making the parent container display as a table
, and the child display as the cell
, it follows the same vertical alignment rules as a table
, because that's what you're telling it to recognize itself as.
Here's my JS fiddle for reference. I put a fixed height to show the vertical alignment in action, but in reality, it will work with percentage heights or calculated heights from padding as well. http://jsfiddle.net/JTVeG/
Upvotes: 0
Reputation: 933
Author code with modifications I shall be in the middle of parentbox regardless of its size!
div.parentbox
{
width:500px;
height:500px;
border-style:solid;
display: table; //added this line
}
div.childbox
{
width:300px;
height:300px;
border-style:solid;
margin-left:auto;
margin-right:auto;
margin-top:auto;
margin-bottom:auto;
display: table-cell; //added this line
vertical-align: middle;
text-align: center;
}
Upvotes: -1
Reputation: 413757
The display: table
approach is one way, but it's also possible to take advantage of CSS transforms. Unlike many other CSS properties like "top", for which percentages are figured relative to the containing element, the CSS transforms apply percentages to the element itself. Thus, you can position an element 50% of the way down inside its container, and then transform it up by 50% of its own size:
.center-me {
position: relative;
top: 50%;
transform: translateY(-50%);
margin-left: auto; margin-right: auto;
width: 300px; /* or whatever */
}
<div class=center-me> Hello World! </div>
Thanks go to the great Dave Walsh. Here is a jsfiddle to demonstrate.
Upvotes: 0
Reputation: 4093
You can easily find the older techniques to do so, but there's a newer technique discussed here: http://zerosixthree.se/vertical-align-anything-with-just-3-lines-of-css/
It works in IE9+ and all other browsers. The benefit of using this is not having to know the height of an element or use absolute positioning. Multiple lines of text aren't affected by the line-height method.
.element {
position: relative;
top: 50%;
transform: translateY(-50%);
}
Upvotes: 0