スケルトンスクリーン(スケルトンローダー)とはコンテンツの枠組のみを表現したデザインのことを指します。
スケルトンスクリーンは画面のローディング中などにUX向上の目的で利用されます。
今回はCSSによるスケルトンスクリーンの実装方法と解説をします。
目次
スケルトンスクリーンの実装手順
- コンテンツの枠(スケルトンスクリーンのデザイン)を作成する
- スケルトンスクリーンの要素に対して擬似要素を追加する
- スケルトンスクリーンのpositionをrelative, 擬似要素をabsoluteにする
- 擬似要素に対してアニメーションを追加する
CSSによるスケルトンスクリーンのサンプルコード
<div class='item'>
<div class='item__image'></div>
<div>
<div class='item__detail'></div>
<div class='item__detail'></div>
<div class='item__detail'></div>
</div>
</div>
@keyframes loading {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
.item {
border: 1px solid #ddd;
border-radius: 5px;
height: 85px;
width: 225px;
display: flex;
align-items: center;
border-top: 1px solid #ddd;
padding: 10px;
}
.item__image {
width: 64px;
height: 64px;
margin-right: 10px;
background: #f4f4f5;
overflow: hidden;
position: relative;
}
.item__image::before {
display: block;
content: '';
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.50), transparent);
animation: loading 1.0s linear infinite;
}
.item__detail {
height: 15px;
width: 125px;
background: #f4f4f5;
overflow: hidden;
position: relative;
}
.item__detail:not(:last-child) {
margin-bottom: 5px;
}
.item__detail::before {
display: block;
content: '';
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);
animation: loading 1.0s linear infinite;
}
See the Pen
Untitled by Toshiharu Nishina (@nishina555)
on CodePen.
以下では上記のCSSについて解説します。
擬似要素の背景について
スケルトンスクリーンのCSSに記載されているbackground: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);
の意味について解説します。
擬似要素(before/after)の詳細解説は擬似要素before/afterの概要と具体例で紹介しています。
linear-gradientについて
linear-gradient()とはグラデーションを生成するCSS関数です。第1引数にグラデーションの向き、第2引数以降にグラデーションの配色を指定します。
以下はlinear-gradient
の例です。
<div class='pattern1'></div>
<hr>
<div class='pattern2'></div>
<hr>
<div class='pattern3'></div>
<hr>
<div class='pattern4'></div>
.pattern1 {
width: 200px;
height: 100px;
/* グラデーション。配色は青、赤の順 */
background: linear-gradient(0deg, blue, red);
}
.pattern2 {
width: 200px;
height: 100px;
/* 90度傾いたグラデーション。配色は青、赤、黄の順 */
background: linear-gradient(90deg, blue, red, yellow);
}
.pattern3 {
width: 200px;
height: 100px;
/* 45度傾いたグラデーション。配色は青、赤、黄の順 */
background: linear-gradient(45deg, blue, red, yellow);
}
.pattern4 {
width: 200px;
height: 100px;
/* 右下から左上に向かうグラデーション。配色は青、赤の順 */
background: linear-gradient(to left top, blue, red);;
}
See the Pen
Untitled by Toshiharu Nishina (@nishina555)
on CodePen.
白色半透過の擬似要素を重ねた時の見た目について
rgba()は赤、緑、青の成分で色を表現するCSS関数です。オプションで色の透明度(opacity)を指定できます。
スケルトンスクリーンで利用されているrgba(255, 255, 255, 0.5);
は半透過の白色を表現しています。
白色半透過の擬似要素を重ね合わせると、要素の色は薄くなります。
<div class='item'></div>
.item {
width: 100px;
height: 100px;
background: red;
position: relative;
}
.item::before {
content: '';
display: block;
height: 50%;
width: 100%;
background: rgba(255, 255, 255, 0.5);
position: absolute;
}
See the Pen
background-white-half-opacity by Toshiharu Nishina (@nishina555)
on CodePen.
transparentな擬似要素を重ねた時の見た目について
transparentは要素を透明にするプロパティですので、transparentな擬似要素を重ね合わせても要素の色はかわりません。
<div class='item'></div>
.item {
width: 100px;
height: 100px;
background: red;
position: relative;
}
.item::before {
content: '';
display: block;
height: 50%;
width: 100%;
background: transparent;
position: absolute;
}
See the Pen
background-transparent by Toshiharu Nishina (@nishina555)
on CodePen.
transparentと白色半透過のグラデーションを重ねた時の見た目について
linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);
は「左から、透明、白色半透過、透明というグラデーション」を意味します。
上記のグラデーションを要素に重ね合わせると、要素の真ん中の色だけ薄くなります。
<div class='item'></div>
.item {
width: 100px;
height: 100px;
background: red;
position: relative;
}
.item::before {
content: '';
display: block;
height: 50%;
width: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);
position: absolute;
}
See the Pen
Untitled by Toshiharu Nishina (@nishina555)
on CodePen.
擬似要素のアニメーションについて
スケルトンスクリーンのCSSに記載されている以下の意味について解説します。
@keyframes loading {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
.item__detail::before {
animation: loading 1.0s linear infinite;
}
transformについて
transformは要素を移動するCSSプロパティです。translateX
でX軸(横軸)に関する要素の移動距離を指定できます。
<div class='item_1'></div>
<hr>
<div class='item_2'></div>
<hr>
<div class='item_3'></div>
.item_1 {
width: 100px;
height: 100px;
background: red;
position: relative;
margin-left: 150px;
}
.item_1::before {
content: '';
display: block;
height: 50%;
width: 100%;
background: blue;
position: absolute;
transform: translateX(-100%);
}
.item_2 {
width: 100px;
height: 100px;
background: red;
position: relative;
margin-left: 150px;
}
.item_2::before {
content: '';
display: block;
height: 50%;
width: 100%;
background: blue;
position: absolute;
transform: translateX(50%);
}
.item_3 {
width: 100px;
height: 100px;
background: red;
position: relative;
margin-left: 150px;
}
.item_3::before {
content: '';
display: block;
height: 50%;
width: 100%;
background: blue;
position: absolute;
transform: translateX(100%);
}
See the Pen
pseudo-transform-patterns by Toshiharu Nishina (@nishina555)
on CodePen.
@keyframesを利用したanimationについて
animationとはスタイルのアニメーションを定義するプロパティです。
@keyframesとはアニメーションの各キーフレームにおけるCSSを定義するCSSアットルールです。@keyframes
を利用することでアニメーションの詳細な定義、制御ができます。
スケルトンスクリーンに登場したanimation: loading 1.0s linear infinite;
は「loading
というキーフレーム名の動きを、1秒1周期(1s
)、一定のスピード(liner
)、無限に繰り返す(infinite
)」というアニメーションを意味します。
スケルトンスクリーンで利用されていたキーフレーム(始点translateX(-100%)
、終点translateX(100%)
)を適用すると以下のようになります。
<div class='item'></div>
@keyframes loading {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
.item {
width: 100px;
height: 100px;
background: red;
position: relative;
margin-left: 150px;
}
.item::before {
content: '';
display: block;
height: 100%;
width: 100%;
background: blue;
position: absolute;
animation: loading 1.0s linear infinite;
}
See the Pen
Untitled by Toshiharu Nishina (@nishina555)
on CodePen.
さらに要素からはみ出した部分をoverflow: hidden
で無視すると以下のようになります。
<div class='item'></div>
@keyframes loading {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
.item {
width: 100px;
height: 100px;
background: red;
position: relative;
margin-left: 150px;
overflow: hidden;
}
.item::before {
content: '';
display: block;
height: 100%;
width: 100%;
background: blue;
position: absolute;
animation: loading 1.0s linear infinite;
}
See the Pen
animation-keyframes-overflow-hidden by Toshiharu Nishina (@nishina555)
on CodePen.
スケルトンスクリーンのコードをあらためて確認
今回紹介したスケルトンスクリーンのサンプルコードは「透明・白色半透過・透明というグラデーションの擬似要素を左右に移動させ、要素の一部の色のみを薄くする」ということを行っています。その結果、ローディング中のようなデザインとなります。
冒頭で紹介したサンプルコードを再掲します。
<div class='item'>
<div class='item__image'></div>
<div>
<div class='item__detail'></div>
<div class='item__detail'></div>
<div class='item__detail'></div>
</div>
</div>
@keyframes loading {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
.item {
border: 1px solid #ddd;
border-radius: 5px;
height: 85px;
width: 225px;
display: flex;
align-items: center;
border-top: 1px solid #ddd;
padding: 10px;
}
.item__image {
width: 64px;
height: 64px;
margin-right: 10px;
background: #f4f4f5;
overflow: hidden;
position: relative;
}
.item__image::before {
display: block;
content: '';
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.50), transparent);
animation: loading 1.0s linear infinite;
}
.item__detail {
height: 15px;
width: 125px;
background: #f4f4f5;
overflow: hidden;
position: relative;
}
.item__detail:not(:last-child) {
margin-bottom: 5px;
}
.item__detail::before {
display: block;
content: '';
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);
animation: loading 1.0s linear infinite;
}
See the Pen
Untitled by Toshiharu Nishina (@nishina555)
on CodePen.
さいごに
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!