SVGで動的なバナーを実装してみた

ホスティングサービス「ConoHa」では、各サービスで毎月1~2回ほどキャンペーンを実施しています。
更新頻度が高い上、キャンペーンごとにLPやバナーを作成・実装する必要があり、デザイナー・フロントエンドエンジニアにとってはできるだけ効率化したい業務のひとつです。
今回紹介するのは、フロントエンド側の効率化の一環としてトップページのバナーを自動化した仕組みについてです。

キャンペーンバナーをSVGに置き換えてみた

フロントエンド側の効率化の一環としてトップページのバナーを自動化した仕組みについてです。
デザイナーが毎回新しい画像を制作する代わりに、SVGに置き換えることでキャンペーン名や金額を自動で切り替わるようにしました。

下記キャプチャが実際に実装したバナーです。

パソコン(PC)でもスマートフォン(SP)でもデザインを保ったままきれいに表示されています。

divによる実装との違い

divで実装してみる

最初はdiv要素内にpでテキストを配置し、CSSでスタイルを付けて実装してみました。
一番簡単な方法ですが、拡大・縮小したときに領域に対してテキストの相対的なバランスが崩れるのがネックでした。

フォントサイズに相対値を設定できれば良いのですが、親要素に対しての相対値が設定できないため断念しました。

SVGで実装してみる

上記に対して汎用性があり、レスポンシブと相性の良い実装方法として思い付いたのが今回のSVGによる実装です。
SVGの場合、ビューボックス(viewBox属性)を設定することで内包した要素もビューボックスを基準に相対的にレンダリングされます。そのため、拡大・縮小してもテキスト含めバランスを保つことができます。

また、ラスター画像と違ってSVG内のtext要素はテキストの選択やコピーができます。SEOに対する効果は分かりませんが、画像のalt属性よりも情報量を多くできる点もメリットといえます。
テキストの邪魔にならないよう、装飾目的のオブジェクトには pointer-events: none; を設定しておくのがおすすめです。

SVGの書き方

Adobe Illustratorなどで制作したSVGファイルを利用することはありますが、ソースコードとして書く機会はあまり無いため知らないタグや属性も多く、その点苦戦した一方であまり時間をかけることなく実装することができました。

以下がConoHa WINGのキャンペーンバナーの実際のソースコードです。

<svg viewBox="0 0 560 210" class="bannerType02 is-wing">
	<defs>
		<clipPath id="bannerType02Clippath">
			<rect x="0" y="0" rx="12" ry="12" />
		</clipPath>
	</defs>
	<g class="bannerType02Background">
		<rect x="0" y="0" rx="12" ry="12" />
		<image href="/common_38448/images/banners/forSVG/wing_campaign-top.png" x="0" y="0"></image>
	</g>
	<g class="bannerType02Title">
		<text x="50%" y="42" text-anchor="middle"><?php echo $campaign_name; ?></text>
	</g>
	<g class="bannerType02Subtitle">
		<g class="bannerType02Subtitle_background">
			<circle cx="90" cy="100" r="50" />
		</g>
		<g class="bannerType02Subtitle_text">
			<text x="52" y="97">レンタル</text>
			<text x="52" y="118">サーバー</text>
		</g>
	</g>
	<?php if($_is_typeA): ?>
		<g class="bannerType02Off">
			<g class="bannerType02Off_label">
				<text x="154" y="105">最</text>
				<text x="150" y="135">大</text>
			</g>
			<g class="bannerType02Off_number">
				<text x="242" y="142" text-anchor="middle" style="letter-spacing: <?php echo $letterspacing; ?>em;"><?php echo $campaign_price; ?></text>
				<text x="308" y="142">%OFF</text>
			</g>
		</g>
	<?php else: ?>
		<g class="bannerType02Price">
			<g class="bannerType02Price_label">
				<text x="154" y="105">月</text>
				<text x="150" y="135">額</text>
			</g>
			<g class="bannerType02Price_number">
				<text x="283" y="142" text-anchor="middle" style="letter-spacing: <?php echo $letterspacing; ?>em;"><?php echo $campaign_price; ?></text>
				<text x="394" y="136">円~</text>
			</g>
		</g>
	<?php endif; ?>
	<g class="bannerType02Term">
		<g class="bannerType02Term_background">
			<rect x="0" y="158" />
		</g>
		<g class="bannerType02Term_label">
			<rect x="60" y="167"></rect>
			<text x="79" y="191">期間限定</text>
		</g>
		<g class="bannerType02Term_date">
			<text x="190" y="193">
				<tspan><?php echo $campaign_date_year; ?></tspan>年
				<tspan><?php echo $campaign_date_month; ?></tspan>月
				<tspan><?php echo $campaign_date_date; ?></tspan>日(<?php echo $campaign_date_day; ?>)
				<tspan><?php echo $campaign_date_hour; ?></tspan>時まで
			</text>
		</g>
	</g>
	<g class="bannerType02Frame">
		<rect x="0" y="0" rx="12" ry="12" />
	</g>
</svg>

以下基本的なタグや属性を紹介いたします。
また、ソースコードに不慣れなデザイナーさん向けに概念をAdobe Illustratorの機能に置き換えた説明をこの色で併記してあります。

svg

まずはsvgタグで囲みます。これがキャンバス領域アートボード)となります。

  • viewBox
    前述の通り、キャンバスサイズを設定するための属性です。4つの数値がセットとなります。
    • min-x(0)
      ビューポート(キャンバスの内、実際に表示される領域)の基点のX軸です。基本的には左上を設定しますので、0となります。
      アートボードを編集 > 変形 > X
    • min-y(0)
      ビューポートの基点のY軸です。基本的には左上を設定しますので、0となります。
      アートボードを編集 > 変形 > Y
    • width(560)
      キャンバスの横幅です。
      今回ベースとなったバナー画像が280×105、レティーナ対応で2倍で作られていたため、そのデザインファイルを参照しやすいよう同じサイズを設定しました。
      アートボードを編集 > 変形 > W
    • height(210)
      キャンバスの高さです。同上。
      アートボードを編集 > 変形 > H
  • class
    一般的なHTMLタグ同様、クラスを付けてCSSでスタイルを設定することもできます。今回は商材サイト内で使い回しやすいよう、一部のスタイルはCSSファイルに書いています。

defs

defsタグは目に見える形で表示されないSVGの設定などを書くためのタグです。
スタイルを定義するstyle、グラデーションの色合いを定義するlinearGradient、今回利用したクリップパスの形状を定義するclipPathなどはdefs内に書きます。

clipPath

clipPathタグはキャンバス内のオブジェクトを任意の形状に切り抜くための設定です。切り抜く形状自体はclipPathタグ内にパスを書きます。
今回のバナーは角丸のデザインなので、角丸の長方形で切り抜くために書いています。id属性で命名し、適用したい場所で呼び出すことができます。
オブジェクト > クリッピングマスク > 作成

g

gタグはオブジェクトのグルーピングを設定するタグです。
今回の場合、CSSでスタイルを付けるのに便利だったため各オブジェクトを機能別にグルーピングしています。
オブジェクト > グループ

image

imageタグは画像ファイルを埋め込むためのタグです。
ファイル > 配置

  • x
    画像を配置したい基点(左上)のX軸
    プロパティ > 変形 > (基準点を左上とした状態の)X
  • y
    画像を配置したい基点(左上)のY軸
    プロパティ > 変形 > (基準点を左上とした状態の)Y
  • src
    画像のファイルパス
    プロパティ > リンクファイル

text

textタグはテキストを配置するためのタグです。
文字ツール

  • x
    テキストを配置したい基点(後述のtext-anchor属性)のX軸
    プロパティ > 変形 > X
  • y
    テキストを配置したい基点(ベースライン)のY軸
    プロパティ > 変形 > Y
  • text-anchor
    テキストを配置する基点をstart/middle/endで設定します。xで設定された座標が始点になります。
    プロパティ > 段落 > 左揃え/中央揃え/右揃え

tspan

tspanタグはテキストの一部をグルーピングするためのタグです。HTMLでいうspanにあたります。
今回は「期間限定」の数字のみ別フォントを充てるためにtspanタグで囲っています。

rect

rectタグは長方形を作るためのタグです。形状そのものは属性によって設定します。
長方形ツール

  • x
    長方形を配置したい基点(左上)のX軸
    プロパティ > 変形 > (基準点を左上とした状態の)X
  • y
    長方形を配置したい基点(左上)のY軸
    プロパティ > 変形 > (基準点を左上とした状態の)Y
  • rx
    角丸の半径の横幅
    変形 > 長方形のプロパティ > 角丸の半径(IllustratorではX軸・Y軸の半径は変えられない)
  • ry
    角丸の半径の高さ
    変形 > 長方形のプロパティ > 角丸の半径(IllustratorではX軸・Y軸の半径は変えられない)

circle

circleタグは正円を作るためのタグです。
楕円形ツール

  • cx
    円の中心の座標のX軸
    プロパティ > 変形 > (基準点を中心とした状態の)X
  • cy
    円の中心の座標のY軸
    プロパティ > 変形 > (基準点を中心とした状態の)Y
  • r
    円の半径の長さ
    プロパティ > 変形 > WまたはHの半分

path

pathタグは座標の組み合わせで任意の形状のオブジェクトを作るためのタグです。
ConoHa WINGのバナーでは使っていませんが、ConoHa for GAMEのバナーの「長期割引パス」の囲みデザインに使っています。
ペンツール

  • x
    パスを配置したい基点(左上)のX軸
    プロパティ > 変形 > (基準点を左上とした状態の)X
  • y
    パスを配置したい基点(左上)のY軸
    プロパティ > 変形 > (基準点を左上とした状態の)Y
  • d
    パスのアンカーひとつひとつの座標データを繋げた文字列です。複雑な図形は特に算出するのが難しいため、Illustratorでパスを作成しSVGで保存し、テキストエディターで開いてコピーすると良いです。

CSSによるスタイル設定

SVGの属性の一部は、CSSに書き写すことができます。

<rect height="10" width="20" fill="#000"> ... </rect>

rect {
	height: 10px;
	width: 20px;
	fill: #000;
}
  • height
    オブジェクトの高さ
  • width
    オブジェクトの横幅
  • fill
    オブジェクトの塗り
  • stroke
    オブジェクトの線色
  • stroke-width
    オブジェクトの線幅

CSSに書ける属性と、属性として書かないと適用されないものがあります。どの属性がCSSのプロパティに置き換えられるかは、ドキュメントをご参照ください。

PHPとの組み合わせ

SVGは画像でありながらソースコードとして書くことができるため、PHPなどの言語と組み合わせることで内容やスタイルを動的に変更できます。
ConoHaの場合、PHPを介してデータを参照し、

  • キャンペーン名・料金・キャンペーン終了日などを変数に置き換えることで、キャンペーン切り替えの度に画像を作ったり文字を変えたりするような手間を省く
  • 「最大○○%OFF」「月額○○円~」という2パターンの見せ方を切り替える
  • 文字によって文字間を計算し、letter-spacingを設定する

などを実装しています。

Webフォントの併用がおすすめ

バナーをコーディングで実装するデメリットのひとつに、デザイナーが1枚1枚作った画像と比べてデザイン性に欠けることがあります。
そこでおすすめしたいのがWebフォントの利用です。

Webフォントは重いというイメージが先行して適用を渋るケースがありますが、フォントファイルの重さは含まれている文字の多さに依存します。日本語の場合は漢字・ひらがな・かたかな・アルファベット・記号…… と文字種が非常に多くなるため、フォントファイルが重くなる傾向にあります。

今回のバナーで英数字にあてたフォントは数字と「%」や「OFF」を表示するための数十文字に絞っているため、わずか2.5KBです。一般的なバナー画像1枚よりも軽くすることができます。

キャンペーン名にどのような文字が入ってくるか分からないため、今回のバナーはConoHaでデフォルトで利用しているNoto Sansを適用していますが、文字種が固定であればWebフォントを何種類か用意しておいて出し分けることでデザインにも幅を持たせることもできます

画像と動的SVGの合わせ技

上記のバナーで背景画像をimageタグで読み込んでいるように、SVGの中に画像を取り込んで一部だけ動的にすることもできます。

<svg viewBox="0 0 560 210">
	<defs>
		<style>
			.text{
				fill: #06c;
				font-size: 96px;
				font-weight: 400;
				letter-spacing: -0.01em;
				text-shadow: 2px 2px #ff0;
			}
		</style>
	</defs>
	<image href="画像パス" x="0" y="0" height="100%" width="100%"></image>
	<text x="270" y="158" text-anchor="end" class="text"><?php echo $campaign_price; ?></text>
</svg>

例えばこのように、imageタグで画像を読み込んだ上にtextタグで料金を重ねると、料金部分を動的にしつつ作り込んだデザインにすることができます。

デザインを保ちつつ$campaign_priceを変更するだけで数字を変えられるので、料金が変わる度に画像を制作する手間を減らせます。

ブログの著者欄

長谷川 由希子

GMOインターネットグループ株式会社

採用情報

関連記事

KEYWORD

採用情報

SNS FOLLOW

GMOインターネットグループのSNSをフォローして最新情報をチェック