SVGノイズ質感

feTurbulence で生成した粒状ノイズをグラデーションに重ね、上質なマット質感を演出。ボタンでノイズの粗さを切り替えられます。

#svg#css#texture

ライブデモ

使用例(お題: カフェ MOON BREW)

この技法を「カフェ MOON BREW」というテーマのダミーサイトで実際に使った例です。

HTML
<!-- MOON BREW:SVGノイズで紙のようなマット質感を出したメニュー -->
<section class="mn-menu">
  <!-- ★主役:feTurbulence のノイズ質感(粗さは切替可能) -->
  <svg class="mn-noise" id="mnNoise" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
    <filter id="mnGrain">
      <feTurbulence type="fractalNoise" baseFrequency="0.8" numOctaves="2" stitchTiles="stitch"/>
    </filter>
    <rect width="100%" height="100%" filter="url(#mnGrain)"/>
  </svg>

  <header class="mn-head">
    <div class="mn-brand">☕ MOON BREW</div>
    <p class="mn-since">自家焙煎珈琲 ・ since 2014</p>
  </header>

  <h2 class="mn-cat">本日のドリップ</h2>
  <ul class="mn-list">
    <li>
      <span class="mn-name">ムーンブレンド<small>深煎り・チョコの余韻</small></span>
      <span class="mn-price">¥520</span>
    </li>
    <li>
      <span class="mn-name">琥珀ハニーラテ<small>はちみつとミルクの甘み</small></span>
      <span class="mn-price">¥620</span>
    </li>
    <li>
      <span class="mn-name">エチオピア 浅煎り<small>柑橘と花の香り</small></span>
      <span class="mn-price">¥580</span>
    </li>
  </ul>

  <button class="mn-toggle" id="mnToggle" type="button">ざらつき:標準</button>
</section>
CSS
/* MOON BREW:クリーム×濃ブラウン。SVGノイズで紙のマット質感を演出 */
* { box-sizing: border-box; margin: 0; padding: 0; }

.mn-menu {
  position: relative;
  min-height: 400px;
  height: 400px;
  overflow: hidden;
  padding: 26px 30px;
  /* クリーム地に琥珀のグラデ。ここにノイズを重ねる */
  background:
    radial-gradient(120% 80% at 80% 0%, #f7efe3 0%, #efe2cf 55%, #e6d4bb 100%);
  color: #2b1d12;
  font-family: "Hiragino Mincho ProN", "Yu Mincho", "Segoe UI", serif;
}

/* ★主役:feTurbulence で作った粒状ノイズを全面に soft-light で重ねる */
.mn-noise {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  opacity: 0.5;
  mix-blend-mode: soft-light;
  pointer-events: none;
}

.mn-head, .mn-cat, .mn-list, .mn-toggle { position: relative; z-index: 1; }

.mn-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  border-bottom: 1.5px solid rgba(43,29,18,0.25);
  padding-bottom: 12px;
}
.mn-brand {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: 0.06em;
  color: #2b1d12;
}
.mn-since { font-size: 11px; color: #7a6450; letter-spacing: 0.08em; }

.mn-cat {
  margin: 20px 0 12px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: #c98a3b;
}

.mn-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.mn-list li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
/* 価格までを点線リーダーでつなぐ(メニューらしさ) */
.mn-list li::after {
  content: "";
  flex: 1;
  order: 1;
  margin: 0 4px 4px;
  border-bottom: 1.5px dotted rgba(43,29,18,0.35);
}
.mn-name {
  order: 0;
  font-size: 16px;
  font-weight: 700;
  display: flex;
  flex-direction: column;
}
.mn-name small {
  font-size: 11px;
  font-weight: 400;
  color: #8a715a;
  margin-top: 3px;
  letter-spacing: 0.02em;
}
.mn-price {
  order: 2;
  font-size: 16px;
  font-weight: 800;
  color: #2b1d12;
}

.mn-toggle {
  position: absolute;
  right: 24px;
  bottom: 20px;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  color: #fff;
  background: #2b1d12;
  border: none;
  padding: 8px 16px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.2s ease;
}
.mn-toggle:hover { background: #c98a3b; transform: translateY(-1px); }
.mn-toggle:active { transform: scale(0.97); }
JavaScript
// ノイズの粗さ(baseFrequency)を3段階で切り替え、紙質感の見え方を変える
(() => {
  const toggle = document.getElementById("mnToggle");
  const noise = document.getElementById("mnNoise");
  if (!toggle || !noise) return; // null安全

  const turb = noise.querySelector("feTurbulence");
  if (!turb) return;

  // 細かい→標準→粗い の3段階を巡回
  const levels = [
    { f: "1.2", label: "ざらつき:細かい" },
    { f: "0.8", label: "ざらつき:標準" },
    { f: "0.45", label: "ざらつき:粗い" },
  ];
  let i = 1; // 初期は標準

  toggle.addEventListener("click", () => {
    i = (i + 1) % levels.length;
    const lv = levels[i];
    turb.setAttribute("baseFrequency", lv.f);
    toggle.textContent = lv.label;
  });
})();

コード

HTML
<!-- SVGノイズ質感: feTurbulence のノイズをグラデに重ねてザラついた紙の質感を出す -->
<div class="noise-stage">
  <!-- SVGフィルタでノイズを生成(描画はCSS背景として利用) -->
  <svg class="noise-defs" aria-hidden="true">
    <filter id="grain">
      <feTurbulence type="fractalNoise" baseFrequency="0.85" numOctaves="3" stitchTiles="stitch"/>
      <feColorMatrix type="saturate" values="0"/>
    </filter>
    <rect width="100%" height="100%" filter="url(#grain)"/>
  </svg>

  <div class="noise-card">
    <h1 class="noise-title">Grain Texture</h1>
    <p class="noise-sub">feTurbulence で生成した粒状ノイズをグラデーションに重ね、上質なマット質感を演出します。</p>
    <button class="noise-btn" type="button">テクスチャを楽しむ</button>
  </div>
</div>
CSS
/* グラデ地 + SVGノイズのオーバーレイで質感を作る */
* { box-sizing: border-box; margin: 0; padding: 0; }

.noise-stage {
  position: relative;
  min-height: 360px;
  display: grid;
  place-items: center;
  overflow: hidden;
  font-family: "Segoe UI", "Hiragino Sans", system-ui, sans-serif;
  /* ベースの暖色グラデ */
  background:
    radial-gradient(120% 120% at 30% 0%, #3a2d5c 0%, #1b1430 55%, #0c0a1a 100%);
}

/* ノイズを敷くSVG: stage全面に絶対配置し、乗算で重ねる */
.noise-defs {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0.42;
  mix-blend-mode: overlay;
  pointer-events: none;
}

/* 上品なビネット */
.noise-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(100% 100% at 50% 50%, transparent 55%, rgba(0,0,0,0.55) 100%);
  pointer-events: none;
}

.noise-card {
  position: relative;
  z-index: 2;
  text-align: center;
  color: #f3eefc;
  max-width: 460px;
  padding: 0 26px;
}

.noise-title {
  font-size: 42px;
  font-weight: 800;
  letter-spacing: 0.02em;
  background: linear-gradient(90deg, #ffd9a0, #ff9ec7, #c9a0ff);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.noise-sub {
  margin-top: 14px;
  font-size: 14px;
  line-height: 1.85;
  color: rgba(243, 238, 252, 0.82);
}

.noise-btn {
  margin-top: 22px;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  color: #1b1430;
  padding: 12px 26px;
  border: none;
  border-radius: 999px;
  cursor: pointer;
  background: linear-gradient(90deg, #ffd9a0, #ff9ec7);
  box-shadow: 0 10px 30px rgba(255, 158, 199, 0.35);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.noise-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 14px 36px rgba(255, 158, 199, 0.5);
}
JavaScript
// ノイズの粗さ(baseFrequency)をボタンで切り替え、質感の違いを体感させる
(() => {
  const turb = document.querySelector("#grain feTurbulence");
  const btn = document.querySelector(".noise-btn");
  if (!turb || !btn) return; // null安全

  // 粗→細の3段階を巡回
  const freqs = ["0.85", "0.45", "1.2"];
  let i = 0;

  btn.addEventListener("click", () => {
    i = (i + 1) % freqs.length;
    turb.setAttribute("baseFrequency", freqs[i]);
  });
})();

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

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

# 追加してほしい効果
SVGノイズ質感(背景 & グラデーション)
feTurbulence で生成した粒状ノイズをグラデーションに重ね、上質なマット質感を演出。ボタンでノイズの粗さを切り替えられます。

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

# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- SVGノイズ質感: feTurbulence のノイズをグラデに重ねてザラついた紙の質感を出す -->
<div class="noise-stage">
  <!-- SVGフィルタでノイズを生成(描画はCSS背景として利用) -->
  <svg class="noise-defs" aria-hidden="true">
    <filter id="grain">
      <feTurbulence type="fractalNoise" baseFrequency="0.85" numOctaves="3" stitchTiles="stitch"/>
      <feColorMatrix type="saturate" values="0"/>
    </filter>
    <rect width="100%" height="100%" filter="url(#grain)"/>
  </svg>

  <div class="noise-card">
    <h1 class="noise-title">Grain Texture</h1>
    <p class="noise-sub">feTurbulence で生成した粒状ノイズをグラデーションに重ね、上質なマット質感を演出します。</p>
    <button class="noise-btn" type="button">テクスチャを楽しむ</button>
  </div>
</div>

【CSS】
/* グラデ地 + SVGノイズのオーバーレイで質感を作る */
* { box-sizing: border-box; margin: 0; padding: 0; }

.noise-stage {
  position: relative;
  min-height: 360px;
  display: grid;
  place-items: center;
  overflow: hidden;
  font-family: "Segoe UI", "Hiragino Sans", system-ui, sans-serif;
  /* ベースの暖色グラデ */
  background:
    radial-gradient(120% 120% at 30% 0%, #3a2d5c 0%, #1b1430 55%, #0c0a1a 100%);
}

/* ノイズを敷くSVG: stage全面に絶対配置し、乗算で重ねる */
.noise-defs {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0.42;
  mix-blend-mode: overlay;
  pointer-events: none;
}

/* 上品なビネット */
.noise-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(100% 100% at 50% 50%, transparent 55%, rgba(0,0,0,0.55) 100%);
  pointer-events: none;
}

.noise-card {
  position: relative;
  z-index: 2;
  text-align: center;
  color: #f3eefc;
  max-width: 460px;
  padding: 0 26px;
}

.noise-title {
  font-size: 42px;
  font-weight: 800;
  letter-spacing: 0.02em;
  background: linear-gradient(90deg, #ffd9a0, #ff9ec7, #c9a0ff);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.noise-sub {
  margin-top: 14px;
  font-size: 14px;
  line-height: 1.85;
  color: rgba(243, 238, 252, 0.82);
}

.noise-btn {
  margin-top: 22px;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  color: #1b1430;
  padding: 12px 26px;
  border: none;
  border-radius: 999px;
  cursor: pointer;
  background: linear-gradient(90deg, #ffd9a0, #ff9ec7);
  box-shadow: 0 10px 30px rgba(255, 158, 199, 0.35);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.noise-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 14px 36px rgba(255, 158, 199, 0.5);
}

【JavaScript】
// ノイズの粗さ(baseFrequency)をボタンで切り替え、質感の違いを体感させる
(() => {
  const turb = document.querySelector("#grain feTurbulence");
  const btn = document.querySelector(".noise-btn");
  if (!turb || !btn) return; // null安全

  // 粗→細の3段階を巡回
  const freqs = ["0.85", "0.45", "1.2"];
  let i = 0;

  btn.addEventListener("click", () => {
    i = (i + 1) % freqs.length;
    turb.setAttribute("baseFrequency", freqs[i]);
  });
})();

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

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