Why the space after the table, and how to remove it?


Tags: css,css-tables

Problem :

HTML:

<span id="a">
  <span id="b">
    <span id="c">
      Text
    </span>
  </span>
</span>

CSS:

#a { display: block;        border: 2px solid #e00; }
#b { display: inline-block; border: 2px solid #0e0; }
#c { display: table;                                }

This shows as:

with display: table

You can view this in this jsFiddle.

Notice how there is no space between the top of the green/inner box and the red/outer box, but there is some space between the bottom of the green/inner and red/outer box. This is caused by the display: table. Adding margin: 0; padding: 0 on all 3 boxes doesn't have an effect. So my questions are:

  1. How do you explain this added space? I'm finding this to be somewhat unusual.
  2. How can you avoid it, assuming you need to keep the display as-is on all 3 elements, you can't change the HTML (can't add or remove elements), but otherwise you can add any CSS you'd like?


Solution :

  1. How do you explain this added space? I'm finding this to be somewhat unusual.

    As Alohci has explained in the comments, the display: table element masks the baseline of its contained text (which itself lives in an anonymous table-cell within the table box).

    The reason display: table has this effect is because, as stated in section 17.4 of the CSS2.1 spec, the principal box that's generated, called the table wrapper box, establishes a block formatting context. The table box and any caption boxes within this element participate in this block formatting context, completely isolated from the rest of the layout. This means that the text within the display: table element participates in an inline formatting context within the table wrapper box (specifically, in the anonymous table-cell mentioned above) and the inline-block element is completely unaware of this text.

    So, as far as the inline-block is concerned, it doesn't contain any in-flow line boxes since the only in-flow box in its own block formatting context is a block-level table, and section 10.8 of the spec says:

    The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible', in which case the baseline is the bottom margin edge.

    And again as Alohci explains, this causes the inline-block to align its bottom edge with the line box it's on (via the strut). The added space is there to accommodate typographic descenders on the same line box as the inline-block.

    If you change the display: table declaration to a float declaration, i.e.:

    #a { display: block;        border: 2px solid #e00; }
    #b { display: inline-block; border: 2px solid #0e0; }
    #c { float: left;                                   }
    

    You'll get similar results.

  2. How can you avoid it, assuming you need to keep the display as-is on all 3 elements, you can't change the HTML (can't add or remove elements), but otherwise you can add any CSS you'd like?

    There are a number of ways. You can either force the line-height of #a to be zero and restore the line-height on #b:

    #a { display: block;        line-height: 0;      border: 2px solid #e00; }
    #b { display: inline-block; line-height: normal; border: 2px solid #0e0; }
    #c { display: table;                                                     }
    

    Or you can set vertical-align to any of top, middle or bottom to #b:

    #a {
      display: block;
      border: 2px solid #e00;
    }
    #b {
      display: inline-block;
      vertical-align: middle;
      border: 2px solid #0e0;
    }
    #c {
      display: table;
    }
    

    CSS Howto..

    Basic Accordion pull down using java script and css not working. How can I get it to not have a symbol beside it?

    How to print outlines and background colors from css, when using JQuery printElement, and IE8?

    How to size images loaded from other users such that dimensions are maintained yet a max width and height are set with css? (HTML/JS/CSS)

    css how to make full height div with scroll support?

    Show/Hide images based on tab selection

    If there is too many menu items how to gather them into collapsed menu

    How Is This Effect Achieved? HTML/CSS/jQuery [closed]

    How to set a background image in css?

    How to generate regular CSS file from SASS?

    How to achieve this bevel button in CSS?

    How to convert a CSS3 2D animatuon to a 3D Transform

    How does browser layout adjacent div to a floating div

    How do I line up CSS elements? Is there a tool I can use?

    How can a site Use Javascript and NOT display any structural HTML in the browser?

    how can I center button below my text while using bootstrap css?

    how to use static folder in django for css and javascript?

    How do I animate a div with css3 to move and spin?

    Django + Mac osx how to use less css?

    How to show “…” when there's not enough space to view all the text

    how to do 3d menu in css 3 with that effect like on page [closed]

    How to toggle the contents of span when clicked?

    How to set CSS rule for a LI in a UL nested in DIV with class?

    How is does Jquery display a tooltip on this span element?

    How to get the navigation bar to align to the center

    How to put some divs in a row?

    How can i improve my javascript? codepen included

    how to render tilted images in html or css or javascript ..?

    How to add tooltip to image on hover with CSS

    Normalized CSS, option in JSFiddle, how to add it to document

    How to change horizontal block-level elements to vertical elements after specific width?