I'm looking for the most efficient (or elegant) way to vertically and horizontally center content of variable height. I've come up with this: http://cssdeck.com/t/2veysdkg/16, which uses css tables to vertically center the main content.
My demands for writing this particular piece of code were:
The weird thing is that the demands above are only met when the header and footer are set to display:table-row, and the body-tag to display:table. Which is weird because as I understand it the css will generate anonymous table elements when parent table elements are missing. So display:table-cell should work without all the surrounding elements, but yet I've not been able to make it work.
If it were up to me I would prefer to not mess with the display mode for the body tag, and leave the header and footer on display:block. But I've not been able to make it work. Does anyone understand why this doesn't work, and how to meet the above demands without the use of display:table and display:table-row?
For those who would rather not visit cssdeck to view my sourcecode I'll post it here:
HTML
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Vertical Centering</title>
</head>
<body>
<div id="header">header</div>
<div id="vertical">
<div id="horizontal">content</div>
</div>
<div id="footer">footer</div>
</body>
</html>
CSS
body, html {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
body {
display: table;
}
#header {
display: table-row;
height: 2em;
background: gray;
}
#vertical {
display: table-cell;
vertical-align: middle;
width: 100%;
height: 100%;
}
#horizontal {
height: 500px;
width: 500px;
margin: auto;
background: gray;
}
#footer {
height: 2em;
display: table-row;
width: 100%;
background: gray;
}
How Does display property Work?
The display property allows you to specify a range of table-related values in order to make elements display as though they were table elements. The available display values are:
table makes the element behave like a table elementtable-row makes the element behave like a table row (tr) elementtable-cell makes the element behave like a table cell (td) elementtable-row-group makes the element behave like a table body row group
(tbody) elementtable-header-group makes the element behave like a table header row
group (thead) elementtable-footer-group makes the element behave like a table footer row
group (tfoot) elementtable-caption makes the element behave like a table caption elementtable-column makes the element behave like a table column (col)
elementtable-column-group makes the element behave like a table column group
(colgroup) elementcheck complete list here... http://www.digital-web.com/articles/everything_you_know_about_CSS_Is_wrong/
but your issue can be solved like this
Check working fiddle http://jsfiddle.net/jZJXf/1/
Css should be like this.
body, html {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
body {
display: table;
}
#header {
width: 100%;
height: 2em;
background: gray;
}
#vertical {
display: table;
width: 100%;
height: 100%;
}
#horizontal {
display:table;
height: 500px;
width: 500px;
margin: 10% auto 0% auto;
background: gray;
}
#footer {
height: 2em;
width: 100%;
background: gray;
bottom: 0px;
display: table;
}
Actually, the browser is inserting an anonymous table element as you expected. However, this element only exists to make the table semantics work. There isn't any way in CSS to target this anonymous block to give it 100% width and height, which your layout requires.
You'll need an actual element in your HTML to act as the "table" object if you want to alter its presentation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With