RGBずらしグリッチ

同一画像を3枚重ねてチャンネルごとに着色・ずらし、走査線を被せたグリッチ風ホバーエフェクト。サイバー/音楽系サイトのアクセントに。

#css#animation#glitch#hover

ライブデモ

使用例(お題: アイドルグループ Sakura)

この技法を「アイドルグループ Sakura」というテーマのダミーサイトで実際に使った例です。

HTML
<!-- Sakura:デジタルライブ告知(RGBずらしグリッチ) -->
<section class="sk-gl">
  <!-- ライブ写真を3枚重ねて RGB グリッチ -->
  <figure class="sk-gl__media" tabindex="0" aria-label="ライブ映像グリッチ">
    <img class="sk-gl__layer sk-gl__layer--r" src="https://picsum.photos/720/520?random=61" alt="">
    <img class="sk-gl__layer sk-gl__layer--g" src="https://picsum.photos/720/520?random=61" alt="">
    <img class="sk-gl__layer sk-gl__layer--b" src="https://picsum.photos/720/520?random=61" alt="オンラインライブ映像">
    <figcaption class="sk-gl__cap">LIVE</figcaption>
    <span class="sk-gl__rec">● ON AIR</span>
  </figure>

  <!-- 告知テキスト -->
  <div class="sk-gl__info">
    <span class="sk-gl__tag">DIGITAL LIVE</span>
    <h2 class="sk-gl__title">真夜中の<br>配信ライブ。</h2>
    <p class="sk-gl__meta">6.30 MON 23:00 START<br>オンライン生配信</p>
    <p class="sk-gl__note">※ 写真にホバーでグリッチ演出</p>
    <a class="sk-gl__btn" href="#">視聴チケット</a>
  </div>
</section>
CSS
/* Sakura:デジタルライブ告知(RGBグリッチ) */
:root {
  --pink: #ffd1e0;
  --deep: #2a1620;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  height: 400px;
  display: flex;
  align-items: center;
  gap: 30px;
  padding: 0 30px;
  font-family: "Hiragino Kaku Gothic ProN", system-ui, sans-serif;
  background:
    radial-gradient(120% 100% at 100% 0%, #4a1f38 0%, var(--deep) 70%);
  color: #fff;
  overflow: hidden;
}

/* グリッチ写真 */
.sk-gl__media {
  position: relative;
  flex: 0 0 360px;
  height: 300px;
  margin: 0;
  border-radius: 14px;
  overflow: hidden;
  cursor: pointer;
  outline: none;
  box-shadow: 0 18px 42px rgba(0,0,0,0.5);
}
.sk-gl__layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* 通常は B レイヤーのみ素のまま */
.sk-gl__layer--r,
.sk-gl__layer--g { opacity: 0; mix-blend-mode: screen; }

/* ホバー / フォーカスでチャンネル分離&ずらし(桜ピンク寄りに) */
.sk-gl__media:hover .sk-gl__layer--r,
.sk-gl__media:focus-visible .sk-gl__layer--r {
  opacity: 0.85;
  filter: sepia(1) saturate(6) hue-rotate(-30deg);
  animation: skShiftR 0.35s steps(2) infinite;
}
.sk-gl__media:hover .sk-gl__layer--g,
.sk-gl__media:focus-visible .sk-gl__layer--g {
  opacity: 0.8;
  filter: sepia(1) saturate(5) hue-rotate(120deg);
  animation: skShiftG 0.3s steps(2) infinite;
}
.sk-gl__media:hover .sk-gl__layer--b,
.sk-gl__media:focus-visible .sk-gl__layer--b {
  filter: sepia(1) saturate(6) hue-rotate(200deg);
  animation: skShiftB 0.4s steps(2) infinite;
}

/* 走査線 */
.sk-gl__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0,0,0,0) 0,
    rgba(0,0,0,0.12) 2px,
    rgba(0,0,0,0) 3px
  );
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.sk-gl__media:hover::after,
.sk-gl__media:focus-visible::after { opacity: 1; }

@keyframes skShiftR { 0% { transform: translate(0,0); } 100% { transform: translate(-5px, 2px); } }
@keyframes skShiftG { 0% { transform: translate(0,0); } 100% { transform: translate(4px, -3px); } }
@keyframes skShiftB { 0% { transform: translate(0,0); } 100% { transform: translate(2px, 3px); } }

.sk-gl__cap {
  position: absolute;
  left: 14px;
  bottom: 14px;
  z-index: 3;
  font-size: 18px;
  font-weight: 800;
  letter-spacing: 0.25em;
  color: #fff;
}
.sk-gl__media:hover .sk-gl__cap,
.sk-gl__media:focus-visible .sk-gl__cap {
  text-shadow: 2px 0 #ff3c7e, -2px 0 #00e5ff;
}
.sk-gl__rec {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 3;
  font-size: 10px;
  letter-spacing: 0.1em;
  font-weight: 700;
  color: #ff3c7e;
  background: rgba(0,0,0,0.5);
  padding: 4px 9px;
  border-radius: 4px;
}

/* 告知テキスト */
.sk-gl__info { flex: 1; }
.sk-gl__tag { font-size: 10px; letter-spacing: 0.3em; color: var(--pink); }
.sk-gl__title {
  margin: 10px 0 12px;
  font-size: 28px;
  font-weight: 800;
  line-height: 1.35;
  font-family: "Hiragino Mincho ProN", "Yu Mincho", serif;
}
.sk-gl__meta { margin: 0 0 8px; font-size: 12.5px; line-height: 1.8; color: rgba(255,255,255,0.85); }
.sk-gl__note { margin: 0 0 18px; font-size: 11px; color: rgba(255,209,224,0.7); }
.sk-gl__btn {
  display: inline-block;
  padding: 11px 24px;
  border-radius: 999px;
  background: var(--pink);
  color: #5a2e44;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  box-shadow: 0 8px 20px rgba(255,150,185,0.4);
  transition: transform 0.2s ease;
}
.sk-gl__btn:hover { transform: translateY(-2px); }

@media (prefers-reduced-motion: reduce) {
  .sk-gl__layer { animation: none !important; }
  .sk-gl__btn { transition: none; }
}
JavaScript
// このデモは CSS アニメーションのみで完結。JSは不要。

コード

HTML
<!-- ホバーで RGB チャンネルをずらすグリッチ風エフェクト -->
<div class="stage">
  <figure class="glitch" tabindex="0" aria-label="グリッチ画像">
    <!-- 同じ画像を3枚重ね、R/G/B 風に色付け&ずらす -->
    <img class="glitch__layer glitch__layer--r" src="https://picsum.photos/id/1062/800/600" alt="">
    <img class="glitch__layer glitch__layer--g" src="https://picsum.photos/id/1062/800/600" alt="">
    <img class="glitch__layer glitch__layer--b" src="https://picsum.photos/id/1062/800/600" alt="グリッチ対象画像">
    <figcaption class="glitch__cap" data-text="GLITCH">GLITCH</figcaption>
  </figure>
</div>
CSS
* { box-sizing: border-box; }
body {
  margin: 0;
  min-height: 100vh;
  display: grid;
  place-items: center;
  background: #07070b;
  font-family: "Courier New", monospace;
}
.stage { padding: 24px; }

.glitch {
  position: relative;
  width: min(64vw, 380px);
  aspect-ratio: 4 / 3;
  margin: 0;
  border-radius: 10px;
  overflow: hidden;
  cursor: pointer;
  outline: none;
  box-shadow: 0 18px 45px -15px rgba(0, 0, 0, .8);
}

/* 3レイヤーを重ねる */
.glitch__layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* 通常時は B レイヤーだけ素のまま見せる */
.glitch__layer--r,
.glitch__layer--g { opacity: 0; mix-blend-mode: screen; }

/* ホバー / フォーカスでチャンネル分離&ずらし */
.glitch:hover .glitch__layer--r,
.glitch:focus-visible .glitch__layer--r {
  opacity: .85;
  filter: sepia(1) saturate(6) hue-rotate(-50deg);
  animation: shiftR .35s steps(2) infinite;
}
.glitch:hover .glitch__layer--g,
.glitch:focus-visible .glitch__layer--g {
  opacity: .85;
  filter: sepia(1) saturate(6) hue-rotate(70deg);
  animation: shiftG .3s steps(2) infinite;
}
.glitch:hover .glitch__layer--b,
.glitch:focus-visible .glitch__layer--b {
  filter: sepia(1) saturate(6) hue-rotate(170deg);
  animation: shiftB .4s steps(2) infinite;
}

/* 走査線を被せる */
.glitch::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0,
    rgba(0, 0, 0, .12) 2px,
    rgba(0, 0, 0, 0) 3px
  );
  pointer-events: none;
  opacity: 0;
  transition: opacity .3s ease;
}
.glitch:hover::after,
.glitch:focus-visible::after { opacity: 1; }

@keyframes shiftR {
  0% { transform: translate(0, 0); }
  100% { transform: translate(-5px, 2px); }
}
@keyframes shiftG {
  0% { transform: translate(0, 0); }
  100% { transform: translate(4px, -3px); }
}
@keyframes shiftB {
  0% { transform: translate(0, 0); }
  100% { transform: translate(2px, 3px); }
}

/* キャプション(グリッチ文字) */
.glitch__cap {
  position: absolute;
  left: 14px;
  bottom: 12px;
  z-index: 3;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: .3em;
  color: #fff;
}
.glitch:hover .glitch__cap,
.glitch:focus-visible .glitch__cap {
  text-shadow: 2px 0 #ff003c, -2px 0 #00e5ff;
}

@media (prefers-reduced-motion: reduce) {
  .glitch__layer { animation: none !important; }
}
JavaScript
// このデモは CSS アニメーションのみで完結。JSは不要。

🤖 AIエージェント用プロンプト

このままコピーしてAIに貼り付け「追加する場所」だけ書き換えればOK
あなたは熟練のフロントエンドエンジニアです。私のWebサイトに「RGBずらしグリッチ」の効果を追加してください。

# 追加してほしい効果
RGBずらしグリッチ(画像エフェクト)
同一画像を3枚重ねてチャンネルごとに着色・ずらし、走査線を被せたグリッチ風ホバーエフェクト。サイバー/音楽系サイトのアクセントに。

# 追加する場所
👉【ここに対象箇所を記入:例「トップのヒーローセクション」「お問い合わせボタン」「記事カードの一覧」など】

# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- ホバーで RGB チャンネルをずらすグリッチ風エフェクト -->
<div class="stage">
  <figure class="glitch" tabindex="0" aria-label="グリッチ画像">
    <!-- 同じ画像を3枚重ね、R/G/B 風に色付け&ずらす -->
    <img class="glitch__layer glitch__layer--r" src="https://picsum.photos/id/1062/800/600" alt="">
    <img class="glitch__layer glitch__layer--g" src="https://picsum.photos/id/1062/800/600" alt="">
    <img class="glitch__layer glitch__layer--b" src="https://picsum.photos/id/1062/800/600" alt="グリッチ対象画像">
    <figcaption class="glitch__cap" data-text="GLITCH">GLITCH</figcaption>
  </figure>
</div>

【CSS】
* { box-sizing: border-box; }
body {
  margin: 0;
  min-height: 100vh;
  display: grid;
  place-items: center;
  background: #07070b;
  font-family: "Courier New", monospace;
}
.stage { padding: 24px; }

.glitch {
  position: relative;
  width: min(64vw, 380px);
  aspect-ratio: 4 / 3;
  margin: 0;
  border-radius: 10px;
  overflow: hidden;
  cursor: pointer;
  outline: none;
  box-shadow: 0 18px 45px -15px rgba(0, 0, 0, .8);
}

/* 3レイヤーを重ねる */
.glitch__layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* 通常時は B レイヤーだけ素のまま見せる */
.glitch__layer--r,
.glitch__layer--g { opacity: 0; mix-blend-mode: screen; }

/* ホバー / フォーカスでチャンネル分離&ずらし */
.glitch:hover .glitch__layer--r,
.glitch:focus-visible .glitch__layer--r {
  opacity: .85;
  filter: sepia(1) saturate(6) hue-rotate(-50deg);
  animation: shiftR .35s steps(2) infinite;
}
.glitch:hover .glitch__layer--g,
.glitch:focus-visible .glitch__layer--g {
  opacity: .85;
  filter: sepia(1) saturate(6) hue-rotate(70deg);
  animation: shiftG .3s steps(2) infinite;
}
.glitch:hover .glitch__layer--b,
.glitch:focus-visible .glitch__layer--b {
  filter: sepia(1) saturate(6) hue-rotate(170deg);
  animation: shiftB .4s steps(2) infinite;
}

/* 走査線を被せる */
.glitch::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0,
    rgba(0, 0, 0, .12) 2px,
    rgba(0, 0, 0, 0) 3px
  );
  pointer-events: none;
  opacity: 0;
  transition: opacity .3s ease;
}
.glitch:hover::after,
.glitch:focus-visible::after { opacity: 1; }

@keyframes shiftR {
  0% { transform: translate(0, 0); }
  100% { transform: translate(-5px, 2px); }
}
@keyframes shiftG {
  0% { transform: translate(0, 0); }
  100% { transform: translate(4px, -3px); }
}
@keyframes shiftB {
  0% { transform: translate(0, 0); }
  100% { transform: translate(2px, 3px); }
}

/* キャプション(グリッチ文字) */
.glitch__cap {
  position: absolute;
  left: 14px;
  bottom: 12px;
  z-index: 3;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: .3em;
  color: #fff;
}
.glitch:hover .glitch__cap,
.glitch:focus-visible .glitch__cap {
  text-shadow: 2px 0 #ff003c, -2px 0 #00e5ff;
}

@media (prefers-reduced-motion: reduce) {
  .glitch__layer { animation: none !important; }
}

【JavaScript】
// このデモは CSS アニメーションのみで完結。JSは不要。

# 外部ライブラリ
なし(追加ライブラリ不要)

# 守ってほしいこと
- 既存のHTML構造・レイアウト・デザインを壊さないこと。必要に応じてクラス名・色・サイズを私のサイトに合わせて調整してよい。
- クラス名やidが既存と衝突しないよう、必要なら接頭辞で名前空間を分けること。
- レスポンシブ対応と prefers-reduced-motion への配慮を入れること。
- 私のサイトのフレームワーク(React / Vue / 素のHTML など)に合わせて実装すること。不明な場合は素のHTML/CSS/JSで提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。