0
0

htmlでスクロールを固定

Posted at

スクロールバーの幅はブラウザやOSによって異なるため、固定の値を使用するのは理想的ではありません。そのため、スクロールバーの幅を動的に取得する方法があります。以下は、スクロールバーの幅を動的に計算し、複数行のセルにも対応できるようにした例です。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>5列30行の表</title>
    <style>
        table {
            width: 100%;
            border-collapse: collapse;
        }
        th, td {
            border: 1px solid black;
            text-align: center;
            padding: 8px;
            word-wrap: break-word;
        }
        th {
            background-color: #f2f2f2;
        }
        thead, tbody {
            display: block;
        }
        tbody {
            height: 400px; /* Set the height you need */
            overflow: auto;
        }
        tr {
            display: table;
            width: 100%;
            table-layout: fixed;
        }
        .fixed-header {
            position: sticky;
            top: 0;
            background: white;
            z-index: 10;
        }
        .fixed-row {
            position: sticky;
            background: white;
            z-index: 5;
        }
    </style>
</head>
<body>

<table>
    <thead>
        <tr class="fixed-header">
            <th>列1</th>
            <th>列2</th>
            <th>列3</th>
            <th>列4</th>
            <th>列5</th>
        </tr>
        <tr class="fixed-row" id="fixed-row">
            <td>行1列1</td><td>行1列2</td><td>行1列3</td><td>行1列4</td><td>行1列5</td>
        </tr>
    </thead>
    <tbody>
        <tr><td>行2列1</td><td>行2列2</td><td>行2列3</td><td>行2列4</td><td>行2列5</td></tr>
        <tr><td>行3列1</td><td>行3列2</td><td>行3列3</td><td>行3列4</td><td>行3列5</td></tr>
        <tr><td>行4列1</td><td>行4列2</td><td>行4列3</td><td>行4列4</td><td>行4列5</td></tr>
        <tr><td>行5列1</td><td>行5列2</td><td>行5列3</td><td>行5列4</td><td>行5列5</td></tr>
        <tr><td>行6列1</td><td>行6列2</td><td>行6列3</td><td>行6列4</td><td>行6列5</td></tr>
        <tr><td>行7列1</td><td>行7列2</td><td>行7列3</td><td>行7列4</td><td>行7列5</td></tr>
        <tr><td>行8列1</td><td>行8列2</td><td>行8列3</td><td>行8列4</td><td>行8列5</td></tr>
        <tr><td>行9列1</td><td>行9列2</td><td>行9列3</td><td>行9列4</td><td>行9列5</td></tr>
        <tr><td>行10列1</td><td>行10列2</td><td>行10列3</td><td>行10列4</td><td>行10列5</td></tr>
        <tr><td>行11列1</td><td>行11列2</td><td>行11列3</td><td>行11列4</td><td>行11列5</td></tr>
        <tr><td>行12列1</td><td>行12列2</td><td>行12列3</td><td>行12列4</td><td>行12列5</td></tr>
        <tr><td>行13列1</td><td>行13列2</td><td>行13列3</td><td>行13列4</td><td>行13列5</td></tr>
        <tr><td>行14列1</td><td>行14列2</td><td>行14列3</td><td>行14列4</td><td>行14列5</td></tr>
        <tr><td>行15列1</td><td>行15列2</td><td>行15列3</td><td>行15列4</td><td>行15列5</td></tr>
        <tr><td>行16列1</td><td>行16列2</td><td>行16列3</td><td>行16列4</td><td>行16列5</td></tr>
        <tr><td>行17列1</td><td>行17列2</td><td>行17列3</td><td>行17列4</td><td>行17列5</td></tr>
        <tr><td>行18列1</td><td>行18列2</td><td>行18列3</td><td>行18列4</td><td>行18列5</td></tr>
        <tr><td>行19列1</td><td>行19列2</td><td>行19列3</td><td>行19列4</td><td>行19列5</td></tr>
        <tr><td>行20列1</td><td>行20列2</td><td>行20列3</td><td>行20列4</td><td>行20列5</td></tr>
        <tr><td>行21列1</td><td>行21列2</td><td>行21列3</td><td>行21列4</td><td>行21列5</td></tr>
        <tr><td>行22列1</td><td>行22列2</td><td>行22列3</td><td>行22列4</td><td>行22列5</td></tr>
        <tr><td>行23列1</td><td>行23列2</td><td>行23列3</td><td>行23列4</td><td>行23列5</td></tr>
        <tr><td>行24列1</td><td>行24列2</td><td>行24列3</td><td>行24列4</td><td>行24列5</td></tr>
        <tr><td>行25列1</td><td>行25列2</td><td>行25列3</td><td>行25列4</td><td>行25列5</td></tr>
        <tr><td>行26列1</td><td>行26列2</td><td>行26列3</td><td>行26列4</td><td>行26列5</td></tr>
        <tr><td>行27列1</td><td>行27列2</td><td>行27列3</td><td>行27列4</td><td>行27列5</td></tr>
        <tr><td>行28列1</td><td>行28列2</td><td>行28列3</td><td>行28列4</td><td>行28列5</td></tr>
        <tr><td>行29列1</td><td>行29列2</td><td>行29列3</td><td>行29列4</td><td>行29列5</td></tr>
        <tr><td>行30列1</td><td>行30列2</td><td>行30列3</td><td>行30列4</td><td>行30列5</td></tr>
    </tbody>
</table>

<script>
    window.addEventListener('load', function() {
        var headerHeight = document.querySelector('.fixed-header').offsetHeight;
        var fixedRow = document.querySelector('.fixed-row');
        fixedRow.style.top = headerHeight + 'px';
    });

    // Function to dynamically calculate scrollbar width
    function getScrollbarWidth() {
        var outer = document.createElement('div');
        outer.style.visibility = '

hidden';
        outer.style.overflow = 'scroll';
        outer.style.msOverflowStyle = 'scrollbar'; // Needed for WinJS apps
        document.body.appendChild(outer);

        var inner = document.createElement('div');
        outer.appendChild(inner);

        var scrollbarWidth = (outer.offsetWidth - inner.offsetWidth);

        outer.parentNode.removeChild(outer);

        return scrollbarWidth;
    }

    // Adjust the width of the thead to account for scrollbar
    window.addEventListener('load', function() {
        var thead = document.querySelector('thead');
        var scrollbarWidth = getScrollbarWidth();
        thead.style.width = `calc(100% - ${scrollbarWidth}px)`;
    });
</script>

</body>
</html>

このコードでは、以下のことを行っています:

  1. fixed-header クラスと fixed-row クラスを使って、1行目と2行目を固定。
  2. JavaScriptを使って、fixed-rowtop プロパティを動的に設定し、ヘッダーの高さに応じて位置を調整。
  3. スクロールバーの幅を動的に計算し、その幅に基づいて thead の幅を調整。

これにより、ヘッダーと2行目が複数行になっても正しく固定され、下の部分をスクロールできるようになります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0