47
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

NIJIBOXAdvent Calendar 2020

Day 11

ユーザーに優しいローディング画面「スケルトンスクリーン」

Last updated at Posted at 2020-12-10

はじめまして。アドベントカレンダー初参戦のフロントエンド1年生です。(1月で2年生👏)
以前ふと耳にした言葉「スケルトンスクリーン」がずっと気になっていたので、これを機に皆さまにも共有できたらと思います。

スケルトンスクリーンとは

スケルトンスクリーンはご存知ですか?
名前を聞いたことがない方も、きっとどこかで見たことがあると思います。
↓この人です。
skeleton.png

ページやコンテンツの読み込み中、真っ白なページが長く続くとユーザーは不安になります。
その不安を解消するため、プログレスバーやぐるぐる回るスピナーを表示して「今、読み込んでますよ」とユーザーに伝える手法が定番でした。
そしてここ数年で新たに見かけるようになったのがスケルトンスクリーンです。

スケルトンスクリーンは、画像やCSS、JavaScriptを読み込んでいる間にワイヤーフレームのようなボックスを表示し、UXを向上させるために使われる。ユーザにとってはプログレスバーやスピナーと違いどんなページが表示されるか予想できるため、ロード時間が長くても心理的に短く感じられる。
(引用:https://kuroeveryday.blogspot.com/2017/05/load-with-skeleton-screens-and-shimmer-effect.html)

確かに、どこにどんな形で表示されるのかわかるので、
ただ真ん中でスピナーが1つグルグル表示されているよりは、ストレスも軽減されますね!!
YouTubeやSlackやQiitaなど、さまざまなサイトで見かけるようになりましたが、
なんだか実装難しそう・・・
ということで、調べながらですが挑戦してみました。

実装

手順は3つ!

  1. コンテンツを用意
  2. loadingクラスでスケルトンスクリーン作成
  3. 画像の読み込みが終わったタイミングで、loadingクラスを非表示にする

今回の題材は、お正月も近いので干支にしました。
contents

コンテンツが用意できたらHTMLとCSSでこの子のスケルトンスクリーンを作成します。

index.html
<ul class="list">
  <li class="item">
    <div class="item__img">
      <!-- 画像部分のスケルトンスクリーン -->
      <div class="loading" data-js="loading">
        <span class="loading__img"></span>
      </div>
      <img class="img"
      src="/images/nezumi.png"
      />
    </div>
    <div class="item__text">
      <!-- テキスト部分のスケルトンスクリーン -->
      <div class="loading" data-js="loading">
        <span class="loading__line"></span>
        <span class="loading__line"></span>
        <span class="loading__line"></span>
      </div>
      <dl class="text">
        <dt class="text__title">ねずみ(子)</dt>
        <dd class="text__description">すぐに子ねずみが増え成長することから、子孫繁栄の意味があります。</dd>
      </dl>
    </div>
  </li>
</ul>
style.css
.loading {
  position: absolute;
  display: block;
  width: 100%;
  height: 100%;
  background: #fff;
  overflow: hidden;
  z-index: 50;
}

/* キラキラエフェクトのアニメーション */
@keyframes skeleton-animation {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(100%);
  }
}

.loading::before {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 100;
  content: "";
  display: block;
  height: 100%;
  width: 100%;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(255, 255, 255, 0.2),
    transparent
  );
  animation: skeleton-animation 1.2s linear infinite;
}

/* 画像部分のスケルトンスクリーン */
.loading__img {
  display: block;
  width: 100%;
  height: 100%;
  background-color: #e2e2e2;
  border-radius: 50%;
}

/* テキスト部分のスケルトンスクリーン */
.loading__line {
  display: block;
  margin-top: 10px;
  height: 20px;
  background-color: #e2e2e2;
}

/* スケルトンスクリーンを非表示にするクラス */
.loading--hidden {
  display: none;
}

skeleton.png
こんな感じに、コンテンツの画像・テキストをシルバーのスクリーンで覆うイメージです。

そして最後にJSです。
画像の読み込みが終わったらdata-js='loading'の要素のクラスにloading--hiddenを追加して非表示にしてあげるだけです。

main.js
// ローディングの要素取得
const loadingItem = document.querySelectorAll("[data-js=loading]");

// loading非表示クラスを追加
const hideLoading = (list, className) => {
  list.forEach((element) => {
    element.classList.add(className);
  });
};

window.onload = () => {
  hideLoading(loadingItem, "loading--hidden");
};

skeleton.gif
このように、ローディング中の数秒間だけスケルトンスクリーンが表示されるようになりました!

完成

ねずみだけだと寂しいので、仲間を増やして完成です。
とてもとてもいい感じな気がします。
※コードはこちら:GitHub

skeleton2.gif

おわりに

スケルトンスクリーンの実装は思ったよりも難しくはなく、案外シンプルに実装できました。
しかし、

  • 読み込みが早い場合はコンテンツ表示時に一瞬ちらつくな…
  • コンテンツの文字数が増えたらはみ出しそうだな…
  • スクロールに合わせて画像を読み込み開始にしたらさらに良いかも…

など、いろいろ改善の余地はありそうです。
また、従来のスピナーやプログレスバーとの効果的な使い分けについても、もう少し探っていけたらと思います。

ストレスフリーなローディング画面を目指して!!!!

参考

47
14
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
47
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?