When comparing grid mode to row mode in a rendered table, it's evident that the elements are not organized in the same way. In row mode, inspecting the DOM structure reveals a standard table with a header and body.
<div
class="q-table__container q-table--horizontal-separator column no-wrap q-table__card q-table--no-wrap my-sticky-header-table"
>
<div class="q-table__top relative-position row items-center">...</div>
<div
class="q-table__middle q-virtual-scroll q-virtual-scroll--vertical scroll"
>
<table class="q-table">
<!-- table header -->
<thead>
<tr>
<th class="text-left sortable">...</th>
<th class="text-center sortable">...</th>
<th class="text-right sortable">...</th>
<th class="text-right">Carbs (g)</th>
</tr>
</thead>
<!-- table content -->
<tbody class="q-virtual-scroll__padding">...</tbody>
<tbody class="q-virtual-scroll__content" tabindex="-1">...</tbody>
<tbody class="q-virtual-scroll__padding">...</tbody>
</table>
</div>
</div>
To achieve a sticky header row in row mode, apply position: sticky; top: 0;
to the <th>
elements as follows:
thead tr th
position: sticky
z-index: 1
thead tr:first-child th
top: 0
On the other hand, in grid mode, the elements are not structured within a <table>
. Instead, they are positioned separately from the header information.
<div
class="q-table__container q-table--horizontal-separator column no-wrap q-table--grid q-table--no-wrap my-sticky-header-table"
>
<div class="q-table__top relative-position row items-center">...</div>
<div class="q-table__middle">
<table class="q-table">
<!-- table header -->
<thead>
<tr>
<th class="text-left sortable">...</th>
<th class="text-center sortable">...</th>
<th class="text-right sortable">...</th>
<th class="text-right">Carbs (g)</th>
</tr>
</thead>
</table>
</div>
<!-- grid content -->
<div class="q-table__grid-content row">
<div class="q-table__grid-item col-xs-12 col-sm-6 col-md-4 col-lg-3">...</div>
<div class="q-table__grid-item col-xs-12 col-sm-6 col-md-4 col-lg-3">...</div>
<div class="q-table__grid-item col-xs-12 col-sm-6 col-md-4 col-lg-3">...</div>
<div class="q-table__grid-item col-xs-12 col-sm-6 col-md-4 col-lg-3">...</div>
...
</div>
</div>
In this case, even though there is a <table>
, it only contains the header details, separate from the grid content. Therefore, applying overflow: auto
and setting a height to the grid content will keep the header fixed on top while allowing for scrollbar functionality.
.q-table__grid-content
height: 310px
overflow: auto
For a visual demonstration, you can check out this working sandbox example.