はじめに
WordPressサイトでSVGアイコンを使ったアイキャッチ画像を作ろうとしたとき、画面サイズによってレイアウトが崩れる問題に直面しました。特に、固定サイズで作ったデザインがスマートフォンでは小さすぎたり、大画面では余白が多すぎたりと、バランスの取れた表示が難しい状況でした。
そこで、CSSのvw単位とclamp()関数を組み合わせることで1、どの画面サイズでも美しく表示されるレスポンシブなSVGアイキャッチを実現しました。
解決したい課題
従来の固定サイズでのSVGレイアウトには、いくつかの問題がありました。
まず、絶対位置指定(position: absolute)を使ったSVGの配置です。これは特定の画面サイズでは美しく見えるものの、ウィンドウサイズが変わると要素同士の位置関係が崩れてしまいます。レスポンシブデザインの基本に反する手法といえるでしょう2。
次に、メディアクエリによる段階的な調整の限界です。複数のブレークポイントを設定して、それぞれで異なるサイズを指定する方法では、ブレークポイント間でのサイズ変化が急激になります。また、様々なデバイスサイズに対応するために、多くのメディアクエリが必要になり、コードが複雑化していました。
SVGアイコンの準備
今回使用したSVGは、WordPressプラグインを表現するアイコンデザインです。青い円の背景に白いプラグインパーツ、緑色のベジェ曲線、そして左右にコードブラケット記号を配置した構成になっています。
<svg class="eyecatch-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" width="128" height="128">
<!-- 背景円 -->
<circle cx="64" cy="64" r="56" fill="#4A90E2"></circle>
<!-- WordPressプラグインピース -->
<g transform="translate(35, 35)">
<path d="M 8 8 L 42 8 Q 48 8 48 14 L 48 18 L 52 18 Q 58 18 58 24 L 58 34 Q 58 40 52 40 L 48 40 L 48 44 Q 48 50 42 50 L 8 50 Q 2 50 2 44 L 2 14 Q 2 8 8 8 Z" fill="#FFFFFF"></path>
</g>
<!-- SVGベクター線 -->
<g transform="translate(20, 45)">
<path d="M 15 25 Q 35 15 55 25 Q 75 35 88 25" stroke="#7ED321" stroke-width="4" fill="none" stroke-linecap="round"></path>
<circle cx="35" cy="20" r="2" fill="#7ED321"></circle>
<circle cx="75" cy="30" r="2" fill="#7ED321"></circle>
</g>
<!-- コードブラケット -->
<g transform="translate(25, 75)">
<path d="M 6 8 L 2 12 L 6 16" stroke="#FFFFFF" stroke-width="3" fill="none" stroke-linecap="round"></path>
<path d="M 72 8 L 76 12 L 72 16" stroke="#FFFFFF" stroke-width="3" fill="none" stroke-linecap="round"></path>
</g>
</svg>
Code language: HTML, XML (xml)
このSVGをHTMLのh1タイトル要素内に直接配置し、タイトルテキストと組み合わせて表示します。
最初のアプローチ:固定サイズと絶対位置指定
当初は、以下のようなCSSで実装していました。
.single .inside-article .entry-header h1.entry-title {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
height: 200px;
top: 202px;
font-size: 36px;
line-height: 1.4em;
margin: 30px;
font-weight: 700;
}
.single .inside-article .entry-header h1.entry-title .eyecatch-svg {
position: absolute;
top: -200px;
height: 180px;
width: 180px;
}
Code language: CSS (css)
この方法では、SVGを絶対位置で上部に配置し、テキストを下部に固定していました。デスクトップでは問題なく表示されるものの、画面サイズが変わると要素の配置バランスが崩れてしまいます。
改善アプローチ:Flexboxレイアウトへの変更
まず、絶対位置指定を廃止し、Flexboxレイアウトに変更しました。
.single .inside-article .entry-header {
height: 480px;
background: beige;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.single .inside-article .entry-header h1.entry-title {
position: static;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: auto;
max-width: 800px;
font-size: 36px;
line-height: 1.4em;
margin: 30px;
font-weight: 700;
text-align: center;
gap: 20px;
}
.single .inside-article .entry-header h1.entry-title .eyecatch-svg {
position: static;
height: 128px;
width: 128px;
flex-shrink: 0;
}
Code language: CSS (css)
Flexboxのflex-direction: columnでSVGとテキストを縦に並べ、gapプロパティで要素間の間隔を制御します。flex-shrink: 0により、SVGのサイズが意図せず縮小されることを防ぎます。
vw単位とclamp関数による動的調整
Flexboxレイアウトでの基本構造ができたところで、画面サイズに応じた動的調整を実装しました。ここで重要な役割を果たすのが、vw単位とclamp()関数です。
vw単位の特徴
vw(viewport width)は、ビューポート幅の1%を表す単位です。画面幅が1000pxの場合、1vwは10pxに相当します3。この単位を使うことで、画面サイズに比例したスケーリングが可能になります。
clamp関数の活用
clamp(最小値, 理想値, 最大値)関数は、理想値を基準としながら最小値と最大値の範囲内で値を制限します。これにより、極端に小さな画面や大きな画面での表示問題を防げます。
最終的な実装は以下のようになりました。
.single .inside-article .entry-header {
height: clamp(280px, 40vw, 480px);
background: beige;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.single .inside-article .entry-header h1.entry-title {
position: static;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: auto;
max-width: min(800px, 90vw);
font-size: clamp(20px, 3.2vw, 36px);
line-height: 1.6em;
margin: clamp(15px, 3vw, 30px);
font-weight: 700;
text-align: center;
gap: clamp(10px, 2vw, 20px);
}
.single .inside-article .entry-header h1.entry-title .eyecatch-svg {
position: static;
height: clamp(120px, 15vw, 152px);
width: clamp(120px, 15vw, 152px);
flex-shrink: 0;
margin: auto;
}
Code language: CSS (css)
各要素の調整ポイント
ヘッダー全体の高さはclamp(280px, 40vw, 480px)で設定しました。小さな画面では280px、大きな画面では480pxを上限とし、中間サイズでは画面幅の40%で動的に調整されます。
SVGサイズはclamp(120px, 15vw, 152px)で、画面幅の15%を基準にスケーリングします。最小120px、最大152pxの範囲で制限することで、極端なサイズ変化を防いでいます。
フォントサイズはclamp(20px, 3.2vw, 36px)で調整しました。SVGが大きめに設定されているため、フォントサイズの増加率は3.2vwと控えめにして、全体のバランスを保っています。
ブログ一覧での統一表示
個別記事だけでなく、ブログ一覧でも同じSVGアイコンを表示することで、サイト全体の統一感を高めました。
.blog .inside-article .entry-title .eyecatch-svg,
.archive .inside-article .entry-title .eyecatch-svg {
width: 64px;
height: 64px;
display: block;
position: absolute;
left: 0px;
top: 0px;
}
.blog .inside-article,
.archive .inside-article {
padding-left: 80px;
position: relative;
}
Code language: CSS (css)
ブログ一覧では64pxの固定サイズでSVGを左上に配置し、記事タイトルとの視覚的な関連性を明確にしています。
レスポンシブ戦略の最適化
最終的な実装では、画面サイズに応じて異なる戦略を採用しました。
極端に小さな画面(480px以下)では、vwベースの計算が適切に機能しない場合があるため、固定値を使用します4。
@media (max-width: 480px) {
.single .inside-article .entry-header {
height: 240px;
}
.single .inside-article .entry-header h1.entry-title {
font-size: 18px;
margin: 10px;
gap: 8px;
}
.single .inside-article .entry-header h1.entry-title .eyecatch-svg {
height: 120px;
width: 120px;
}
}
Code language: CSS (css)
逆に、非常に大きな画面(1200px以上)では、要素が過度に大きくなることを防ぐため、上限値で固定します。
@media (min-width: 1200px) {
.single .inside-article .entry-header {
height: 480px;
}
.single .inside-article .entry-header h1.entry-title {
font-size: 36px;
margin: 30px;
gap: 20px;
}
.single .inside-article .entry-header h1.entry-title .eyecatch-svg {
height: 152px;
width: 152px;
}
}
Code language: CSS (css)
実装の効果と改善点
この実装により、以下の改善が達成されました。
まず、画面サイズに関係なく一貫したデザインバランスが保たれるようになりました。SVGとテキストの比率が画面幅に応じて適切にスケーリングされるため、どのデバイスでも美しい表示が実現できます。
次に、メディアクエリの大幅な削減です。従来は複数のブレークポイントでそれぞれ異なる値を設定していましたが、clamp()とvwの組み合わせにより、メディアクエリは極端なケースのみに限定できました。
また、コードの保守性も向上しました。値の調整が必要な場合、clamp()の引数を変更するだけで全体のスケーリングを調整できるため、メンテナンスが容易になります。
まとめ
WordPressでSVGアイキャッチアイコンの完全レスポンシブ化を実現するには、固定サイズと絶対位置指定を避け、Flexboxレイアウトを基盤とすることが重要です5。その上で、vw単位とclamp()関数を組み合わせることで、画面サイズに応じた滑らかなスケーリングが可能になります。極端な画面サイズではメディアクエリによる制限を併用し、実用的なレスポンシブデザインを構築できます。
- clamp() – CSS | MDN – CSS clamp()関数の公式仕様と使用例、パラメータの詳細解説
- Basic concepts of flexbox – CSS | MDN – Flexboxレイアウトの基本概念と軸の概念、プロパティの動作原理
- Modern Fluid Typography Using CSS Clamp — Smashing Magazine – clamp()を使った流体タイポグラフィの実装とアクセシビリティ配慮
- CSS Viewport Units: vh, vw, vmin, and vmax — SitePoint – ビューポート単位(vw、vh)の詳細解説とレスポンシブデザインでの活用法
- CSS min(), max(), and clamp() | Articles | web.dev – Googleによるmin()、max()、clamp()関数の実用的な使用例とベストプラクティス
- How to Enable SVG Support in WordPress (Most Secure Methods) – WordPressでのSVGファイル安全な有効化方法とセキュリティ対策
- Complete Guide to Flexbox | CSS-Tricks – Flexboxプロパティの包括的なリファレンスと実装パターン集
- clamp()関数は2020年7月以降、主要ブラウザでサポートされており、現在のブラウザ互換性スコアは92%となっています。 – CSS clamp() Function Browser Support | Can I Use
- Flexboxは2015年のSafari 9リリース以降、主要ブラウザで完全にサポートされており、モダンなレスポンシブレイアウトの標準的な手法となっています。 – CSS Flexible Box Layout Module | Can I Use
- モバイルSafariでは、アドレスバーの表示・非表示によってビューポートが変化する問題があります。iOS 8以降、この問題を解決するために固定値ベースの計算方式が採用されています。 – The trick to viewport units on mobile | CSS-Tricks
- モバイルデバイスでのビューポート単位には、アドレスバーの動的表示による問題があります。新しいdvh、svh、lvh単位がこれらの問題を解決するために策定されましたが、まだブラウザサポートが限定的です。 – The large, small, and dynamic viewport units | web.dev
- WordPressはセキュリティ上の理由からSVGファイルのアップロードをデフォルトで無効にしています。SVGファイルはXMLベースであり、悪意のあるコードを含む可能性があるためです。Safe SVGなどのプラグインを使用することで安全にSVGファイルを利用できます。 – How to Enable SVG Support in WordPress (Most Secure Methods)