Table fixed header and scrollable body

前端 未结 29 1257
粉色の甜心
粉色の甜心 2020-11-22 05:33

I am trying to make a table with fixed header and a scrollable content using the bootstrap 3 table. Unfortunately the solutions I have found does not work with bootstrap or

相关标签:
29条回答
  • 2020-11-22 05:46

    By far the best solution I've seen that is CSS only, with good cross browser support, and no alignment issues is this solution from codingrabbithole

    table {
      width: 100%;
    }
    thead, tbody tr {
      display: table;
      width: 100%;
      table-layout: fixed;
    }
    tbody {
      display: block;
      overflow-y: auto;
      table-layout: fixed;
      max-height: 200px;
    }
    
    0 讨论(0)
  • 2020-11-22 05:47

    An easy way without fixed width:

    .myTable tbody{
      display:block;
      overflow:auto;
      height:200px;
      width:100%;
    }
    .myTable thead tr{
      display:block;
    }
    

    Source

    Now, on onLoad, to adjust th widths, just add this jquery script:

    $.each($('.myTable tbody tr:nth(0) td'), function(k,v) {
        $('.myTable thead th:nth('+k+')').css('width', $(v).css('width'));
    });
    
    0 讨论(0)
  • 2020-11-22 05:48

    Now that “all” browsers support ES6, I’ve incorporated the various suggestions above into a JavaScript class that takes a table as an argument and makes the body scrollable. It lets the browser’s layout engine determine header and body cell widths, and then makes the column widths match each other.

    The height of a table can be set explicitly, or made to fill the remaining part of the browser window, and provides callbacks for events such as viewport resizing and/or details elements opening or closing.

    Multi-row header support is available, and is especially effective if the table uses the id/headers attributes for accessibility as specified in the WCAC Guidelines, which is not as onerous a requirement as it might seem.

    The code does not depend on any libraries, but plays nicely with them if they are being used. (Tested on pages that use JQuery).

    The code and sample usage are available on Github.

    0 讨论(0)
  • 2020-11-22 05:50

    Fixed table head - CSS-only

    Simply position: sticky; top: 0; your th elements. (Chrome, FF, Edge)

    .tableFixHead          { overflow-y: auto; height: 100px; }
    .tableFixHead thead th { position: sticky; top: 0; }
    
    /* Just common table stuff. Really. */
    table  { border-collapse: collapse; width: 100%; }
    th, td { padding: 8px 16px; }
    th     { background:#eee; }
    <div class="tableFixHead">
      <table>
        <thead>
          <tr><th>TH 1</th><th>TH 2</th></tr>
        </thead>
        <tbody>
          <tr><td>A1</td><td>A2</td></tr>
          <tr><td>B1</td><td>B2</td></tr>
          <tr><td>C1</td><td>C2</td></tr>
          <tr><td>D1</td><td>D2</td></tr>
          <tr><td>E1</td><td>E2</td></tr>
        </tbody>
      </table>
    </div>

    TH borders problem fix

    Since border cannot be painted properly on a translated TH element, to recreate and render "borders" use the box-shadow property:

    /* Borders (if you need them) */
    .tableFixHead,
    .tableFixHead td {
      box-shadow: inset 1px -1px #000;
    }
    .tableFixHead th {
      box-shadow: inset 1px 1px #000, 0 1px #000;
    }
    

    .tableFixHead          { overflow-y: auto; height: 100px; }
    .tableFixHead thead th { position: sticky; top: 0; }
    
    /* Just common table stuff. Really. */
    table  { border-collapse: collapse; width: 100%; }
    th, td { padding: 8px 16px; }
    th     { background:#eee; }
    
    /* Borders (if you need them) */
    .tableFixHead,
    .tableFixHead td {
      box-shadow: inset 1px -1px #000;
    }
    .tableFixHead th {
      box-shadow: inset 1px 1px #000, 0 1px #000;
    }
    <div class="tableFixHead">
      <table>
        <thead>
          <tr><th>TH 1</th><th>TH 2</th></tr>
        </thead>
        <tbody>
          <tr><td>A1</td><td>A2</td></tr>
          <tr><td>B1</td><td>B2</td></tr>
          <tr><td>C1</td><td>C2</td></tr>
          <tr><td>D1</td><td>D2</td></tr>
          <tr><td>E1</td><td>E2</td></tr>
        </tbody>
      </table>
    </div>


    Fixed table head - using JS. (IE)

    You can use a bit of JS and translateY the th elements

    jQuery example

    var $th = $('.tableFixHead').find('thead th')
    $('.tableFixHead').on('scroll', function() {
      $th.css('transform', 'translateY('+ this.scrollTop +'px)');
    });
    .tableFixHead { overflow-y: auto; height: 100px; }
    
    /* Just common table stuff. */
    table  { border-collapse: collapse; width: 100%; }
    th, td { padding: 8px 16px; }
    th     { background:#eee; }
    <div class="tableFixHead">
      <table>
        <thead>
          <tr><th>TH 1</th><th>TH 2</th></tr>
        </thead>
        <tbody>
          <tr><td>A1</td><td>A2</td></tr>
          <tr><td>B1</td><td>B2</td></tr>
          <tr><td>C1</td><td>C2</td></tr>
          <tr><td>D1</td><td>D2</td></tr>
          <tr><td>E1</td><td>E2</td></tr>
        </tbody>
      </table>
    </div>
    
    <script src="https://code.jquery.com/jquery-3.1.0.js"></script>

    Or plain ES6 if you prefer (no jQuery required):

    // Fix table head
    function tableFixHead (e) {
        const el = e.target,
              sT = el.scrollTop;
        el.querySelectorAll("thead th").forEach(th => 
          th.style.transform = `translateY(${sT}px)`
        );
    }
    document.querySelectorAll(".tableFixHead").forEach(el => 
        el.addEventListener("scroll", tableFixHead)
    );
    
    0 讨论(0)
  • 2020-11-22 05:51

    For tables that are full height (the page scrolls, not the table)

    Note: I move the whole <thead>...</thead> beause In my case I had two rows (Title and filters)

    With JS (jQuery)

    $( function() {
    
                let marginTop = 0; // Add margin if the page has a top nav-bar
                let $thead = $('.table-fixed-head').find('thead');
                let offset = $thead.first().offset().top - marginTop;
                let lastPos = 0;
    
                $(window).on('scroll', function () {
    
                    if ( window.scrollY > offset )
                    {
                        if ( lastPos === 0 )
                        {
                            // Add a class for styling
                            $thead.addClass('floating-header');
                        }
    
                        lastPos = window.scrollY - offset;
                        $thead.css('transform', 'translateY(' + ( lastPos ) + 'px)');
                    }
                    else if ( lastPos !== 0 )
                    {
                        lastPos = 0;
                        $thead.removeClass('floating-header');
                        $thead.css('transform', 'translateY(' + 0 + 'px)');
                    }
                });
    });
    

    CSS (Just for styling)

     thead.floating-header>tr>th {
           background-color: #efefef;
     }
    
    thead.floating-header>tr:last-child>th {
           border-bottom: 1px solid #aaa;
    }
    
    0 讨论(0)
  • 2020-11-22 05:52

    Cleaner Solution (CSS Only)

    .table-fixed tbody {
        display:block;
        height:85vh;
        overflow:auto;
    }
    .table-fixed thead, .table-fixed tbody tr {
        display:table;
        width:100%;
    }
    
    
    <table class="table table-striped table-fixed">
        <thead>
            <tr align="center">
                <th>Col 1</th>
                <th>Col 2</th>
                <th>Col 3</th>
                <th>Col 4</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Content 1</td>
                <td>Content 1</td>
                <td>Content 1</td>
                <td>Content 1</td>
            </tr>
            <tr>
                <td>Longer Content 1</td>
                <td>Longer Content 1</td>
                <td>Longer Content 1</td>
                <td>Longer Content 1</td>
            </tr>
        </tbody
    </table
    
    0 讨论(0)
提交回复
热议问题