2021.03.03

HTML・CSS

tableの横スクロール時にタッチデバイスでアニメーション表示

ブラウザの幅がtableの幅よりも狭くなった時に、CSSのoverflow-xを利用して横スクロールでtableを表示します。ただしiOS13以降safariではスクロールバーが表示されないため、iPhoneやiPadでは横スクロールを促すアニメーションを表示します。
デモページはこちら

以下のhtmlでテストします。tableタグは2つのdivタグで囲みます。

<div class="c-scroll-x-wrap">
  <div class="c-scroll-x">
    <table class="c-table">
      <thead>
        <tr>
          <th>タイトル01</th>
          <th>タイトル02</th>
          <th>タイトル03</th>
          <th>タイトル04</th>
          <th>タイトル05</th>
          <th>タイトル06</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>データ01</td>
          <td>データ02</td>
          <td>データ03</td>
          <td>データ04</td>
          <td>データ05</td>
          <td>データ06</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

CSSのコードです。
アニメーション用のsvgをposition: absolute;で配置する関係で、tableを囲む一番外側のdivにposition: relative;を指定します。そしてその内側のdivに横スクロール用のoverflow-x: auto;とtable内のテキストを改行させないためにwhite-space: nowrap;を指定します。
アニメーションのCSSは@media (hover: none)内に記述して、hoverを利用できないタッチデバイスを対象とします。クラス名-scrollableが付与された時にアニメーションを実行し、クラス名-scrolledが付与された時にアニメーションを停止します。このクラス名はjsで判定して付与します。

.c-scroll-x-wrap {
  position: relative;
  max-width: 100%;
  max-height: 100%;
}
.c-scroll-x {
  overflow-x: auto;
  max-width: 100%;
  white-space: nowrap;
}
.c-table {
  width: 100%;
  border: 1px solid rgba(79, 79, 79, 0.5);
}
.c-table th,
.c-table td {
  padding: 15px 30px;
  border-right: 1px solid rgba(79, 79, 79, 0.5);
  border-bottom: 1px solid rgba(79, 79, 79, 0.5);
  font-size: 15px;
  font-size: 1.5rem;
  line-height: 2;
  vertical-align: middle;
  letter-spacing: 0.2rem;
}
.c-table th {
  background: #ede8e2;
}
.c-table td {
  text-align: center;
}
@media screen and (max-width: 767px) {
  .c-table th,
  .c-table td {
    padding: 10px;
    font-size: 13px;
    font-size: 1.3rem;
  }
}
@media (hover: none) {
  .c-scroll-x.-scrollable {
    padding-bottom: 15px;
  }
  .c-scroll-x.-scrollable::after {
    position: absolute;
    z-index: 1;
    right: 10px;
    bottom: 0;
    display: inline-block;
    width: 50px;
    height: 20px;
    background: url("../images/slide_arr_right.svg") no-repeat 0 0;
    background-size: 50px auto;
    pointer-events: none;
    content: "";
    opacity: 0;
    animation-name: scrollable-x;
    animation-duration: 2.8s;
    animation-timing-function: ease;
    animation-iteration-count: infinite;
    animation-fill-mode: none;
  }
  .c-scroll-x.-scrolled::after {
    animation-name: none;
  }
}
@keyframes scrollable-x {
  0% {
    opacity: 0;
    transform: translateX(-50px);
  }
  33% {
    opacity: 0;
    transform: translateX(-50px);
  }
  66% {
    opacity: 1;
    transform: translateX(0);
  }
  90% {
    opacity: 1;
    transform: translateX(0);
  }
  100% {
    opacity: 0;
    transform: translateX(0);
  }
}
::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
::-webkit-scrollbar-track {
  border-radius: 3px;
  background: #d3d3d3;
}
::-webkit-scrollbar-thumb {
  border-radius: 3px;
  background: #6c6c6c;
}

最後にJavaScriptのコードです。ページ読み込み時とブラウザリサイズ時の動作になります。
クラス名-scrollableは横スクロールが発生した時に付与し、横スクロールが解除された時は削除します。クラス名-scrolledは最後まで横スクロールした時に付与し、最後まで横スクロールしていない時は削除します。

//scrollable animation
$(window).on('load resize', function() {
  const class_x = '.c-scroll-x';
  const class_able = '-scrollable';
  const class_done = '-scrolled';

  //横スクロール判定
  if(document.querySelector(class_x)) {
    const lists = document.body.querySelectorAll(class_x);
    const list = Array.prototype.slice.call(lists,0); //IE用の処理

    list.forEach(function(item) {
      if ( item.scrollWidth - item.clientWidth > 10 ) {
        item.classList.add(class_able);

        // スマホではスクロールの開始点が異なる
        let is_count_start_left = (item.scrollLeft > 0) ? 1 : 0;

        //現在のスクロール量
        item.addEventListener('scroll', function() {
          let scroll_x = (is_count_start_left) ? item.scrollLeft : item.scrollWidth - (item.clientWidth + item.scrollLeft);

          if(scroll_x < 10) {
            item.classList.add(class_done);
          } else {
            item.classList.remove(class_done);
          }
        });
      } else {
        item.classList.remove(class_able);
      }
    });
  }
});

関連記事

2020.08.19

HTML・CSS

iOS Safariのツールバーと表示エリアの挙動

iOS Safariで表示される画面下部のツールバーは、下にスクロールすると非表示になります。正確には上部のアドレスバーが小さくなり、下部のツールバーが消えます…

2021.02.02

HTML・CSS

flex-growプロパティを利用した横並びのリスト

flex-growプロパティを利用して、左右にボーダーのある横並びのリストを作ります。リスト内のテキストの文字数が異なる場合でも、簡単にレスポンシブ対応できます…

2025.08.08

HTML・CSS

fit-contentのセンタリングを利用した横幅可変のグラデーション背景

width: fit-contentを利用してテキストをセンタリングし、グラデーションの背景を表示します。デモページはこちら 以下のhtml構造で確認します。d…

2020.10.03

HTML・CSS

WAI-ARIAのaria-current属性で現在位置を指定

デモページはこちら ナビゲーションメニューにWAI-ARIAのaria-current属性で現在位置を指定します。jQueryでページのURLを判別し、対象のa…

2021.09.13

HTML・CSS

nth-childとlast-childの複合条件

デモページはこちら 3カラムで複数行のコンテンツの両側にCSSで角丸を設定します。コンテンツ数は可変の前提で、部分的に2カラムや1カラムになった時のパターンも考…

上に戻る