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>