ズームしながら一定時間ごとに切り替える
CSS の transform: scale() と opacity を @keyframes で組み合わせ、ズームしながらフェードで切り替える方法を4パターンで解説します。各デモと同じ動きを再現できるHTML・CSS・JavaScriptを掲載しています。
HTML・CSS・JSコードプレビューツールでも動作を確認できます。
このページで作るもの
① 基本のズームフェード — scale と opacity を同時に動かす
<div class="zf-basic-wrap">
<div class="zf-basic-panel is-on">
<span class="zf-basic-num">01</span>
<span class="zf-basic-txt">Nature</span>
</div>
</div>
.zf-basic-wrap {
height: 220px;
overflow: hidden;
}
.zf-basic-panel {
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
height: 100%;
background: linear-gradient(135deg, #134e4a, #065f46 50%, #064e3b);
}
.zf-basic-panel.is-on {
display: flex;
animation: zfBasicZoom 5s ease-in-out forwards;
}
.zf-basic-num {
font-size: 2.4rem;
font-weight: 900;
line-height: 1;
color: rgba(255, 255, 255, 0.2);
}
.zf-basic-txt {
font-size: 1.2rem;
font-weight: 700;
letter-spacing: 0.08em;
color: rgba(255, 255, 255, 0.85);
}
@keyframes zfBasicZoom {
0% {
opacity: 0;
transform: scale(1);
}
20% {
opacity: 1;
}
80% {
opacity: 1;
}
100% {
opacity: 0;
transform: scale(1.2);
}
}
@keyframes で scale(1) から scale(1.2) へ拡大しつつ、opacity を 0→1→0 と動かします。親に overflow: hidden を付けると、はみ出した部分が隠れ、自然なズームになります。
② 自動スライドショー — setInterval で5秒ごとに切替
<div class="zf-show-wrap">
<div class="zf-show-inner">
<div class="zf-show-pane zf-show-1 is-on">
<span class="zf-show-num">01</span>
<span class="zf-show-txt">Nature</span>
</div>
<div class="zf-show-pane zf-show-2">
<span class="zf-show-num">02</span>
<span class="zf-show-txt">Ocean</span>
</div>
<div class="zf-show-pane zf-show-3">
<span class="zf-show-num">03</span>
<span class="zf-show-txt">Sunset</span>
</div>
</div>
<div class="zf-show-dots">
<span class="zf-show-dot is-on"></span>
<span class="zf-show-dot"></span>
<span class="zf-show-dot"></span>
</div>
</div>
.zf-show-inner {
position: relative;
height: 220px;
overflow: hidden;
}
.zf-show-pane {
position: absolute;
inset: 0;
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
}
.zf-show-pane.is-on {
display: flex;
animation: zfShowZoom 5s ease-in-out forwards;
}
.zf-show-1 {
background: linear-gradient(135deg, #134e4a, #065f46 50%, #064e3b);
}
.zf-show-2 {
background: linear-gradient(135deg, #1e3a5f, #1e40af 50%, #1d4ed8);
}
.zf-show-3 {
background: linear-gradient(135deg, #7c2d12, #c2410c 50%, #ea580c);
}
.zf-show-num {
font-size: 3rem;
font-weight: 900;
line-height: 1;
color: rgba(255, 255, 255, 0.2);
}
.zf-show-txt {
font-size: 1.4rem;
font-weight: 700;
letter-spacing: 0.1em;
color: rgba(255, 255, 255, 0.9);
}
.zf-show-dots {
display: flex;
justify-content: center;
gap: 8px;
padding: 14px 0;
background: #0f172a;
}
.zf-show-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.25);
transition: background 0.3s;
}
.zf-show-dot.is-on {
background: #7c3aed;
}
@keyframes zfShowZoom {
0% {
opacity: 0;
transform: scale(1);
}
20% {
opacity: 1;
}
80% {
opacity: 1;
}
100% {
opacity: 0;
transform: scale(1.2);
}
}
var paneList = document.querySelectorAll('.zf-show-pane');
var dotList = document.querySelectorAll('.zf-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');
}, 5000);
5秒ごとに表示クラスを外し、次のパネルへ付け直します。クラスが付くたびに @keyframes が再起動し、ズームフェードが繰り返されます。最後のあと最初へ戻すループにしています。
③ ズーム倍率を変える — scale() の値で印象が変わる
ズーム値: ×1.2
<div class="zf-mag-wrap">
<div class="zf-mag-panel is-on">
<span class="zf-mag-num">Demo</span>
<span class="zf-mag-txt">Zoom Scale</span>
</div>
</div>
.zf-mag-wrap {
height: 220px;
overflow: hidden;
}
.zf-mag-panel {
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
height: 100%;
background: linear-gradient(135deg, #4f46e5, #7c3aed 50%, #9333ea);
}
.zf-mag-panel.is-on {
display: flex;
animation: zfMagZoom 5s ease-in-out forwards;
}
.zf-mag-num {
font-size: 2.4rem;
font-weight: 900;
line-height: 1;
color: rgba(255, 255, 255, 0.2);
}
.zf-mag-txt {
font-size: 1.2rem;
font-weight: 700;
letter-spacing: 0.08em;
color: rgba(255, 255, 255, 0.85);
}
@keyframes zfMagZoom {
0% {
opacity: 0;
transform: scale(1);
}
20% {
opacity: 1;
}
80% {
opacity: 1;
}
100% {
opacity: 0;
transform: scale(1.2);
}
}
倍率が小さい(×1.05)ほど繊細に、大きい(×1.5)ほど躍動感が出ます。メインビジュアルでは scale(1.1)〜scale(1.2) 程度が扱いやすいです。ボタンを押すとデモとコピペ用CSSが同時に更新されます。
④ 切り替え速度の変更 — clearInterval で再設定
状態: 停止中
<div class="zf-spd-wrap">
<div class="zf-spd-pane zf-spd-1 is-on">
<span class="zf-spd-num">01</span>
<span class="zf-spd-txt">Spring</span>
</div>
<div class="zf-spd-pane zf-spd-2">
<span class="zf-spd-num">02</span>
<span class="zf-spd-txt">Summer</span>
</div>
<div class="zf-spd-pane zf-spd-3">
<span class="zf-spd-num">03</span>
<span class="zf-spd-txt">Autumn</span>
</div>
<div class="zf-spd-pane zf-spd-4">
<span class="zf-spd-num">04</span>
<span class="zf-spd-txt">Winter</span>
</div>
</div>
<input class="zf-spd-slider" type="range" min="2" max="8" step="1" value="5">
.zf-spd-wrap {
position: relative;
height: 220px;
overflow: hidden;
}
.zf-spd-pane {
position: absolute;
inset: 0;
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
}
.zf-spd-pane.is-on {
display: flex;
animation: zfSpdZoom 5s ease-in-out forwards;
}
.zf-spd-1 {
background: linear-gradient(135deg, #365314, #4d7c0f 50%, #3f6212);
}
.zf-spd-2 {
background: linear-gradient(135deg, #1e3a5f, #2563eb 50%, #1d4ed8);
}
.zf-spd-3 {
background: linear-gradient(135deg, #78350f, #d97706 50%, #b45309);
}
.zf-spd-4 {
background: linear-gradient(135deg, #1e293b, #334155 50%, #475569);
}
.zf-spd-num {
font-size: 2.4rem;
font-weight: 900;
line-height: 1;
color: rgba(255, 255, 255, 0.2);
}
.zf-spd-txt {
font-size: 1.2rem;
font-weight: 700;
letter-spacing: 0.08em;
color: rgba(255, 255, 255, 0.85);
}
.zf-spd-slider {
display: block;
width: 200px;
margin: 16px auto;
cursor: pointer;
}
@keyframes zfSpdZoom {
0% {
opacity: 0;
transform: scale(1);
}
20% {
opacity: 1;
}
80% {
opacity: 1;
}
100% {
opacity: 0;
transform: scale(1.2);
}
}
var paneList = document.querySelectorAll('.zf-spd-pane');
var speedSlider = document.querySelector('.zf-spd-slider');
var panePos = 0;
var timerRef = null;
function rotatePane() {
paneList[panePos].classList.remove('is-on');
panePos = (panePos + 1 >= paneList.length) ? 0 : panePos + 1;
paneList[panePos].classList.add('is-on');
}
function startTimer(ms) {
if (timerRef) clearInterval(timerRef);
timerRef = setInterval(rotatePane, ms);
}
speedSlider.addEventListener('input', function() {
startTimer(speedSlider.value * 1000);
});
startTimer(5000);
速度を変えるときは、保存しておいたタイマーを clearInterval で止めてから、新しい間隔で setInterval し直します。タイマー参照を変数に残しておかないと、あとから止められません。
overflow: hidden はなぜ必要?
scale で拡大した部分が枠外へはみ出します。親で overflow: hidden を付けると、はみ出しが隠れてズームらしい見え方になります。
フェードのみとの違いは?
opacity だけの切替は静かな印象です。scale を足すと奥行きや動きが出ます。フェードイン切り替えと用途で使い分けるとよいです。
ズーム倍率の目安は?
メインビジュアルでは 1.1〜1.2 が扱いやすいです。③で倍率を切り替えて印象を比較できます。
画像に置き換えるには?
各パネル内に img を置き、object-fit: cover と親の overflow: hidden を指定します。パネル自体にアニメーションを掛けるか、画像要素に掛けるかはどちらでも構いません。
当サイトで公開しているWebデザインやUIの実装例は、一覧として以下記事に纏めています。

