Reputation: 525
i have a outer table with a fixed row height (in this example 24px). i want to nest a table to add some content but also want to mimic the row heights and borders inside. But there is a 1px difference as you can see here:
I cannot explain this, but have the feeling that is has something to do with the rowspan and maybe the nested table with flexboxes.
Question: I wonder that the innerTable has a expected height of 72px, but the parent td.itemblock has a height of 72.8px. Can someone tell me the reason for this difference? And is there some setting to prevent this?
* {
margin: 0;
padding: 0;
border: 0;
outline: 0;
}
table {
border-collapse: collapse;
box-sizing: border-box;
table-layout: fixed;
width: 100%;
font-size: 10px;
border-spacing: 0;
}
tr {
height: 24px;
}
td {
border-bottom: 1px solid black;
padding: 0;
vertical-align: top;
box-sizing: border-box;
}
.firstColumn {
width: 24px;
border-right: 1px solid black;
}
td.small {
width: 12px;
border-right: 1px solid black;
}
.title {
flex-grow: 1;
display: block;
text-overflow: ellipsis;
overflow: hidden;
height: 24px;
}
.item {
display: flex;
background-color: lightblue;
padding-left: 4px;
padding-right: 4px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin-bottom: 1px;
height: 100%;
}
.innerTable td {
border-bottom: 0;
border-right: 0;
width: auto;
}
.itemCell {
position: relative;
}
.innerTable td.blockCell {
border-bottom: 1px solid black;
}
<html>
<head>
</head>
<body>
<table class="outerTable">
<tr>
<td rowspan="2" class="firstColumn">0</td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td rowspan="3" class="itemBlock">
<table class="innerTable">
<tr>
<td rowspan="3" class="itemCell">
<div class="item">
<div class="title">some content</div>
</div>
</td>
<td class="blockCell"></td>
</tr>
<tr>
<td class="itemCell blockCell">
<div class="item">
<div class="title">other content</div>
</div>
</td>
</tr>
<tr>
<td>
</td>
</tr>
</table>
</td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td rowspan="2" class="firstColumn">1</td>
<td></td>
<td class="small"></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td rowspan="2" class="firstColumn">2</td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
</table>
</body>
<html>
Update:
With the proposals i was able to assemble this, which looks like it is working. The changes are:
Though it seems i have a "hacky" solution, still i dont have an explanation for this! Any html table experts?
* {
margin: 0;
padding: 0;
border: 0;
outline: 0;
}
table {
border-collapse: collapse;
box-sizing: border-box;
table-layout: fixed;
width: 100%;
font-size: 10px;
border-spacing: 0;
}
tr {
height: 24px;
}
td {
box-shadow: 3px -3.5px 0px -3px rgba(0, 0, 0, 1) inset;
padding: 0;
vertical-align: top;
box-sizing: border-box;
}
.firstColumn {
width: 24px;
border-right: 1px solid black;
}
td.small {
width: 12px;
border-right: 1px solid black;
}
.title {
display: block;
text-overflow: ellipsis;
overflow: hidden;
}
.innerTable td {
border-bottom: 0;
border-right: 0;
width: auto;
height: 72px;
}
.itemCell {}
.item {
height: calc(100% - 0.75px);
background: lightblue;
display: flex;
background-color: lightblue;
padding-left: 4px;
padding-right: 4px;
}
.innerTable td.blockCell {
box-shadow: 3px -3.5px 0px -3px rgba(0, 0, 0, 1) inset;
}
<html>
<head>
</head>
<body>
<table class="outerTable">
<tr>
<td rowspan="2" class="firstColumn">0</td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td rowspan="3" class="itemBlock">
<table class="innerTable">
<tr>
<td rowspan="3" class="itemCell">
<div class="item">
<div class="title">some content</div>
</div>
</td>
<td class="blockCell"></td>
</tr>
<tr>
<td class="itemCell blockCell">
<div class="item">
<div class="title">other content</div>
</div>
</td>
</tr>
<tr>
<td>
</td>
</tr>
</table>
</td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td rowspan="2" class="firstColumn">1</td>
<td></td>
<td class="small"></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td rowspan="2" class="firstColumn">2</td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
</table>
</body>
<html>
Upvotes: 6
Views: 1217
Reputation: 968
Using box-sizing:border-box
is relevant only for the parent cell who has the border - but the nested table doesn't care about it's parent's border, only about its own.
In a plain table the border of the cells is part of the cell and thus considered in the computation of the cell heights:
<tr>
<td></td>
<td></td>
</tr>
In the case of a nested table, the border belongs to the cell that contains the table, and thus is not available for computing the height of the cell:
<tr>
<td rowspan="2">
<table>
<tr>
<td></td>
<td></td>
</tr>
</table>
</td>
</tr>
Finding the solution is harder than determining the cause.
My idea is to
.innerTable{
margin-top: -1px;
margin-bottom: -1px;
border-top: 1px solid black;
border-bottom: 1px solid black;
}
Setting only margin-bottom
(or even worse, setting margin-bottom:-2px
) doesn't help - border-collapse: collapse;
means that two cells share their border, but it doesn't change that they end up having borders on both sides, so the size of both borders needs to be counted.
.innerTable{
margin-top: -1px;
margin-bottom: -1px;
border-top: 1px solid black;
border-bottom: 1px solid black;
}
* {
margin: 0;
padding: 0;
border: 0;
outline: 0;
}
table {
border-collapse: collapse;
box-sizing: border-box;
table-layout: fixed;
width: 100%;
font-size: 10px;
border-spacing: 0;
}
tr {
height: 24px;
}
td {
border-bottom: 1px solid black;
padding: 0;
vertical-align: top;
box-sizing: border-box;
}
.firstColumn {
width: 24px;
border-right: 1px solid black;
}
td.small {
width: 12px;
border-right: 1px solid black;
}
.title {
flex-grow: 1;
display: block;
text-overflow: ellipsis;
overflow: hidden;
height: 24px;
}
.item {
display: flex;
background-color: lightblue;
padding-left: 4px;
padding-right: 4px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin-bottom: 1px;
height: 100%;
}
.innerTable td {
border-bottom: 0;
border-right: 0;
width: auto;
}
.itemCell {
position: relative;
}
.innerTable td.blockCell {
border-bottom: 1px solid black;
}
<html>
<head>
</head>
<body>
<table class="outerTable">
<tr>
<td rowspan="2" class="firstColumn">0</td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td rowspan="3" class="itemBlock">
<table class="innerTable">
<tr>
<td rowspan="3" class="itemCell">
<div class="item">
<div class="title">some content</div>
</div>
</td>
<td class="blockCell"></td>
</tr>
<tr>
<td class="itemCell blockCell">
<div class="item">
<div class="title">other content</div>
</div>
</td>
</tr>
<tr>
<td>
</td>
</tr>
</table>
</td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td rowspan="2" class="firstColumn">1</td>
<td></td>
<td class="small"></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td rowspan="2" class="firstColumn">2</td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
</table>
</body>
<html>
Upvotes: 2
Reputation: 1550
table {
border-collapse: collapse;
box-sizing: border-box;
table-layout: fixed;
width: 100%;
font-size: 10px;
}
tr {
height: 24px;
}
td {
box-shadow: 3px -3.5px 0px -3px rgba(0,0,0,1) inset;
padding: 0;
vertical-align: top;
box-sizing: border-box;
}
.firstColumn {
width: 24px;
border-right: 1px solid black;
}
td.small {
width: 12px;
border-right: 1px solid black;
}
.title {
flex-grow: 1;
display: block;
text-overflow: ellipsis;
overflow: hidden;
height: 24px;
}
.innerTable td {
border-bottom: 0;
border-right: 0;
width: auto;
}
td.itemCell {
background: lightblue;
}
.itemCell {
position: relative;
}
.innerTable td.blockCell {
box-shadow: 3px -3.5px 0px -3px rgba(0,0,0,1) inset;
}
<html>
<head>
</head>
<body>
<table class="outerTable">
<tr>
<td rowspan="2" class="firstColumn">0</td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td rowspan="3" class="itemBlock">
<table class="innerTable">
<tr>
<td rowspan="3" class="itemCell">
<div class="item">
<div class="title">some content</div>
</div>
</td>
<td class="blockCell"></td>
</tr>
<tr>
<td class="itemCell blockCell">
<div class="item">
<div class="title">other content</div>
</div>
</td>
</tr>
<tr>
<td>
</td>
</tr>
</table>
</td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td rowspan="2" class="firstColumn">1</td>
<td></td>
<td class="small"></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td rowspan="2" class="firstColumn">2</td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
</table>
</body>
<html>
Upvotes: 4
Reputation: 15349
As I have already mentioned as a comment, first of all ensure that the browser isn't zoomed-in so that you have accurate results.
If you carefully notice the rows where all cells are single, you see that each table cell has a total height of 24px - 23px of the cell plus 1px of the the border.
The table cells next to the table-block, have a height of 24.333px, this is due to the fact that there are 2px missing from the borders.
So, the total height of the cell that holds the table item should be 24*3=72px+1px
border, giving a total of 73px. Now divide this by 3 (the rowspan) and you can see that each table cell next to the merged one equal to 24.333px
(73/3)
. This is simply the outcome of the observation.
The thing with tables it that they sometimes render in an arbitrary way, so you can't really predict the rendered result. I am sure there is a way to prevent it, in this particular example I would set margin-bottom:-1px
to the table.innertable
.
table {
border-collapse: collapse;
box-sizing: border-box;
table-layout: fixed;
width: 100%;
font-size: 10px;
}
tr {
height: 24px;
}
td {
border-bottom: 1px solid black;
padding: 0;
vertical-align: top;
box-sizing: border-box;
}
.firstColumn {
width: 24px;
border-right: 1px solid black;
}
td.small {
width: 12px;
border-right: 1px solid black;
}
.title {
flex-grow: 1;
display: block;
text-overflow: ellipsis;
overflow: hidden;
height: 24px;
}
.item {
display: flex;
background-color: lightblue;
padding-left: 4px;
padding-right: 4px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin-bottom: 1px;
height: 100%;
}
.innerTable td {
border-bottom: 0;
border-right: 0;
width: auto;
}
.itemCell {
position: relative;
}
.innerTable td.blockCell {
border-bottom: 1px solid black;
}
table.innerTable {
margin-bottom:-1px;
}
<html>
<head>
</head>
<body>
<table class="outerTable">
<tr>
<td rowspan="2" class="firstColumn">0</td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td rowspan="3" class="itemBlock">
<table class="innerTable">
<tr>
<td rowspan="3" class="itemCell">
<div class="item">
<div class="title">some content</div>
</div>
</td>
<td class="blockCell"></td>
</tr>
<tr>
<td class="itemCell blockCell">
<div class="item">
<div class="title">other content</div>
</div>
</td>
</tr>
<tr>
<td>
</td>
</tr>
</table>
</td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td rowspan="2" class="firstColumn">1</td>
<td></td>
<td class="small"></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td rowspan="2" class="firstColumn">2</td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
</table>
</body>
</html>
Upvotes: -2
Reputation: 74
table {
border-collapse: collapse;
box-sizing: border-box;
table-layout: fixed;
width: 100%;
font-size: 10px;
}
tr {
height: 24px;
}
td {
box-shadow: 3px -3.5px 0px -3px rgba(0,0,0,1) inset;
padding: 0;
vertical-align: top;
box-sizing: border-box;
}
.firstColumn {
width: 24px;
border-right: 1px solid black;
}
td.small {
width: 12px;
border-right: 1px solid black;
}
.title {
flex-grow: 1;
display: block;
text-overflow: ellipsis;
overflow: hidden;
height: 24px;
}
.item {
display: flex;
background-color: lightblue;
padding-left: 4px;
padding-right: 4px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin-bottom: 1px;
}
.innerTable td {
border-bottom: 0;
border-right: 0;
width: auto;
}
.itemCell {
position: relative;
}
.innerTable td.blockCell {
box-shadow: 3px -3.5px 0px -3px rgba(0,0,0,1) inset;
}
<html>
<head>
</head>
<body>
<table class="outerTable">
<tr>
<td rowspan="2" class="firstColumn">0</td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td rowspan="3" class="itemBlock">
<table class="innerTable">
<tr>
<td rowspan="3" class="itemCell">
<div class="item">
<div class="title">some content</div>
</div>
</td>
<td class="blockCell"></td>
</tr>
<tr>
<td class="itemCell blockCell">
<div class="item">
<div class="title">other content</div>
</div>
</td>
</tr>
<tr>
<td>
</td>
</tr>
</table>
</td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td rowspan="2" class="firstColumn">1</td>
<td></td>
<td class="small"></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td rowspan="2" class="firstColumn">2</td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
<tr>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
<td></td>
<td class="small"></td>
</tr>
</table>
</body>
<html>
Upvotes: 3