Позиция липкая с несколькими рядами TH - PullRequest
0 голосов
/ 25 апреля 2020

Есть ли эффективный способ использования позиции: закрепить несколько строк?

        <table id="table-example" class="table mw-850">
        <thead>
        <tr>
            <th></th>
            <th colspan="2" class="text-center" scope="col">Checked In</th>
            <th colspan="2" class="text-center" scope="col">Checked Out</th>
        </tr>
        <tr>
            <th scope="col" style="background-color: #fdfdfe;">Action</th>
            <th class="text-center" scope="col">Email</th>
            <th class="text-center" scope="col">Event</th>
            <th class="text-center" scope="col">Email</th>
            <th class="text-center" scope="col">Event</th>
        </tr>
        </thead>
        <tbody>

        ...

И CSS

.table thead th {
    position: sticky !important;
    top: -1px !important;
    z-index: 1;
}

Когда я прокручиваю, разваливаются друг на друга.

1 Ответ

1 голос
/ 25 апреля 2020

К сожалению, в CSS нет встроенного способа, который бы правильно обрабатывал «position: sticky, но относительно другого sticky элемента», поэтому, когда мне нужно было сделать то же самое ранее в этом месяце, я использовал ResizeObserver в скрипт для настройки смещения top: во второй строке.

К счастью, его довольно просто использовать:

window.addEventListener( 'DOMContentLoaded', setUpStickyHeaders );

function setUpStickyHeaders() {

    if( typeof window.ResizeObserver !== 'function' ) return;

    const headerFirstRow = document.querySelector( 'table > thead > tr:first-child' );

    const headerSecondRowCells = document.querySelectorAll( 'table > thead > tr:not(:first-child) > th' );

    function onHeaderFirstRowResize( entries, observer ) {        

        for( const entry of entries ) {
            if( entry !== headerFirstRow ) continue;

            const firstRowBottom = entry.contentRect.bottom;

            for( const th of headerSecondRowCells ) {
                th.style.top = firstRowBottom.toString() + 'px'; // I find I often have to add a few extra px here for it to look good though.
            }
        }
    }

    const ro = new ResizeObserver( onHeaderFirstRowResize );
    ro.observe( headerFirstRow );
}

Это поддерживается всеми основными браузерами, кроме IE11 (конечно ) и Safari (как MacOS Safari, так и iOS Safari), которые в настоящее время не поддерживают ResizeObserver , но есть хороший доступный полифил, который безупречно работает для меня .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...