6

I'm implementing SLDS table in lightning component where you load more data on vertical scroll and it would be nice to have headers fixed. The code that I'm using is pretty much as in the slds docs:

<div class="scrollable">
    <table class="slds-table slds-table_bordered slds-table_cell-buffer">                
        <thead>
            <tr class="slds-text-title_caps">
                ...
            </tr>
        </thead>     
        <tbody aura:id="tBody">

            ...

        </tbody>
    </table>
<div>

But I was not able to find any good solution for fixed headers as there looks to be nothing about it in slds defined classes, also was trying to implement this using custom css like this one https://jsfiddle.net/dPixie/byB9d/3/ where you have relative wrapper and absolute divs but was not able to adjust it for slds probably because slds has a lot of styles defined.

Also you can't just make tbody scrollable because for this you`ll need to change it's display to block which will also ruin the slds styling:(

Anyone knows a good solution for that(ideally without javascript)?

  • I'm also looking for something of that sort. Hopefully lightning:dataTable with the real datatable like functionality will be up by Winter '18 as I just saw in a roadmap somewhere. As of now, if you want fixed header, then you probably would have to split the table into two separate table and implement the fixed header functionality. (In the mean time I would suggest you to go with datatable as it's Locker Service compatible, you have a fixedHeader property in-built in it.) – SE_User Jul 11 '17 at 9:46
  • @SE_User sorry but I'm not sure about what datatable are you talking about? I'm creating this in a lightning component, forgot to mention this. – Oles Malkov Jul 11 '17 at 10:12
  • 1
    lightningdatatable is something similar to like lightning:tabset which would be coming in Winter '18 release as per their roadmap.[Hopefully, there would be native SF functionalities like sorting, fixed header and all..] For time being you may use :jQuery datatable which is Locker Service compatible. (There's an in-built fixedHeader feature for jQuery datatable) – SE_User Jul 11 '17 at 10:22
8

The SLDS table header row can be fixed using standard classes. There are two classes that are important slds-table–header-fixed_container and slds-cell-fixed and i created a working example on github please refer this link for sample code Github link

The detailed explanation is on link SLDS framework data-table with fixed header without javascript

Edited to provide code and explanation: The slds-table--header-fixed_container class is not documented in SLDS framework, it provides some padding to the table container and relative position. The slds-cell-fixed class is used inside th element it provides absolute position to table header and also responsible for giving top:0 within that container.

The sample code is

<div class="slds-table--header-fixed_container" style="height:450px;">
    <div class="slds-scrollable_y" style="height:100%;">
            <table class="slds-table slds-table_bordered slds-table--header-fixed">
                <thead>
                    <tr class="slds-text-title_caps">
                        <th scope="col">
                            <div class="slds-truncate slds-cell-fixed" title="Opportunity Name">Opportunity Name</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate slds-cell-fixed" title="Account Name">Account Name</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate slds-cell-fixed" title="Close Date">Close Date</div>
                        </th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                      <th scope="row" data-label="Opportunity Name">
                        <div class="slds-truncate" title="Cloudhub"><a href="javascript:void(0);">Cloudhub</a></div>
                      </th>
                      <td data-label="Account Name">
                        <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                      </td>
                      <td data-label="Close Date">
                        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                      </td>

                    </tr>
                    <tr>
                      <th scope="row" data-label="Opportunity Name">
                        <div class="slds-truncate" title="Cloudhub + Anypoint Connectors"><a href="javascript:void(0);">Cloudhub + Anypoint Connectors</a></div>
                      </th>
                      <td data-label="Account Name">
                        <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                      </td>
                      <td data-label="Close Date">
                        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                      </td>

                    </tr>
                     <tr>
                      <th scope="row" data-label="Opportunity Name">
                        <div class="slds-truncate" title="Cloudhub"><a href="javascript:void(0);">Cloudhub</a></div>
                      </th>
                      <td data-label="Account Name">
                        <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                      </td>
                      <td data-label="Close Date">
                        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                      </td>

                    </tr>
                    <tr>
                      <th scope="row" data-label="Opportunity Name">
                        <div class="slds-truncate" title="Cloudhub + Anypoint Connectors"><a href="javascript:void(0);">Cloudhub + Anypoint Connectors</a></div>
                      </th>
                      <td data-label="Account Name">
                        <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                      </td>
                      <td data-label="Close Date">
                        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                      </td>

                    </tr>
                     <tr>
                      <th scope="row" data-label="Opportunity Name">
                        <div class="slds-truncate" title="Cloudhub"><a href="javascript:void(0);">Cloudhub</a></div>
                      </th>
                      <td data-label="Account Name">
                        <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                      </td>
                      <td data-label="Close Date">
                        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                      </td>

                    </tr>
                    <tr>
                      <th scope="row" data-label="Opportunity Name">
                        <div class="slds-truncate" title="Cloudhub + Anypoint Connectors"><a href="javascript:void(0);">Cloudhub + Anypoint Connectors</a></div>
                      </th>
                      <td data-label="Account Name">
                        <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                      </td>
                      <td data-label="Close Date">
                        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                      </td>

                    </tr>
                     <tr>
                      <th scope="row" data-label="Opportunity Name">
                        <div class="slds-truncate" title="Cloudhub"><a href="javascript:void(0);">Cloudhub</a></div>
                      </th>
                      <td data-label="Account Name">
                        <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                      </td>
                      <td data-label="Close Date">
                        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                      </td>

                    </tr>
                    <tr>
                      <th scope="row" data-label="Opportunity Name">
                        <div class="slds-truncate" title="Cloudhub + Anypoint Connectors"><a href="javascript:void(0);">Cloudhub + Anypoint Connectors</a></div>
                      </th>
                      <td data-label="Account Name">
                        <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                      </td>
                      <td data-label="Close Date">
                        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                      </td>

                    </tr>
                     <tr>
                      <th scope="row" data-label="Opportunity Name">
                        <div class="slds-truncate" title="Cloudhub"><a href="javascript:void(0);">Cloudhub</a></div>
                      </th>
                      <td data-label="Account Name">
                        <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                      </td>
                      <td data-label="Close Date">
                        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                      </td>

                    </tr>
                    <tr>
                      <th scope="row" data-label="Opportunity Name">
                        <div class="slds-truncate" title="Cloudhub + Anypoint Connectors"><a href="javascript:void(0);">Cloudhub + Anypoint Connectors</a></div>
                      </th>
                      <td data-label="Account Name">
                        <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                      </td>
                      <td data-label="Close Date">
                        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                      </td>

                    </tr>
                     <tr>
                      <th scope="row" data-label="Opportunity Name">
                        <div class="slds-truncate" title="Cloudhub"><a href="javascript:void(0);">Cloudhub</a></div>
                      </th>
                      <td data-label="Account Name">
                        <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                      </td>
                      <td data-label="Close Date">
                        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                      </td>

                    </tr>
                    <tr>
                      <th scope="row" data-label="Opportunity Name">
                        <div class="slds-truncate" title="Cloudhub + Anypoint Connectors"><a href="javascript:void(0);">Cloudhub + Anypoint Connectors</a></div>
                      </th>
                      <td data-label="Account Name">
                        <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                      </td>
                      <td data-label="Close Date">
                        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                      </td>

                    </tr>
                     <tr>
                      <th scope="row" data-label="Opportunity Name">
                        <div class="slds-truncate" title="Cloudhub"><a href="javascript:void(0);">Cloudhub</a></div>
                      </th>
                      <td data-label="Account Name">
                        <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                      </td>
                      <td data-label="Close Date">
                        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                      </td>

                    </tr>
                    <tr>
                      <th scope="row" data-label="Opportunity Name">
                        <div class="slds-truncate" title="Cloudhub + Anypoint Connectors"><a href="javascript:void(0);">Cloudhub + Anypoint Connectors</a></div>
                      </th>
                      <td data-label="Account Name">
                        <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                      </td>
                      <td data-label="Close Date">
                        <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                      </td>

                    </tr>
                    <tr>
                        <th scope="row" data-label="Opportunity Name">
                            <div class="slds-truncate" title="Cloudhub"><a href="javascript:void(0);">Cloudhub</a></div>
                        </th>
                        <td data-label="Account Name">
                            <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                        </td>
                        <td data-label="Close Date">
                            <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                        </td>

                    </tr>
                    <tr>
                        <th scope="row" data-label="Opportunity Name">
                            <div class="slds-truncate" title="Cloudhub + Anypoint Connectors"><a href="javascript:void(0);">Cloudhub + Anypoint Connectors</a></div>
                        </th>
                        <td data-label="Account Name">
                            <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                        </td>
                        <td data-label="Close Date">
                            <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                        </td>

                    </tr>
                    <tr>
                        <th scope="row" data-label="Opportunity Name">
                            <div class="slds-truncate" title="Cloudhub"><a href="javascript:void(0);">Cloudhub</a></div>
                        </th>
                        <td data-label="Account Name">
                            <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                        </td>
                        <td data-label="Close Date">
                            <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                        </td>

                    </tr>
                    <tr>
                        <th scope="row" data-label="Opportunity Name">
                            <div class="slds-truncate" title="Cloudhub + Anypoint Connectors"><a href="javascript:void(0);">Cloudhub + Anypoint Connectors</a></div>
                        </th>
                        <td data-label="Account Name">
                            <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                        </td>
                        <td data-label="Close Date">
                            <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                        </td>

                    </tr>
                     <tr>
                        <th scope="row" data-label="Opportunity Name">
                            <div class="slds-truncate" title="Cloudhub"><a href="javascript:void(0);">Cloudhub</a></div>
                        </th>
                        <td data-label="Account Name">
                            <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                        </td>
                        <td data-label="Close Date">
                            <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row" data-label="Opportunity Name">
                            <div class="slds-truncate" title="Cloudhub + Anypoint Connectors"><a href="javascript:void(0);">Cloudhub + Anypoint Connectors</a></div>
                        </th>
                        <td data-label="Account Name">
                            <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                        </td>
                        <td data-label="Close Date">
                            <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                        </td>
                    </tr>
                     <tr>
                        <th scope="row" data-label="Opportunity Name">
                            <div class="slds-truncate" title="Cloudhub"><a href="javascript:void(0);">Cloudhub</a></div>
                        </th>
                        <td data-label="Account Name">
                            <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                        </td>
                        <td data-label="Close Date">
                            <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row" data-label="Opportunity Name">
                            <div class="slds-truncate" title="Cloudhub + Anypoint Connectors"><a href="javascript:void(0);">Cloudhub + Anypoint Connectors</a></div>
                        </th>
                        <td data-label="Account Name">
                            <div class="slds-truncate" title="Cloudhub">Cloudhub</div>
                        </td>
                        <td data-label="Close Date">
                            <div class="slds-truncate" title="4/14/2015">4/14/2015</div>
                        </td>
                    </tr>
                </tbody>
            </table>


    </div>
</div>

Hope this will help @glls

  • Please provide a resume of your detailed explanation, as links are bound to break/expire. As is, this does not provide an answer. Thanks! – glls Aug 18 '17 at 19:07
  • Code details updated..... @glls – kanwalpreet singh Aug 19 '17 at 15:29
  • This is great. But it is not working if I specify column widths. May be I am doing something wrong.. – javanoob Apr 3 '18 at 2:11
2

I based this off of the LEX source for reports ;) :

helper:

 handleScroll : function(cmp) {


        //var thePage = cmp.getElement().getBoundingClientRect();
        var tables = cmp.find('table');
        if($A.util.isArray(tables)){
            for(var i=0; i < tables.length; i++){

                var theTable = tables[i].getElement().getBoundingClientRect();
                var difference = 0 - theTable.top;
                cmp.find('headerRow')[i].getElement().style.transform = 0 < difference ? "translateY(" + difference + "px)" : "initial";
            }
        }else{
            var theTable = tables.getElement().getBoundingClientRect();
            var difference = 0 - theTable.top;
            cmp.find('headerRow').getElement().style.transform = 0 < difference ? "translateY(" + difference + "px)" : "initial";
        }
    }

renderer:

afterRender : function(cmp, helper){

        this.superAfterRender();

    var makeOnScroll = function(c, h){
        return function(e){
            h.handleScroll(c);
        };
    }
    //CAREFUL this works only with 1 cmp of this type alive at once
    helper.scrolly = makeOnScroll(cmp, helper);
    window.addEventListener("scroll", helper.scrolly);



},
unrender : function(cmp, helper){
    window.removeEventListener("scroll", helper.scrolly);

    this.superUnrender();
}
  • Thanks for your answer, but will wait for pure css solution. – Oles Malkov Jul 13 '17 at 8:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.