一定時間ごとに要素をフワッと切り替える
JavaScript の setInterval() と CSS の opacity アニメーションで、一定時間ごとに表示を切り替える方法を4パターンで解説します。各デモと同じ動きを再現できるHTML・CSS・JavaScriptを掲載しています。
HTML・CSS・JSコードプレビューツールでも動作を確認できます。
このページで作るもの
① 基本のフェードイン — opacity を 0 から 1 へ
<p class="fd-basic-msg is-on">こんにちは!</p>
.fd-basic-msg {
display: none;
margin: 0;
text-align: center;
font-size: 1.5rem;
font-weight: 700;
color: #1e293b;
}
.fd-basic-msg.is-on {
display: block;
animation: fdBasicFade 2s ease-out forwards;
}
@keyframes fdBasicFade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
opacity を 0 から 1 へ変えると、フワッと現れる動きになります。animation に forwards を付けると終了後も不透明のまま残り、消えてしまうのを防げます。
② テキストのローテーション — 3秒ごとに自動切り替え
こんにちは!
Hello!
你好!
Bonjour!
Guten Tag!
状態: 停止中
<p class="fd-rotate-msg is-on">こんにちは!</p>
<p class="fd-rotate-msg">Hello!</p>
<p class="fd-rotate-msg">你好!</p>
<p class="fd-rotate-msg">Bonjour!</p>
<p class="fd-rotate-msg">Guten Tag!</p>
.fd-rotate-msg {
display: none;
margin: 0;
text-align: center;
font-size: 1.5rem;
font-weight: 700;
color: #1e293b;
}
.fd-rotate-msg.is-on {
display: block;
animation: fdRotateFade 2s ease-out;
}
@keyframes fdRotateFade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
var msgList = document.querySelectorAll('.fd-rotate-msg');
var msgPos = 1;
function rotateMsg() {
if (msgPos >= msgList.length) msgPos = 0;
msgList.forEach(function(msg) {
msg.classList.remove('is-on');
});
msgList[msgPos].classList.add('is-on');
msgPos++;
}
setInterval(rotateMsg, 3000);
setInterval で一定間隔ごとに関数を呼び、全要素から表示クラスを外して次の要素だけ付け直します。クラスが付くたびに @keyframes が再起動するため、連続してフェードします。
③ 切り替え速度の変更 — clearInterval で再設定
春 Spring
夏 Summer
秋 Autumn
冬 Winter
状態: 停止中
<p class="fd-speed-msg is-on">春 Spring</p>
<p class="fd-speed-msg">夏 Summer</p>
<p class="fd-speed-msg">秋 Autumn</p>
<p class="fd-speed-msg">冬 Winter</p>
<input class="fd-speed-slider" type="range" min="1" max="5" step="1" value="2">
.fd-speed-msg {
display: none;
margin: 0;
text-align: center;
font-size: 1.5rem;
font-weight: 700;
color: #1e293b;
}
.fd-speed-msg.is-on {
display: block;
animation: fdSpeedFade 1s ease-out forwards;
}
@keyframes fdSpeedFade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.fd-speed-slider {
display: block;
width: 200px;
margin: 16px auto;
cursor: pointer;
}
var msgList = document.querySelectorAll('.fd-speed-msg');
var speedSlider = document.querySelector('.fd-speed-slider');
var msgPos = 1;
var timerRef = null;
function rotateMsg() {
if (msgPos >= msgList.length) msgPos = 0;
msgList.forEach(function(msg) {
msg.classList.remove('is-on');
});
msgList[msgPos].classList.add('is-on');
msgPos++;
}
function startTimer(ms) {
if (timerRef) clearInterval(timerRef);
timerRef = setInterval(rotateMsg, ms);
}
speedSlider.addEventListener('input', function() {
startTimer(speedSlider.value * 1000);
});
startTimer(2000);
速度を変えるときは、保存しておいたタイマーを clearInterval で止めてから、新しい間隔で setInterval し直します。タイマー参照を変数に残しておかないと、あとから止められません。
④ パネルのスライドショー — 画像切替への応用
<div class="fd-show-wrap">
<div class="fd-show-inner">
<div class="fd-show-pane fd-show-1 is-on">
<span class="fd-show-num">01</span>
<span class="fd-show-txt">Nature</span>
</div>
<div class="fd-show-pane fd-show-2">
<span class="fd-show-num">02</span>
<span class="fd-show-txt">Ocean</span>
</div>
<div class="fd-show-pane fd-show-3">
<span class="fd-show-num">03</span>
<span class="fd-show-txt">Sunset</span>
</div>
</div>
<div class="fd-show-dots">
<span class="fd-show-dot is-on"></span>
<span class="fd-show-dot"></span>
<span class="fd-show-dot"></span>
</div>
</div>
.fd-show-inner {
position: relative;
height: 220px;
}
.fd-show-pane {
position: absolute;
inset: 0;
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
}
.fd-show-pane.is-on {
display: flex;
animation: fdShowFade 1s ease-out forwards;
}
.fd-show-1 {
background: linear-gradient(135deg, #134e4a, #065f46 50%, #064e3b);
}
.fd-show-2 {
background: linear-gradient(135deg, #1e3a5f, #1e40af 50%, #1d4ed8);
}
.fd-show-3 {
background: linear-gradient(135deg, #7c2d12, #c2410c 50%, #ea580c);
}
.fd-show-num {
font-size: 3rem;
font-weight: 900;
line-height: 1;
color: rgba(255, 255, 255, 0.2);
}
.fd-show-txt {
font-size: 1.4rem;
font-weight: 700;
letter-spacing: 0.1em;
color: rgba(255, 255, 255, 0.9);
}
.fd-show-dots {
display: flex;
justify-content: center;
gap: 8px;
padding: 14px 0;
background: #0f172a;
}
.fd-show-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.25);
transition: background 0.3s;
}
.fd-show-dot.is-on {
background: #7c3aed;
}
@keyframes fdShowFade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
var paneList = document.querySelectorAll('.fd-show-pane');
var dotList = document.querySelectorAll('.fd-show-dot');
var panePos = 0;
setInterval(function() {
paneList[panePos].classList.remove('is-on');
dotList[panePos].classList.remove('is-on');
panePos = (panePos + 1 >= paneList.length) ? 0 : panePos + 1;
paneList[panePos].classList.add('is-on');
dotList[panePos].classList.add('is-on');
}, 3000);
各パネルの中に img を置けば、メインビジュアルの画像切替にも使えます。パネルは absolute で重ね、表示クラスの付け外しでフェードを発火させます。
setTimeout との違いは?
setInterval は一定間隔で繰り返し呼びます。setTimeout は一度だけです。ローテーションのような繰り返しには setInterval が向いています。
フェードアウトも付けられますか?
可能です。切り替える前に opacity を下げるクラスを付け、アニメーション完了後に次の要素を出す流れにします。まずは表示側のフェードインから作るのがおすすめです。
速度を変えても動きがおかしいときは?
古いタイマーを clearInterval してから作り直しているか確認してください。③のように参照を変数に残す必要があります。
スクロールで始めたいときは?
表示領域に入ったタイミングで setInterval を開始します。Intersection Observer と組み合わせると実装しやすいです。
当サイトで公開しているWebデザインやUIの実装例は、一覧として以下記事に纏めています。

