I've always disliked the idea of using the CSS property of display:table. Using it feels like an ugly hack and I always prefer to use a direct <table> tag instead. Of course, I use it only when necessary and always prefer a non-<table> based layout when possible. But for those occasions when a table is the only choice, I prefer the tag not the CSS. Naturally I've been reproached several times about this. In a recent discussion with Toni Leigh I finally managed to define my feelings about this issue well enough to make an argument out of it, so I'd like to present it here and hear what you guys think.

Crucial definitions

In HTML every tag can be thought of containing three distinct properties - functionality, layout and semantics.

Functionality is what the tag does. An <a href=""> redirects the user when clicked. An <input type="text"> creates a textbox. A <div> wraps a block of content so that it can be manipulated further as a whole. An <img> shows a picture. Etc.

Layout is what the tag looks like (and sounds like, if you're using a screen reader). This contains things like colors, borders, spacings, fonts, etc.

Semantics is what the tag means (or represents). It could be a menu item, a blog post, a photograph, a design element, etc.

The meat of the issue

In modern HTML the layout is the province of CSS, while both functionality and semantics are dependent of the tag name and occasionally a few attributes, which has the side effect of intertwining them. People try very hard to keep these two domains (layout and functionality/semantics) separated, so that the necessities of one would not affect the other. For that reason using a <table> for layout is scoffed, because that imposes a semantic change where only a layout change should be. And the preferred workaround is to use display: table as an alternative for achieving table-like layout effects but without the semantic changes that come along with the <table> tag. (Preemptive retort: no, a <table> doesn't make a bigger tag soup. You get all the same tags with display:table too, they're just all called <div> now)

The reason this feels so "wrong" to me is because I see the display:table as a CSS property which changes the functionality of a tag. It's like using CSS to change an <a> to a <form> or an <input type="text"> into a <button> or something (well, if it was possible). As far as I'm aware it's the only CSS property with such an effect. Everything else really does affect only layout, but display:table does more. For this reason it feels like it shouldn't even be in CSS. In particular:

  • New kind of relationships between tag sizes are created. In non-tabular layouts, only parent-child relationships between tags are able to affect each other. In a table, other tags in the same row/column can affect a cell's size, as well as the total width/height of the entire table.
  • To make it worse, you get colspans/rowspans (CSS browser support flaky at the moment, but it's getting there)
  • The display:table-header element will be printed on every page, when printing the document.
  • You get vertical alignment of text and border collapse.

And probably others I haven't thought of. Well, I guess they are sort of layout features, but they are a whole world apart from anything else that CSS can do. Treating some markup like a table switches the browser into a completely different mode, which is why I think it's a different functionality, not just layout.

The question

What do you think? Can all the changes that display:table brings be counted only as layout, or is it a change of functionality as well?


3 Answers 3


I'd say that a <table> tag has a semantic meaning. You are encoding tabular data. Mostly, layout is not tabular data, so using the <table> tag for layout is imposing presentation issues on a data-containing tag.

  • OK, I think I finally got it. The table is really in an unfortunate spot. To get the correct layout you need to sacrifice either a correct semantic or a correct functionality. It's a choice between two evils, and the latter is widely considered to be the lesser one.
    – Vilx-
    Commented Sep 21, 2015 at 12:45
  • @Vilx-: What is "the correct functionality" ?
    – JacquesB
    Commented Sep 21, 2015 at 14:03
  • @JacquesB - When I apply display:table to a <div>, that <div> starts acting lika a <table>. In other words, it has adopted the functionality of a different tag. When I do this for layout purposes, the layout of the tag is correct (that's how I wanted it), the semantics are correct (that's what the tag represents, a division), but the functionality is wrong (it's a <table> masquerading as a <div>).
    – Vilx-
    Commented Sep 22, 2015 at 8:06
  • @Vilx-: I think "functionality" muddies the issue because it describes both semantics and presentation. You might as well claim that making a paragraph large and bold gives it the functionality of a header (a <p> masquerading as a <h1>).
    – JacquesB
    Commented Sep 22, 2015 at 8:40
  • @JacquesB - No, a <p> and <h1> actually have an identical functionality. They just group a bit of content and allow to apply style to it. So does <div>, <span>, <blockquote> and a whole lot of others. They have a different semantic meaning and a different default layout, but the same functionality. An <input type="checkbox"> for instance has a different functionality. No matter what layout you apply to it, you cannot make a <p> act like <input type="checkbox">, short of using Javascript.
    – Vilx-
    Commented Sep 23, 2015 at 7:22

CSS "display:table" does not change the semantics of any element. The "functionality" effects you describe are just visual layout effects, which is the domain of CSS.

You are correct that element sizes outside of the parent-child relationships can effect each other when using table-layout. This is the whole point of table layouts in a nutshell. Other layout properties like float also affect the placement and sizing of other elements outside of parents/children. The effect is purely visual layout - its not like styling an element as a table suddenly turns another element from a form into a script. There are no semantic effects on other elements.

Vertical alignment and border collapse are also purely visual effects, and again there are many other examples where the css display model will affect the interpretation of other css properties. I.e. changing the display from 'inline' to 'block' or to 'inline-block' will change how border, padding and margins are interpreted.

All of the available values of the display-property can be said to switch the layout into a different mode which affect many other css properties.


I'm not quite sure what you mean by "functionality", but display is surely a special property. display changes the relationship between how elements interact with each other. The display property can change a block element (act like box) to become inline element (act like text), or vice versa.

AFAICT, display is the only CSS property that actually change not just how the element looks, but the entire algorithm used to render the element, how the element interact with other elements during layout, and how all other properties are interpreted.

When you look at what the other values for display, then display: table is not really very special at all.

  • float and position also changes the layout algorithm.
    – JacquesB
    Commented Sep 22, 2015 at 17:15
  • Functionality is what the tag does. Hmm.. how to better explain... imagine that we ignored all the semantic differences between tags and there was no default CSS for them, not even the default stuff that comes with the browser. In that case, there would be no difference at all between, say, <div>, <span>, <p>, <h1>, etc. All those tags would be equal in every way. But an <a href=""> would be different - it would display a link, which would redirect a user to another page when clicked. You can't do that with a <div> no matter what you do. That's a difference in functionality.
    – Vilx-
    Commented Sep 23, 2015 at 7:26
  • @Vilx: if that's how you define functionality, then I disagree that it belongs to HTML. HTML defines semantic, not interaction flow. The interaction flow is defined by JavaScript. An <a> tag has the semantic that the linked page contains something of interest related to the linked text; defining that the rendered element can be clicked or spoken into to visit the page is outside the domain of HTML. An <input> tag says that the linked page receives the parameter, it doesn't really mean that the browser should display a control widget.
    – Lie Ryan
    Commented Sep 23, 2015 at 9:33
  • @LieRyan - Perhaps, although I think it's worth another debate of its own. If true, then that would be THE biggest most glaring flaw of HTML ever, because this (unspecified) functionality is what every web developer has to rely on every day to do anything at all.
    – Vilx-
    Commented Sep 23, 2015 at 11:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.