Why CSS transform translate leaves border of table row where it was?

The problem is caused by a rule that comes from Bootstrap's normalize.css:

table { border-collapse: collapse; }

If you overwrite that, transforming works:

body {
    padding: 20px;
    box-sizing: border-box;
}
table {
    width: 300px;
    border-collapse: separate !important;
}
thead tr {
    background-color: #eee;
    border: 1px solid blue !important;
    transform: translateY(23px);
}
thead tr th {
    border: 1px solid blue !important;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<table class="table table-bordered" >
    <thead>
        <tr>
            <th>asdasd</th>
            <th>asdasd</th>
            <th>asdasd</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
    </tbody>
</table>

The issue is because bootstrap apply to the table this border-collapse: collapse; which means:

The border-collapse CSS property specifies whether cells inside a table have shared or separate borders.ref

And collapse mean shared border. In other words the border no more belong to the translated element and that's why they are not moving when translating:


In order to fix it you may change the value to separate.

body {
    padding: 20px;
    box-sizing: border-box;
}
table {
    width: 300px;
    border-collapse:separate!important;
}
thead tr {
    background-color: #eee;
    
}
thead tr th {
    border: 1px solid blue !important;
}


thead tr {
    background-color: #eee;
    transform: translateY(23px);
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<table class="table table-bordered" >
    <thead>
        <tr  >
            <th>asdasd</th>
            <th>asdasd</th>
            <th>asdasd</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
        <tr>
            <td>asda</td>
            <td>asda</td>
            <td>asda</td>
        </tr>
    </tbody>
</table>