Grow your CSS skills. Land your dream job.

Wolf in Sheep’s Clothing

Published by Chris Coyier

Roger Johansson has a neat quick-tip style article on centering page content both vertically and horizontally by making the html element display: table; and the body element display: table-cell; with vertical-align: middle;. See the full code to make it happen in the article.

I'm down with that. Works in all modern browsers and IE 8 plus.

I disagree on this though:

I’ve seen people saying that using these CSS properties to create “CSS tables” is no better than using tables in your HTML. I don’t agree with that.

Using CSS to change an element’s display properties does not change the semantics of the underlying HTML – it just changes how the element is displayed. It does not turn arbitrary HTML elements into table, th or td elements.

Using display: table; for this little centering trick is no big deal. It affects how the elements are display, stays semantic, all is well. But when you start using CSS tables for layout, you are entering a world of source order dependent layout. Elements that need to be in the top left need to be first in the markup. Elements that need to be in the bottom right need to be last in the markup. Just like regular tables. You wouldn't use any other positioning to force them the be placed differently, because then there is no point of using CSS tables to begin with.

Floats, as gross as they can be, don't have this problem. You can swap float values and totally change a layout regardless of source order. The CSS3 flexible box model, as unsupported as it is, allow you to control page position with the ordinal group value.

Using a bunch of divs (or even fancy HTML5 semantic elements) and forcing them to behave like tables is a wolf in sheep's clothing. And yeah we've been down this path before =)

Comments

  1. I think it’s pretty clear that Roger means using CSS table properties doesn’t change the semantics of elements they’re applied to. So if you need table display-like properties, whether that means losing the ability to source order or not, you can still keep the same semantics of whatever they’re being applied to.

    • On an element-by-element level the semantics *might* stay the same, but the semantic quality of the document itself is likely to suffer. Let’s say you have a cool design where the logo is in the bottom right corner. Unusual, but it might be a beautiful and effective design. If you did a layout with a bunch of divs or sections or whatever, made them display like a table, that logo would need to be the last thing listed.

      Roger has some good research, a neat technique, and interesting points. I just want to voice my opinion that CSS tables are a dangerous road to go down and hold little value aside from tricks like the centering one.

    • Christopher
      Permalink to comment#

      Chris, I think you may be thinking too broad here. I personally think of the table display properties as similar to other (display related) properties like absolute and relative positioning – they’re tools in the belt to help build a page. I would not build an entire page using AP or RP (like a lot of beginners do) but use them when and where I need them.

      Take for instance a dynamically generated horizontal menu. You could display the list items as table-cell and have them fill the entire width, regardless of the number of items. This requires no more source ordering than if the list items were floats (you could argue that one could change the float order with margin magic but I digress).

      I only wish they hadn’t named the properties ‘table’. While it makes the most sense and is easy to comprehend, it brings about so many unnecessary arguments regarding ‘table layout’.

      Hi Tyssen!

    • The nav bar thing seems pretty reasonable. I’m more worried about this:

      http://www.digital-web.com/articles/everything_you_know_about_CSS_Is_wrong/

    • Jack Nycz
      Permalink to comment#

      Using a table for a nav bar is a completely logical and acceptable approach. Chris is addressing using table for an entire sites layout, about which he is absolutely correct.

  2. Chris, I agree with you that using table displays isn’t really the best solution, but floats are source-order-dependent as well. Without going into all the nuances; in order for display to be completely source-order-independent, you’d have to use absolute or fixed positioning.

  3. Float-based layouts need to die in a fire. What benefits they bring in a slight lessening of source-order dependence is greatly outweighed by their fragility and complexity.

    CSS Tables also have source-order dependence issues, yes, but the general layout abilities they allow are nice enough that we can forgive them for now. They’re simple and useful.

    In the next few years CSS layout will finally stop sucking, with Flexbox Layout, Grid Layout, and Positioned Layout all being specced this year, and implementations beginning soon after that.

    (I’m a CSSWG member, and making layout not suck is my primary goal. ^_^)

  4. Noah
    Permalink to comment#

    Another way to center things vertically and horizontally without using table displays is to do this:

    #parent {
    position:relative;
    }
    #child {
    dposition:absolute;
    top:0;
    right:0;
    bottom:0;
    left:0;
    margin:auto;
    }

    That will center the element in the exact center. Make sure the element isn’t displayed block though since their width is 100%

    • kayan
      Permalink to comment#

      Didn’t work for me, unless I define a height for the child element.

      It’s not that hard to vertically center something when it has a fixed height. It’s only really tricky to vertically center elements with flexible height, which table display accomplishes. But, I suppose this is a good technique for centering fixed height elements.

    • Noah
      Permalink to comment#

      That’s right. I forgot about the set height.

      Well this code works really well if you need to center images. Toss some images in an unordered list, float the list items. Add this css to them. Plus some box-shadow. And you have a sexy looking gallery

  5. There’s no wolf here, Roger is only suggesting to use display:table/table-cell; to align vertically and horizontally a single element inside a container. In his example you could still float elements inside the centered block and keep your loved source-order independency.

  6. Permalink to comment#

    I’ve always used the negative margin-bottom trick to center the page vertically, but I like how simple your method is.

  7. For years and years I preached that classical HTML are bad and CSS Layouts are good. Why is that? Because with CSS we can separate the content from presentation. So we have CSS who is controlling the HTML Layout and body HTML is just the pure content. But some time ago I made Two lines CSS Framework http://www.vcarrer.com/2010/10/two-lines-css-framework.html based on the principles of display:table / table-cell; and I had the same moral dilemma, Am I reinventing the classical HTML tables? But strangely the result is very clean and powerful CSS and the coding approach was similar to the CSS float coding logic. In one hand we have very powerful CSS technique in other hand we have the fears of the past not to do anything that has to do with tables . I will love to hear more opinions about this subject.

  8. I’ve seen a lot of sites use a negative margin-top of half of the height of the element you want to be vertically centered. The only downside is the element has to be fixed height.


    #center {
    position: fixed;
    height: 400px;
    margin-top: -200px;
    top: 50%;
    }

    using display: table-cell is probably the best way though, it just works.

  9. There is another way too, if you define the height of your element (which, when you are centering things in the window, you will most likely be defining a height):

    #container {
    width: 600px;
    height: 600px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -300px 0 0 -300px;
    }

    Just be sure to make your top and left margin a negative of half the height and width, respectively.

  10. If the element doesen’t have fixed height the css is useless… I prefer javascript if i need to vertically center an element. It is more logical as my opinion. I never think of layout or element height just a few lines of javascript code :)

  11. nAME
    Permalink to comment#

    Cool!

  12. GreLI
    Permalink to comment#

    You need a table-row element as well, if you are using a row of elements. Or you risk to encounter a random bug with misplaced elements in firefox and webkit. That makes usefulness of display:table negligible.

  13. well to be honest there’s only one way how this is good – you allready have a page centered horizontally and a customer decides that it shold be centered vertically as well… at this point its no good to go using tables and remaking the whole layout

    … and jusing JavaScript to avoid tables! the wonders :)

    ok i understand that css gives u better flexibility but this comes usefull only for top example, when u have a customer that cant make up his mind.

    Personaly the whole display: table-cell is mostly purist **** is u ask me… ok it comes in handy from time to time…. but the way its being used is bad…. specially since it usually takes up more code than hmm… go figure … tables

    i do like Rugiles solution though – since u usually use fixed height with vertical center

    • also the whole thing at least to me looks like: i really want to use tables for my layout but i can’t since they are ment to be used for tabular data…

      wel i really want to drink a lot of coffee – so i’d love to use a tea cup but i cant since it’s meant for tea …. so i need to get me a bigger coffee cup right ?

      css is nice … but if u want something that looks and feels like a table – use a table

  14. I use this one

    #container {
    width: 600px;
    height: 600px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -300px 0 0 -300px;
    }

    And yes indeed it’s wolf in sheeps clothing, haha nice post =D

  15. Permalink to comment#

    Tables? Seriously? Just hearing the word is making me itchy. The whole thought process behind building tabled sites is the whole reason I stayed away from web design for the first few years I was a designer. Just because your using CSS to build a table doesn’t make it any better.

    Tables are for serving up dinner, not websites.

    • Reminds me the Anti Comic Sans wars. Please don’t forget there is a place for everything. The HTML doesn’t “serve up” a website, table or div. That said, there’s a need for tables in websites. Avoiding them like altogether, much like many avoid using Comic Sans altogether, is just silly.

      As for the post, thanks. I like the idea. I think I’ll be using it, especially when I need to center something vertically. When thinking about how I would use it, having to declare a height, if even a min-height, is something I’d like to avoid.

      Cheers Chris,
      Dan B. Lee

  16. Anthony
    Permalink to comment#

    It seems to me that setting an elements display to “table” or “table-cell” via CSS is just another way of creating tables. Instead of having an HTML file full of ‘s and ‘s, you’ll end up with a CSS file full of “display: table” and “display: table-cell” declarations.

    In regards to the centering, I use the negative margin approach like a few other people here.
    <pre<<code<
    #container {
    width: 300px;
    height: 400px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -150px;
    margin-top: -200px;
    }
    </code<</pre<

    When I need to center an element of variable size, I’ve tended to use javascript but I appreciate that it isn’t a fail-safe solution since some people still insist on using certain browsers and disabling javascript….I’ll avoid opening THAT can of worms! ; )

  17. Anthony
    Permalink to comment#

    ^^^ Sorry for the horrible posting : (

    It seems to me that setting an elements display to “table” or “table-cell” via CSS is just another way of creating tables. Instead of having an HTML file full of <tr>‘s and <td>‘s, you’ll end up with a CSS file full of “display: table” and “display: table-cell” declarations.

    In regards to the centering, I use the negative margin approach like a few other people here.

    #container {
    width: 300px;
    height: 400px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -150px;
    margin-top: -200px;
    }

    When I need to center an element of variable size, I’ve tended to use javascript but I appreciate that it isn’t a fail-safe solution since some people still insist on using certain browsers and disabling javascript….I’ll avoid opening THAT can of worms! ; )

  18. Dan Carper
    Permalink to comment#

    Tables are definitely not cool.

    Using this technique to center something vertical feels dirty, but better than a lot of the alternatives. Mainly because this use-case implies that it is a 1 cell table, used only for the vertical alignment.

    Bottom line?
    1. I don’t think anyone is claiming we should go back to table layouts.

    2. It’s not like CSS3 provides us with a pure-css-vertical-alignment property like it should

  19. I think people are forgetting the main reason tables were bad for design. It wasn’t because they cluttered your markup or made it difficult to change a design. It was because they weren’t semantic and caused usability problems.

    To say that Roger is employing a “wolf in sheep’s clothing technique” or that he is advocating non-semantic HTML is very misleading. As an accessibility expert, I doubt that’s the position he’s trying to take.

    The purpose of the CSS display:table attribute is purely design related and has just as much reason to be used as floats and absolute positioning. As long as it doesn’t affect your HTML markup, I don’t see any problems with using it.

    • Permalink to comment#

      They were also bad because they were slow. Customary CSS layouts (with floats or positioning) load very quickly in comparison to tables. Especially when the page is very long and there are nested tables. Nested DIVs do not really affect speed that much (if at all), but nested tables do.

      I would assume that CSS tables don’t have speed problems, but I honestly don’t know if that’s the case because I’ve never used them, nor have I seen any performance tests based on that.

  20. Permalink to comment#

    Wow, there is a surprising amount of misinformation in the comments. Knee-jerk “oo, tables are bad” comments are missing the point entirely. Chris’s own opinion is that a source order dependency is created, not that having another tool for determining layout behaviour is bad.

    Thank goodness at least a few people have pointed out that you don’t have to use it everywhere.

    You wouldn’t need to litter your CSS with “display: table-cell” statements… if you’re doing your CSS correctly, you will group similar elements together, declaring as many as possible at once. You COULD even do it by adding a single class that does nothing more than set display: table-cell for the elements it is added to, but I’m not a big fan of class cruft either.

    It’s just a tool. And it’s not a hack. And you’re not creating tables by using that display property. Use it where it makes sense. I would use floats in the same scenario as Chris’s change-to-“float:left” example. But that doesn’t mean there’s no place to use display: table-cell elsewhere.

    I mean seriously… we’re willing to hack and trick CSS into doing what we want, discovering use-cases for various attributes that the original spec may not have even intended… (negative margin for centering? It may work, but it’s a hack!) but we’re not willing to use an attribute that’s correct and acceptable?

  21. Neat trick if it works – other solutions are always ugly and mean fiddling about with margins and pixel values. This has potential.

    Good to have the warning about using css tables more generally for markup instead of floats. I haven’t tried them yet …

  22. Permalink to comment#

    Personally I don’t think that using display:table; is bad practice or something like this.

    Here a website I built 3 years ago, were I used this technique and everything is working smooth even in IE6 (except CSS rounded corners but I don’t mind). And, by the way is valid HTML & CSS:

    http://jpginfo.com/

    Cheers,
    Ken

  23. Really neat trick. Very interesting. Will try and see if it works for me later!

  24. Don
    Permalink to comment#

    I wonder what folks think about this?
    http://expression.microsoft.com/en-us/dd794430.aspx Is the approach espoused by the author acceptable?

  25. This is something I’ve never heard of but it does make me fell uneasy. Making divs or other layout elements act like tables is surely not the right way to go. We spent 10 years trying to get away from table layouts and just because we want to do one thing we think its ok to hack CSS to go back to the old ways. I know no-one saying go back to table layouts but i think all the versions here are hacks so lets stick with the none table one.

    • display:table is part of the CSS specification. It’s not a hack. There’s nothing wrong with saying that you want a piece of content to be displayed in a tabular format if that’s what your design requires.

      Using tables in your markup for layout is clearly the wrong way of doing things now that we have good CSS support in all major browsers. However, some people, as evidenced by the comments, don’t seem to understand the difference between HTML and CSS. The whole purpose of CSS is page design and layout. And CSS is where table-like design code belongs.

      It doesn’t make sense to force people into using some convoluted floats or weird margins to accomplish a design that “should” be like a table when there are better CSS attributes. Maybe if they renamed it to something like display:grid, it wouldn’t leave such a bitter taste in everyone’s mouth. Don’t get caught up in the verbiage of it; it’s a useful attribute and has its place.

  26. Permalink to comment#

    Tables are and have always been the root of all evil! Even when they appear to be quick, efficient and good – they stab you in your back in the long run. By principle, I’ll never use tables. Good blog – I like debates… Makes life more interesting.

  27. nice piece of trick

  28. Ant
    Permalink to comment#

    I remember when I did something with div, while it would take same number of tr/td tags and lot less css code.

    /facepalm myself

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".