BLOG

CSSとSVGでどんなフォントも綺麗に縁取りする魔法

どうも。春が近い=夏が近いと生き急いでいるかわゐです。
かわゐは生き急いでいますが、どうも自宅のクワガタムシの幼虫たちはそうでもないようです。

通常、1年ほどで成虫になる種類のクワガタムシが、2年近くかかっているのにまだ幼虫です。
これは大型になる可能性が高いのですが、その話をすると秋になるでしょう…。
夏は採集に行きたいので、この辺でやめておきます。

さて今回は、CSSとSVGと組み合わせる縁取り文字についてお話ししましょう。
最近のイカしたモダンなデザインの中に、縁だけにテキストカラーがついているデザインを見たことがある方も多いでしょう。
しかし、いざ実装しようとすると…

「うわ、線の引かれ方おかしい…」
「あ~画像にしないとダメなやつだ…」

と思い、画像にして実装する方もいらっしゃることでしょう。
かくいうかわゐも、画像にして実装することが多かったです。

しかし、SVGと組み合わせることで、イイ感じに縁取りできる方法を見つけました。
これで反射的に画像にしなくても、SVGで試してみるという選択肢を増やすことができます。

それでは、いってみよ~。

CSSとSVGを使って縁取り文字を攻略しよう!

早速ですが、実際の実装に似せたコードと、コードの解説を行っていきます。

まずはコードから見てみよう!

今回ご紹介するコードはこちらです。
※ headタグやCSS、Google Fontsの読み込みなどについては割愛しています。

◆ HTML

<h1>I want to collect stag beetles in Borneo.<h1>
<svg aria-hidden="true">
    <filter id="dilate">
        <feMorphology operator="dilate" radius="1" result="DILATE"></feMorphology>
        <feComposite in="DILATE" in2="SourceGraphic" operator="xor"></feComposite>
    </filter>
</svg>

◆ CSS(Scss)

h1 {
    filter: url(#dilate);
    color: #333;
    font-weight: 700;
    font-size: 72px;
    font-family: 'Montserrat', sans-serif;

    & + svg {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
    }
}

どうですかこれ。
かなり綺麗な縁取りができたのではないでしょうか?
SVGを使った方法の中にはジェネレーターを使う方法がありますが、そんなことはしません。
よくある「text-shadow」や「text-stroke」なども使用しません。

コードの解説

簡単にいうと、「.text」にSVGのfilter要素を適応し、feMorphologyフィルターとfeCompositeフィルターで文字の縁取っています。
feMorphologyフィルター、feCompositeフィルターにはそれぞれoperator属性があり、色々と指定ができるのですが…。
詳しいことはこちらの記事をご参照ください。

SVGフィルタで縁取り文字を実装する方法

CSS+SVGを使う実装のメリット

イイ感じに綺麗に実装ができているかと思いますが、メリットを見ていきましょう。

バリアブルフォントに対応

「Montserrat」や「Josefin Sans」など、巷でよく見るフォントをCSSのみで縁取りすると、縁取り方が謎になってしまうことがあります。
SVGを合わせ持つことで、謎の縁取りを解消することができ、見た目が美しくなります。

画像にする必要がない

わざわざテキストをアウトライン化して、SVGにして書き出す…といった手間が省けます。
そして、同じSVGならこっちでええやん…ということに気づけることでしょう。

画像の拡張子によっては、微妙ながらもサーバーに負荷をかけてしまうこともあるので、何でもかんでも画像にしてしまうことは避けたいところ…。
SVGを使った縁取りで、パパっと綺麗に実装してしまいましょう!

この実装のデメリット

SVGを使う縁取り文字にデメリットはあるのかどうかを見ていきましょう。

調整が少し手間

先ほどご紹介したコードをそのまま使用すれば、基本的にイイ感じの実装になります。
が、ここから調整を加えたいときが少し手間かも知れません。

縁取りを太くしたいときは、radiusやoperator属性を編集する必要がありますし、中々思うようにいかないこともでてきます。
なので、縁取りの線が太い場合のデザインは少しややこしく感じるかも知れません。

oparetor属性が少ない

これはfeMorphologyフィルターの話ですが、「dilate」と「erode」の2つしかありません。
「dilate」は「広げる、拡張する」という意味、「erode」は「浸食する」という意味です。
なので、縁取りが太くなるか細くなるかの違いなのですが…。

そこそこ見た目が変わるので、「この間の縁取りが欲しい」という痒い所に手が届きづらいことも少々…。
とはいえ、よくあるテキストの縁取りデザインには効果的ですし、複雑な縁取りであれば画像にするという選択肢もあります。
実際に使っていますが、今のところそこまで不便はしていません。

MacOSによるバグ

使用している文字やフォントスタイルによっては、謎の線が引かれたり若干フォントが切れてしまう可能性があります。
使ってみて、今のところそのようなバグに遭遇したことはありませんが、実機で確認しつつ試してみましょう。

CSSのみで縁取り文字を実装する方法

ここで、CSSを使って文字を縁取りしていく方法と、デメリットをご紹介いたします。

-webkit-text-strokeを使う方法

縁取りしたいテキストなどに、以下のプロパティを指定します。

◆ CSS(Scss)

color: transparent;
-webkit-text-stroke: 2px #000;

テキストの色を透明にし、「-webkit-text-stroke」で縁取りをするという感じです。
Googleの検索や書籍などで、よく見る実装かもしれませんね。
Googleフォントなどのバリアブルフォントを使っていない場合は、この方法が早くて確実です。

しかし、Googleフォントなどのバリアブルフォントを使っている場合は、謎の縁取りが完成してしまいます。

例えばこんな感じに…。

この縁取り…何ぞ?!
ということになり、解消のために検索する方を、かわゐはどれほど見てきたか…。
(どれほども見てません)

写真でもわかる通り、Googleフォントなどのバリアブルフォントを使う場合はあまりオススメできる方法ではありません。
…まぁ、デザインの内容によっては「あえて」謎の縁取りにするのもアリかもしれませんが。

text-shadowを使う方法

-webkit-text-stroke以外にも、text-shadowを使う方法もあります。
実装はこんな感じ。

◆ CSS(Scss)

color: #fff;
text-shadow:
3px 3px 0 #000,
-3px 3px 0 #000,
-3px -3px 0 #000,
3px -3px 0 #000;

テキストの四隅に影をつけて、縁取っているかのように見せました。
この方法も、よく見かける実装ではないでしょうか。
しかし見てください…。Googleフォントを使用したときの様子を…。

うん…悪くはない。悪くはないんだよ。
デザインによってはこういうのもアリですし、これだから表現できるものもあると思っています。

やけど、使いどころがめっちゃ限定される…!
しかもtext-shadowに限っていえば、デフォルトのフォントですらおかしくなることもあります。

ちょっと見えにくいですが、「w」の四隅に少々違和感が…。
他にも、要所要所で跳ねてしまっているところがあります。
text-shadowを使う場合は、かなり限定的になってしまいそうです。

CSSとSVGを使えばどんなフォントの縁取りも楽勝!

今回は、CSSとSVGを使って、縁取りを綺麗に行う方法についてお話ししました。
デザインやコーディングで、GoogleフォントやAdobeフォントなどのバリアブルフォントを使う機会も多いことでしょう。
そんな時に、「画像にせず綺麗にできる方法はないものか…」と考えた方もいるはず。

そうしてたどり着いたのが、SVG+CSSを使った今回の方法でした。
デメリットもある方法にはなりますが、今のところめっちゃ困った…!ということにはなっていません。

実装の際は、注意点などを振り返りながら行うとよいでしょう。
というわけで、最後までご覧いただきありがとうございました!

■ 追記 ■
記事を最後までご覧いただいたあなた限定!
そういえばこれで縁取りのテキスト部分太くできるやんがありました。

縁取りのSVGをしている要素(実例ではh1タグ)に対して、text-stroke(-webkit-text-stroke)を指定することで、
縁取り内のテキストを太くすることができました!

縁取りの縁を太くできる方法があったら、その時にでもシェアします!
それでは!

【参考記事】
SVGフィルタで縁取り文字を実装する方法
SVG、feMorphologyフィルターで要素を太く/細くする。
– SVG: スケーラブルベクターグラフィック | MDN
– SVG: スケーラブルベクターグラフィック | MDN

WEBデザイナー かわゐ
著者.
WEBデザイナー かわゐ
役職.
WEBデザイナー
資格.
ITパスポート, 世界遺産検定3級

フロントエンドエンジニア歴4年目。「人生は経験だ」と思い、前職は宮古島に就職。しかしクワガタムシがいないのと台風の勢力が化け物過ぎたのとで、大阪へ避難。避難前にリースに応募して入社。入社後はWordPressやECサイトの構築を担当。クワガタに命を捧げるクワガタ系エンジニア。