Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does display:table-cell not center content without display:table?

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:

  • Must be able to center variable and fixed width content vertically and horizontally
  • Centered content must be inside the normal document flow (so no overlapping)
  • Sticky footer and normal header, both of 100% width
  • As few hacks, ugly code or non-semantic html as possible
  • I didn't care about support for IE6, IE7 (I'll use a different stylesheet for them)

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;
}

2 Answers

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 element
  • table-row makes the element behave like a table row (tr) element
  • table-cell makes the element behave like a table cell (td) element
  • table-row-group makes the element behave like a table body row group (tbody) element
  • table-header-group makes the element behave like a table header row group (thead) element
  • table-footer-group makes the element behave like a table footer row group (tfoot) element
  • table-caption makes the element behave like a table caption element
  • table-column makes the element behave like a table column (col) element
  • table-column-group makes the element behave like a table column group (colgroup) element

check 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;

}
like image 116
CSS Guy Avatar answered Sep 05 '26 23:09

CSS Guy


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.

like image 23
Gareth Avatar answered Sep 06 '26 00:09

Gareth



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!