ブラウザの幅が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);
}
});
}
});





