サイトアイコン WEBデザインMATOME

【実装例付き】ローディング演出で“印象に残るサイト”を作る方法|文字アニメーション×スキップ対応

「なんとなく作ったサイト」と「記憶に残るサイト」の違いは、
最初の数秒で決まることが多いです。

その中でも効果的なのが、

ローディング演出(オープニング)

ただし注意点があります。

つまり重要なのは、

軽くて、気持ちよくて、すぐ終わる演出

です。

この記事では、

✔ 中央から背景が広がる
✔ テキストが1文字ずつ自然に表示
✔ スキップ可能
✔ 初回だけ表示もできる設計

という、実務でも使えるローディング設計を紹介します。

今回の実装コンセプト

今回のコードは「使い回し」を意識しています。

特徴

HTML(シンプル構造)

<section class="loading" id="loading">
<button class="loading__skip" id="skipBtn">SKIP</button> <div class="loading__bg"></div> <div class="loading__content">
<h1 class="loading__title js-text" data-delay="1.2">
Hello World
</h1>
<p class="loading__sub js-text" data-delay="1.6">
sample text
</p>
</div>
</section>

CSS(軽量&拡張しやすい設計)

.loading {
position: fixed;
inset: 0;
z-index: 9999;
background: #fff; display: flex;
justify-content: center;
align-items: center; transform-origin: center;
opacity: 1;
}/* 背景 */
.loading__bg {
position: absolute;
inset: 0;
background: #fff;
transform: scale(0.6);
opacity: 0;
}/* 背景アニメ */
.loading.is-active .loading__bg {
animation: bgExpand 1s ease-out forwards;
}@keyframes bgExpand {
to {
transform: scale(1);
opacity: 1;
}
}/* テキスト */
.loading__content {
position: relative;
text-align: center;
z-index: 2;
}.loading__title {
font-size: clamp(32px, 5vw, 60px);
}.loading__sub {
margin-top: 12px;
}/* 文字 */
.char {
display: inline-block;
opacity: 0;
transform: translateY(10px);
animation: fadeChar 0.4s forwards;
}@keyframes fadeChar {
to {
opacity: 1;
transform: translateY(0);
}
}/* 非表示 */
.loading.is-hidden {
opacity: 0;
pointer-events: none;
transition: opacity 0.6s ease;
}/* スキップ */
.loading__skip {
position: absolute;
top: 20px;
right: 20px;
z-index: 10;
border: 1px solid #333;
background: #fff;
padding: 8px 14px;
cursor: pointer;
}

JavaScript(拡張しやすい設計)

<script>
document.addEventListener('DOMContentLoaded', () => {
const loading = document.getElementById('loading');
const skip = document.getElementById('skipBtn');
const texts = document.querySelectorAll('.js-text'); let closed = false; // テキスト分解
texts.forEach(el => {
const delay = parseFloat(el.dataset.delay || 1);
const parts = el.innerHTML.split(/<br\s*\/?>/i); el.innerHTML = ''; let base = delay; parts.forEach((part, i) => {
part.split('').forEach((char, index) => {
const span = document.createElement('span');
span.className = 'char';
span.textContent = char === ' ' ? '\u00A0' : char;
span.style.animationDelay = (base + index * 0.06) + 's';
el.appendChild(span);
}); if (i < parts.length - 1) {
el.appendChild(document.createElement('br'));
} base += part.length * 0.06 + 0.2;
});
}); // 開始
requestAnimationFrame(() => {
loading.classList.add('is-active');
}); function close() {
if (closed) return;
closed = true;
loading.classList.add('is-hidden'); setTimeout(() => {
loading.remove();
}, 600);
} // スキップ
skip.addEventListener('click', close); // 自動終了
setTimeout(close, 10000);
});
</script>

この設計のメリット

① data属性で制御できる

data-delay="1.2"

テキストごとにタイミング変更できる
デザイナーと共有しやすい

② CSSとJSの責務が分離されている

保守性が高い

③ WordPressでもそのまま使える

例えば

<?php if (!isset($_COOKIE['visited'])) : ?>
<!-- loading表示 -->
<?php endif; ?>

初回だけ表示も可能

応用アイデア

さらにレベルを上げるなら

実務での使いどころ

このローディングは特に

で効果が高いです。

まとめ

今回のポイント

最後に

ローディングは単なる装飾ではなく、

「最初のUX設計」そのものです

今回のコードをベースに、
ぜひあなたのサイトに合った演出にカスタマイズしてみてください。

モバイルバージョンを終了