ビジュアル
CSSとJSで作る、SVGフィルターで奥行きを生み出す文字エフェクト
2026/03/26
2026/3/23
印象的なタイトルやイベントロゴでは、文字そのものに存在感を持たせる演出が効果的です。
このサンプルではSVGフィルターを活用し、通常のテキストに奥行きを与えて立体的に見せるエフェクトを実装しています。
画像を使わずリアルタイムで生成されるため、高解像度でも劣化せず柔軟にカスタマイズできるのが特徴です。
Preview プレビュー
Code コード
<svg class="kumonosu-svg-assets" aria-hidden="true">
<filter id="kumonosu-extrude">
<feConvolveMatrix id="kumonosu-cm" in="SourceAlpha" order="16" divisor="1" />
<feOffset dx="8" dy="8" result="side" />
<feOffset dx="16" dy="16" />
<feBlend in="side" />
<feComposite in2="SourceAlpha" operator="out" result="extr" />
<feColorMatrix in="SourceGraphic" values="0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 1 0 0 0" />
<feBlend in2="extr" />
</filter>
</svg>
<h1 class="kumonosu-title"> kumonosu<br> festival<span class="kumonosu-year">2025</span>
</h1>
@import url('https://fonts.googleapis.com/css2?family=Teko:wght@700&display=swap');
html, body {
display: grid;
margin: 0;
padding: 0;
overflow-x: hidden;
}
html {
height: 100%;
background: #000;
}
.kumonosu-svg-assets {
position: fixed;
width: 0;
height: 0;
}
.kumonosu-title {
place-self: center;
margin: 0;
width: max-content;
transform: skewy(-9deg);
font-family: 'Teko', sans-serif;
font-weight: 700;
font-size: clamp(3.5rem, 15vw, 8rem);
line-height: 1.1cap;
text-transform: uppercase;
letter-spacing: -0.01em;
filter: url(#kumonosu-extrude) invert(1);
}
.kumonosu-year {
display: inline-block;
position: relative;
margin-left: 0.1em;
padding: 0 .25em;
width: 2ch;
border-radius: .125em;
box-shadow: 0 -.2lh #000;
background: #000;
color: #fff;
font-size: 0.5em;
line-height: 1.25cap;
word-wrap: break-word;
vertical-align: top;
}
@media (max-width: 480px) {
.kumonosu-title {
transform: skewy(-7deg);
}
}
const kumonosu_n = 16;
const kumonosu_im = (new Array(kumonosu_n * kumonosu_n)).fill(0).map((_, i) => 1 * !(i % (kumonosu_n + 1)));
document.getElementById('kumonosu-cm').setAttribute('kernelMatrix', kumonosu_im.join(' '));
Explanation 詳しい説明
概要
このコードはCSSとJavaScript、SVGフィルターを組み合わせて、文字に奥行きを与え立体的に見せるテキストエフェクトを実装しています。
text-shadowを重ねる方法とは異なり、SVGフィルターによる画像処理を利用して厚みを生成しているため、滑らかで一体感のある立体表現になるのが特徴です。画像素材を使用せず、通常のHTMLテキストをそのまま加工して表現しています。
仕様
SVGフィルターによる奥行き生成
feConvolveMatrixを使用して文字のアルファ情報を一定方向へ拡張し、側面のような領域を生成しています。
処理の流れは以下の通りです。
- テキストのアルファ情報を取得
- 行列演算でピクセルを斜め方向へ複製
- オフセットで奥行き位置を調整
- 元の文字と合成して立体感を作成
押し出し計算の仕組み
JavaScriptでカーネル行列を生成し、フィルターへ動的に適用しています。
const n = 16;
この値によって奥行きの密度や厚みが変化します。
const im = (new Array(n * n)).fill(0).map((_, i) => 1 * !(i % (n + 1)));
対角線状の行列を生成することで、一定方向へ伸びる奥行き表現を作っています。
色反転処理
filter: url(#extrude) invert(1);
フィルター適用後に色を反転させ、背景とのコントラストを強調しています。
レスポンシブ文字サイズ
font-size: clamp(3.5rem, 15vw, 8rem);
画面幅に応じて文字サイズが自然に変化するよう設定されています。
カスタムできるポイント
奥行きの強さ変更
const n = 16;
数値を大きくすると厚みが強くなり、小さくすると控えめな表現になります。
奥行き方向の変更
kernelMatrixの生成方法を変更することで、左右方向や上下方向への奥行き表現にも変更できます。
立体の角度調整
<feOffset dx="8" dy="8" />
数値を調整することで奥行きの向きや影の角度を変更できます。
デザイン変更
HTMLテキストとして扱われるため、次の要素を自由に変更できます。
- フォント
- 文字内容
- 配色
- サイズ
- レイアウト
注意点
SVGフィルターは描画コストが比較的高いため、大きな文字サイズや複数同時使用ではパフォーマンスに影響する場合があります。
ブラウザによってフィルター描画結果がわずかに異なる場合があります。特にモバイル環境では表示差が出る可能性があります。
filterを重ねすぎると描画負荷が増えるため、blurやshadow系エフェクトとの併用には注意が必要です。
画像ではなくテキストとして描画されるため、コピーやテキスト選択が可能です。