Search code examples
htmlcsshtml-tablesemantic-markup

Different border spacing for different rows


Synopsis: I need to display a table like the one below:

table with different spacing between head and body

Necessities:

  • Semantic HTML coding
  • No scripting

HTML:

<table>
<thead>
    <tr>
        <th colspan=2>
            One
        </th>
        <th colspan=2>
            Two
        </th>
    </tr>
</thead>
<tbody>
    <tr>
        <td>
            One
        </td>
        <td>
            Two
        </td>
        <td>
            Three
        </td>
        <td>
            Four
        </td>
    </tr>
    <tr>
        <td>
            One
        </td>
        <td>
            Two
        </td>
        <td>
            Three
        </td>
        <td>
            Four
        </td>
    </tr>
<tbody>
</table>

First attempt:

"border-collapse attribute"

I tried border-collapse: separate; on thead and border-collapse: collapse; on tbody but that simply didn't work.

table {
    border-collapse: collapse;
    border-spacing: 1em;
}

table thead {
    border-collapse: separate;
}

table tbody tr {
    border-bottom: 1px solid black;
}

table thead tr th{
    border-bottom: 1px solid black;
    padding: 10px;
    text-align: center;
}

table tbody tr td {
    border-bottom: 1px solid black;
    padding: 10px;
}​

On JSFIDDLE


Second Attempt:

"Adding blank cells"

I can get the preferred look of the table by adding blank cells in HTML code. But this approach defects semantic structure.

table {
    border-collapse: collapse;
    border-spacing: 1em;
}

table tbody tr {
    border-bottom: 1px solid black;
}

table thead tr th[colspan="2"]{
    border-bottom: 1px solid black;
    padding: 10px;
    text-align: center;
}

table tbody tr td {
    border-bottom: 1px solid black;
    padding: 10px;
}​

On JSFIDDLE


Other various attemps

I also tried -webkit-border-image: -webkit-linear-gradient(left, black 95%, white 5%); on headers borders but couldn't manage to get it working.


After all I am open to new suggestions.

Note: This is going to be in an eBook file. So general background color may vary in different reader applications.


Solution

  • Depending on your compatibility requirements, you have the option of using CSS generated-content:

    th {
        /* other CSS */
        position: relative;
    }
    
    thead th::before,
    thead th::after {
        content: '';
        position: absolute;
        bottom: -1px;
        width: 0.5em;
        border-bottom: 1px solid #fff;
    }
    
    thead th::before {
        left: 0;
    }
    
    thead th::after {
        right: 0;
    }
    

    JS Fiddle demo.

    For the sake of simplicity I've given both th elements the same ::before and ::after, however if there's always only two th elements the selectors can be changed:

    th {
        /* other CSS */
        position: relative;
    }
    
    thead th:first-child::after,
    thead th:last-child::before {
        content: '';
        position: absolute;
        bottom: -1px;
        width: 0.5em;
        border-bottom: 1px solid #fff;
    }
    
    thead th:last-child::before {
        left: 0;
    }
    
    thead th:first-child::after {
        right: 0;
    }
    

    JS Fiddle demo.