0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

縦長のテーブルでもウィンドウ下部に横スクロールをstickyで表示する

Posted at
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Layout with Fixed Horizontal Scroll</title>

<style>
  body {
    margin: 0;
    font-family: sans-serif;
  }

  /* ============================
      1. 上部ヘッダー(sticky)
     ============================*/
  header {
    position: sticky;
    top: 0;
    height: 100px;
    background: #333;
    color: #fff;
    display: flex;
    align-items: center;
    padding-left: 20px;
    z-index: 1000;
  }

  /* ============================
      2. 左ナビ + コンテンツ
     ============================*/
  .layout {
    display: flex;
    height: calc(100vh - 100px);
  }

  .side-nav {
    width: 200px;
    background: #f4f4f4;
    border-right: 1px solid #ddd;
    padding: 20px;
    box-sizing: border-box;
    position: sticky;
    top: 100px; /* ヘッダー分 */
    height: calc(100vh - 100px);
  }

  .content {
    flex: 1;
    position: relative;
    padding: 20px;
    box-sizing: border-box;
    overflow-y: auto;
  }

  /* ============================
      3. コンテンツ内テーブル
     ============================*/
  .table-area {
    position: relative;
    padding-bottom: 20px; /* fake scrollbar 分 */
  }

  /* 実スクロール部分 */
  .real-scroll {
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
    border: 1px solid #ccc;
  }

  /* コンテンツ内で固定される横スクロールバー */
  .fake-scroll {
    position: sticky;
    bottom: -20px;
    left: 0;
    right: 0;
    height: 16px; 
    overflow-x: auto;
    overflow-y: hidden;
    background: #fff;
    transition: opacity 0.25s ease;
  }

  .fake-scroll.hide {
    opacity: 0;
    pointer-events: none;
  }

  .fake-scroll > div {
    height: 1px;
    width: 1px; /* JSで同期 */
  }

  table {
    border-collapse: collapse;
  }
  td, th {
    border: 1px solid #ccc;
    padding: 8px;
    white-space: nowrap;
  }
</style>
</head>

<body>

<header>
  HEADER(100px sticky)
</header>

<div class="layout">

  <nav class="side-nav">
    左ナビ(固定)
  </nav>

  <main class="content">
    <h2>コンテンツ</h2>

    <div class="table-area">
      <div class="real-scroll" id="real">
        <table id="big-table">
          <tbody>
            <script>
              for (let r = 0; r < 30; r++) {
                document.write("<tr>");
                for (let c = 0; c < 30; c++) {
                  document.write(`<td>R${r+1}C${c+1}</td>`);
                }
                document.write("</tr>");
              }
            </script>
          </tbody>
        </table>
      </div>

      <div class="fake-scroll" id="fake"><div></div></div>
    </div>
  </main>

</div>

<script>
  const real = document.getElementById("real");
  const fake = document.getElementById("fake");
  const fakeInner = fake.firstElementChild;

  function syncWidth() {
    fakeInner.style.width = real.scrollWidth + "px";
  }

  syncWidth();
  window.addEventListener("resize", syncWidth);

  // スクロール同期
  fake.addEventListener("scroll", () => {
    real.scrollLeft = fake.scrollLeft;
  });
  real.addEventListener("scroll", () => {
    fake.scrollLeft = real.scrollLeft;
  });
  
  const content = document.querySelector('.content');
  const fakeBar = document.querySelector('.fake-scroll');

  content.addEventListener('scroll', () => {
    const scrollBottom = content.scrollTop + content.clientHeight;
    const contentHeight = content.scrollHeight;
    if(contentHeight - scrollBottom < 40) {
        fakeBar.classList.add('hide');
    } else {
        fakeBar.classList.remove('hide')
    }
  })
</script>

</body>
</html>
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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?