Search code examples
htmlcssbootstrap-4tapestry

table header and body are not aligned correctly when trying to freeze header


My task is to make the header visible when scrolling down.
I have found a way to do that by using display:block; in my css for the body.
Now the problem, that I have, is the columns of the header are not aligned with the columns in the body.
I tried many things, but I haven't found a way to solve my problem.
I use bootstrap (For username, ..., user function col-xs-12 col-lg-2 col-xl-2; for last login, ..., action col-xs-12 col-lg-2 col-xl-1).
This is what I have now in my css.

Oh and it would be very nice, when the table would fill to the scrollbar.

<div class="container">
            <t:grid
                source="users"
                class="table list-user thead-inverse table-hover"
                inplace="true"
                cellDecorators="cellDecorator"
                rowDecorators="rowDecorator"
                t:mixins="GridDecorator"
                model="modelUserList"
                row="user"
                pagerPosition="both"
                renderTableIfEmpty="true">
                <p:inventoryCell> 
                    ${inventoryString}
                </p:inventoryCell>
                <p:actionsCell>
                    <t:actionlink
                        t:id="editUser"
                        context="user.id"
                        t:zone="userEditZone">
                        <i class="icon-md ion-android-settings" />
                    </t:actionlink>
                    <t:if test="notSelf">
                        <t:actionlink
                            t:id="deleteUser"
                            t:mixins="confirm"
                            t:message="Are you sure you want to delete ${user.fullname}?" page="index"
                            context="user.id">
                            <i class="icon-md ion-trash-b" />
                        </t:actionlink>
                    </t:if>
                </p:actionsCell>
                <p:lastloginCell>${lastlogin}</p:lastloginCell>
            </t:grid>
        </div>


#userlist table .row
{
    margin-right: 0rem;
    margin-left: 0rem;
    table-layout:fixed; 
    text-overflow: ellipsis;

/*  flex-wrap:unset;*/
}

#userlist thead {
    display: inline;
}

#userlist tbody {
    display: block;
    height: 44.25rem;
    overflow: auto;
}
#userlist table .row td {
    word-break: break-all;
    border: none;
}
#userlist table .row th, #bestandlist table .row th {
    border: none;
    text-overflow: ellipsis;

}


<div data-container-type="zone">
   <table class="table list-user thead-inverse table-hover">
      <thead>
         <tr class="row hidden-md-down" data-inplace-grid-links="true">
            <th class="col-xs-12 col-lg-2 col-xl-2" data-grid-column="first" data-grid-column-sort="sortable" data-grid-property="username"></th>
            <th class="col-xs-12 col-lg-2 col-xl-2" data-grid-column-sort="sortable" data-grid-property="email"></th>
            <th class="col-xs-12 col-lg-2 col-xl-2" data-grid-column-sort="sortable" data-grid-property="userFunction"></th>
            <th class="col-xs-12 col-lg-2 col-xl-1" data-grid-column-sort="sortable" data-grid-property="lastLogin"></th>
            <th class="col-xs-12 col-lg-1 col-xl-1" data-grid-column-sort="sortable" data-grid-property=""></th>
            <th class="col-xs-12 col-lg-1 col-xl-1" data-grid-column-sort="sortable" data-grid-property=""></th>
            <th class="col-xs-12 col-lg-1 col-xl-1" data-grid-column-sort="sortable" data-grid-property=""></th>
            <th class="col-xs-12 col-lg-1 col-xl-1" data-grid-column-sort="sortable" data-grid-property=""></th>
            <th class="col-xs-12 col-lg-1 col-xl-1" data-grid-column-sort="sortable" data-grid-property=""></th>
            <th class="col-xs-12 col-lg-1 col-xl-1" data-grid-column-sort="sortable" data-grid-property=""></th>
            <th class="col-xs-12 col-lg-1 col-xl-1" data-grid-column-sort="sortable" data-grid-property=""></th>
            <th class="col-xs-12 col-lg-1 col-xl-1" data-grid-column-sort="sortable" data-grid-property=""></th>
            <th class="col-xs-12 col-lg-1 col-xl-1" data-grid-column="last" data-grid-property="actions">Actions</th>
         </tr>
      </thead>
      <tbody>
         <tr class="row" data-grid-row="first">
            <td class="col-xs-12 col-lg-2 col-xl-2" data-grid-property="username"></td>
            <td class="col-xs-12 col-lg-2 col-xl-2" data-grid-property="email"></td>
            <td class="col-xs-12 col-lg-2 col-xl-2" data-grid-property="userFunction"></td>
            <td class="col-xs-12 col-lg-2 col-xl-1" data-grid-property="lastLogin">&nbsp;</td>
            <td class="col-xs-12 col-lg-1 col-xl-1" data-grid-property=""></td>
            <td class="col-xs-12 col-lg-1 col-xl-1" data-grid-property=""></td>
            <td class="col-xs-12 col-lg-1 col-xl-1" data-grid-property=""></td>
            <td class="col-xs-12 col-lg-1 col-xl-1" data-grid-property=""></td>
            <td class="col-xs-12 col-lg-1 col-xl-1" data-grid-property=""></td>
            <td class="col-xs-12 col-lg-1 col-xl-1" data-grid-property=""></td>
            <td class="col-xs-12 col-lg-1 col-xl-1" data-grid-property=""></td>
            <td class="col-xs-12 col-lg-1 col-xl-1" data-grid-property=""></td>
            <td class="col-xs-12 col-lg-1 col-xl-1" data-grid-property="actions"></td>
         </tr>
      </tbody>
   </table>
</div>

table header must be visible when scrolling down

html code


Solution

  • I did a little bit of testing with your code and Bootstrap 3.3.7 (because the classes you are using aren't Bootstrap 4, those are Bootstrap 3 classes). And the main reason I wanted to do a bit of testing is because I'm not as familiar with Bootstrap 3 as I am with Bootstrap 4.

    Anyway, when using your code and Bootstrap 3, the table header and the body columns are perfectly aligned in my case. I'm saying "in my case" because I had to use some dummy data since you didn't provide any actual table data. And I hope you understand that you do need to put some content into a table to be able to see anything in terms of alignment etc.

    Now, while the alignment looks OK with your code, my dummy table data and Bootstrap 3, I do have to say that you are using some Bootstrap classes incorrectly.

    You see, the Bootstrap row class and the col classes are NOT designed to be used with HTML tables! It kinda works (sort of) in this case but that's more of an accident than anything else. You are not supposed to use the row and the col classes for any elements of an HTML table. HTML tables are sort of an animal of their own and while Bootstrap does provide a bit of nice styling for HTML tables it does NOT make them responsive the same way it does normal divs etc.

    The only "responsiveness" that Bootstrap can add to an HTML table is a horizontal scrollbar at the bottom of the table. That's it! In other words, instead of breaking your layout a "responsive" Bootstrap HTML table gets a sort of an iframe kind of thing. And that isn't just Bootstrap because doing this sort of thing is the only thing you can really do with an HTML table. A table is meant for tabular data. So, it's impossible to manipulate the individual table cells the same way Bootstrap can manipulate divs. That would destroy the entire table.

    I don't know how much sense you can make of what I said here. Feel free to ask for clarification.