記事(ページ)読み込み中のCSSローディングアニメーション - グラデーションが左から右に移動など
ブログなどの記事の読み込み中に使えるCSSローディングアニメーションのサンプルを作りました。
まずは動作サンプルをご覧ください。
▼動画
▼CodePen
See the Pen
記事アニメーションtest by dadada (@dadada-dadada)
on CodePen.
アニメーションは以下2パターンになります。
- グレー背景が点滅(透明度が濃くなる⇔薄くなるの繰り返し)
- グレーのグラデーションが左から右に移動の繰り返し
コード
HTML
<div class="container __loading">
<ul>
<li>コーディング中は、あえてファイルサイズが重い画像を使うのがおすすめです。<br>(読み込み時間が長くなってアニメーションの挙動を確認しやすいので)</li>
<li>ページをリロードする時は、ハード再読み込み(Command+Shift+R)しましょう。<br>(画像のキャッシュが残っていると読み込み時間が短くなってしまうので)</li>
</ul>
<!-- ########################################## -->
<!-- グレーの透明度が点滅するアニメーション -->
<!-- ########################################## -->
<div class="wrap-fade-toggle">
<div class="card">
<div class="card__img anima-fade-toggle">
<img src="https://cdn.spacetelescope.org/archives/images/publicationjpg/heic1901a.jpg" alt="" width="200" height="150">
</div>
<div class="card__ttl anima-fade-toggle">heic1901a</div>
</div>
<div class="card">
<div class="card__img anima-fade-toggle">
<img src="https://cdn.spacetelescope.org/archives/images/publicationjpg/heic1808a.jpg" alt="" width="200" height="150">
</div>
<div class="card__ttl anima-fade-toggle">heic1808a</div>
</div>
<div class="card">
<div class="card__img anima-fade-toggle">
<img src="https://cdn.spacetelescope.org/archives/images/large/heic0821b.jpg" alt="" width="200" height="150">
</div>
<div class="card__ttl anima-fade-toggle">heic0821b</div>
</div>
<div class="card">
<div class="card__img anima-fade-toggle">
<img src="https://cdn.spacetelescope.org/archives/images/large/potw1441a.jpg" alt="" width="200" height="150">
</div>
<div class="card__ttl anima-fade-toggle">potw1441a</div>
</div>
<div class="card">
<div class="card__img anima-fade-toggle">
<img src="https://cdn.spacetelescope.org/archives/images/large/heic0715a.jpg" alt="" width="200" height="150">
</div>
<div class="card__ttl anima-fade-toggle">heic0715a</div>
</div>
<div class="card">
<div class="card__img anima-fade-toggle">
<img src="https://cdn.spacetelescope.org/archives/images/large/potw2114a.jpg" alt="" width="200" height="150">
</div>
<div class="card__ttl anima-fade-toggle">potw2114a</div>
</div>
</div>
<hr>
<!-- ########################################## -->
<!-- グラデーションが移動するアニメーション -->
<!-- ########################################## -->
<div class="wrap-gradient">
<div class="card">
<div class="card__img anima-gradient">
<img src="https://cdn.spacetelescope.org/archives/images/publicationjpg/heic1901a.jpg" alt="" width="200" height="150">
</div>
<div class="card__ttl anima-gradient">heic1901a</div>
</div>
<div class="card">
<div class="card__img anima-gradient">
<img src="https://cdn.spacetelescope.org/archives/images/publicationjpg/heic1808a.jpg" alt="" width="200" height="150">
</div>
<div class="card__ttl anima-gradient">heic1808a</div>
</div>
<div class="card">
<div class="card__img anima-gradient">
<img src="https://cdn.spacetelescope.org/archives/images/large/heic0821b.jpg" alt="" width="200" height="150">
</div>
<div class="card__ttl anima-gradient">heic0821b</div>
</div>
<div class="card">
<div class="card__img anima-gradient">
<img src="https://cdn.spacetelescope.org/archives/images/large/potw1441a.jpg" alt="" width="200" height="150">
</div>
<div class="card__ttl anima-gradient">potw1441a</div>
</div>
<div class="card">
<div class="card__img anima-gradient">
<img src="https://cdn.spacetelescope.org/archives/images/large/heic0715a.jpg" alt="" width="200" height="150">
</div>
<div class="card__ttl anima-gradient">heic0715a</div>
</div>
<div class="card">
<div class="card__img anima-gradient">
<img src="https://cdn.spacetelescope.org/archives/images/large/potw2114a.jpg" alt="" width="200" height="150">
</div>
<div class="card__ttl anima-gradient">potw2114a</div>
</div>
</div>
</div>
CSS
/* ############################################## */
/* 共通(アニメーションとは直接関係のないスタイル) */
/* ############################################## */
body{
padding: 20px;
}
.wrap-fade-toggle,
.wrap-gradient{
display: flex;
flex-wrap: wrap;
}
.card{
width: 200px;
margin: 4%;
}
.card__img{
position: relative; /* 両方のアニメーションで必要 */
overflow: hidden; /* グラデーションが移動するアニメーションで必要 */
}
.card__ttl{
display: inline-block;
font-weight: bold;
margin-top: 8px;
position: relative; /* 両方のアニメーションで必要 */
overflow: hidden; /* グラデーションが移動するアニメーションで必要 */
}
/* ############################################## */
/* グレーの透明度が点滅するアニメーション */
/* ############################################## */
/* 重ねるグレーのベース */
.anima-fade-toggle::before {
content: "";
background-color: #eee;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transition: opacity .4s, visibility .4s;
}
/* 読み込み中 */
.container.__loading .anima-fade-toggle::before {
animation: anima_fade_toggle 1s infinite;
animation-direction: alternate;
}
@keyframes anima_fade_toggle {
0% {
background-color: #eee;
}
100% {
background-color: #ccc;
}
}
/* 読み込み完了後 */
.container.__loaded .anima-fade-toggle::before {
opacity: 0;
visibility: hidden;
}
/* ############################################## */
/* グラデーションが移動するアニメーション */
/* ############################################## */
/* 重ねるグレーのベース */
.anima-gradient::before {
content: "";
background: linear-gradient(90deg, #f1f1f1 0%, #ddd 50%, #f1f1f1 100%);
position: absolute;
top: 0;
left: 0;
width: 300%;
height: 100%;
z-index: 1;
transition: opacity .4s, visibility .4s;
}
.anima-gradient::after {
content: "";
background-color: #f1f1f1;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transition: opacity .4s, visibility .4s;
}
/* 読み込み中 */
.container.__loading .anima-gradient::before {
animation: anima_gradient 2.2s ease-in-out infinite;
opacity: 0.9;
}
@keyframes anima_gradient {
0% {
left: -300%;
}
100% {
left: 300%;
}
}
/* 読み込み完了後 */
.container.__loaded .anima-gradient::before,
.container.__loaded .anima-gradient::after {
opacity: 0;
visibility: hidden;
}
JavaScript
<script>
// DOMや画像など全てを読み込み後、.containerのクラスを切替え
window.addEventListener('load', function(_ev) {
document.querySelector('.container').classList.remove('__loading');
document.querySelector('.container').classList.add('__loaded');
});
</script>
<script>を読み込ませる箇所はどこでも大丈夫です。
迷ったら</body>の手前で読み込ませましょう。
解説
JavaScriptのloadイベントを使い、HTMLや画像など全てが読み込まれたら、全体を囲っている.container要素のクラス.__loadingを削除して.__loadedを追加しています。
なので、.__loadingクラスが付いている時はCSSのアニメーションが動いており、外れたらアニメーションが止まるようになっています。
画像やテキストの上に擬似要素でグレーシェイプの要素を置いて、それに対してグレー背景が点滅したり、グラデーションが左から右に移動したりするアニメーションを付与しています。