4

I have a table in HTML which has an associated caption. I want to draw a box around these collectively (a single box around the tabular part and the caption),

caption {
  border: 2px solid #eeeeee;
}
table {
  border: 4px solid black;
}
<html>
<table>
  <caption>Table caption</caption>
  <thead>
    <tr>
      <td>Alpha</td>
      <td>Beta</td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
    </tr>
  </tbody>
</table>  
</html>

I know I could wrap the whole table in a DIV and style that, but I am using another program to generate the HTML programmatically (HTML from markdown using pandoc) so I can't control this. Is there any way to make the black box in the example go all around both the table part and the caption?

Brian Diggs
  • 57,757
  • 13
  • 166
  • 188

4 Answers4

6

If you set the display property of the table to inline-block, then the border of the table will surround both the tabular part and the caption.

caption {
  border: 2px solid #eeeeee;
}
table {
  border: 4px solid black;
  display: inline-block;
}
<html>
<table>
  <caption>Table caption</caption>
  <thead>
    <tr>
      <td>Alpha</td>
      <td>Beta</td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
    </tr>
  </tbody>
</table>  
</html>
Brian Diggs
  • 57,757
  • 13
  • 166
  • 188
3

Why:

From the description of table model:

In terms of the visual formatting model, a table can behave like a block-level (for display: table) or inline-level (for display: inline-table) element.

In both cases, the table generates a principal block box called the table wrapper box that contains the table box itself and any caption boxes (in document order). The table box is a block-level box that contains the table's internal table boxes. The caption boxes are block-level boxes that retain their own content, padding, margin, and border areas, and are rendered as normal block boxes inside the table wrapper box. Whether the caption boxes are placed before or after the table box is decided by the 'caption-side' property, as described below.[...]

That said caption is a well defined element that's not inside the table element (because the actual parent element is the table-wrapper-box) ;
the border property defined for table is applied only to the table-box.


Solution:

Wanting to maintain the caption-side functionality a good option is creating a wrapper, in this way you can also use default display:table.

A smooth way to do this without using additional markup is with pseudo-elements;

caption {
   border: 2px solid #eeeeee;
   /*caption-side:bottom;*/
}
table {
   /* border: 4px solid black;*/
   position: relative;
   padding: 3px;
   
}
table:before {
   display: block;
   content:'';
   position: absolute;
   bottom: 0;
   left: 0;
   right:0;
   top:-4px;
   border: 4px solid black;
   
}
<html>
<table>
<caption>Table caption</caption>
<thead>
    <tr>
        <td>Alpha</td>
        <td>Beta</td>
    </tr>
</thead>
<tbody>
    <tr>
        <td>1</td>
        <td>2</td>
    </tr>
</tbody>
</table>
</html>
maioman
  • 18,154
  • 4
  • 36
  • 42
  • Your answer got me to an understanding of the distinction between table box and table wrapper box. I could not get your answer to work for me in my more complicated application, but I awarded you the bounty based on the detailed "why". – Brian Diggs Jul 06 '15 at 06:46
  • what do you mean by, "you can also use default display:table"? – IEnjoyEatingVegetables Mar 19 '18 at 14:51
  • @JohnOsborne an alternative can be to change the `display` of table to `inline-block` as in another answer that was already present – maioman Mar 19 '18 at 20:25
1

Just create 3 borders on each element:

caption {
  border-left: 4px solid black;
  border-right: 4px solid black;
  border-top: 4px solid black;
}
table {
  border-left: 4px solid black;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
}

JsFiddle: http://jsfiddle.net/ghorg12110/frffLe7q/

Magicprog.fr
  • 4,072
  • 4
  • 26
  • 35
  • I see that that works, but it seems inelegant. In particular, with `caption {caption-side: bottom}`, which borders to include and which to exclude changes. – Brian Diggs Jun 29 '15 at 16:28
0

Yes You can use inline-block style and for your reqiurement i tried the outline style that also works good and thanks

caption {
   border: 2px solid #eeeeee;
  
}
table {
    outline: 1px solid;
   
   
}


   
<html>
<table>
<caption>Table caption</caption>
<thead>
    <tr>
        <td>Alpha</td>
        <td>Beta</td>
    </tr>
</thead>
<tbody>
    <tr>
        <td>1</td>
        <td>2</td>
    </tr>
</tbody>
</table>
</html>
Raj Rana
  • 90
  • 6
  • Thank you for pointing out the outline property; I had not heard of that before. However, when I try your example, the outline only goes around the table proper, not around the table and caption. When the display property is changed, the outline also follows the border (both go around the same content). – Brian Diggs Jul 04 '15 at 01:15
  • 1
    @BrianDiggs: This is browser differences. Chrome puts outline around the entire table and Firefox places outline around the table minus caption. – DRD Jul 04 '15 at 17:43