ふくろ文字。

CSSで文字にフチを付けてふくろ文字にする方法みっつ。いにしえの方法と、いまどきの方法と、SVGを使って再現する方法についてのメモです。

いにしえの方法

text-shadowプロパティを使って文字に影を落として、その影で文字を縁取る方法。
text-shadowの値は、,カンマで区切っていくつでも指定できるので、四方八方に影を落とせばフチのように見せることができるってワケです;)
下ソースコードでは、左、下、右、上、左上、右上、左下、右下の順に、薄暗い灰色dimgrayの影を落とします。

.outline-text {
	text-shadow: -1px 0 dimgray, 0 1px dimgray, 1px 0 dimgray, 0 -1px dimgray,
		-1px -1px dimgray, 1px -1px dimgray, -1px 1px dimgray, 1px 1px dimgray;
}

けれどこの縁、フォントサイズが大きくなると、ちょっと頼りなく感じます…:(

text-shadowプロパティを使ったふくろ文字のサンプル

大きな文字は縁取りも太くしたいですよね。縁が太くなるよう、影の距離を、1pxから5pxに増やしてみます。
下ソースコードは、文字から四方八方に5pxずつ離れた位置に影を落とします。

.outline-text {
	text-shadow: -5px 0 dimgray, 0 5px dimgray, 5px 0 dimgray, 0 -5px dimgray,
		-5px -5px dimgray, 5px -5px dimgray, -5px 5px dimgray, 5px 5px dimgray;
}

縁取りというにはあまりにも粗が目立ってしまいますね…、特に明朝体はひどいです…X(

text-shadowプロパティでは縁を太くするのが難しい

いまどきの方法

-webkit-text-strokeプロパティで、文字の輪郭線を表示することができます。値はふたつ、線の太さ線の色を指定します。
下ソースコードでは、0.2文字分の太さ2emの、薄暗い灰色の輪郭線を表示します。
塗り色は、colorプロパティのままでも問題ないのだけれど、ここではtext-strokeに合わせて、-webkit-text-fill-colorプロパティで指定しています。

.outline-text {
	-webkit-text-stroke: .2em dimgray;
	-webkit-text-fill-color: white;
}

ただし、デフォルトでは、文字の塗り色の手前に輪郭線が表示されている状態なので、輪郭線で塗り色が隠れちゃいます…。 輪郭線と塗り色の重なり順は、paint-orderプロパティで変更できます。輪郭線と塗り色の描画順を指定します。
下ソースコードのように指定すると、先に輪郭線を描いたあとで塗り色を描画するようになります。

.outline-text {
	paint-order: stroke fill;
}

Safari/Firefoxでは大丈夫ですが、Chromeではまだ反映されないみたい…:((2024年2月現在)

Chromeのために

もう一つ同じ文字を用意して、フチを付けた文字の上に、フチなしの文字を重ねるということをします。
上に重ねる文字は、data属性(ここではdata-textに書いておいて、contentプロパティを使って、::beforeの擬似要素として表示します。これを絶対配置position: absoluteにすることで、ふたつの文字が同じ位置に重なるって寸法;)

.outline-text::before {
	content: attr(data-text);
	position: absolute;
	-webkit-text-stroke: 0;
}

文章の中で使うとこんな感じになります。
data属性を使って、上に重ねる文字を絶対配置しているので途中改行できないのが玉にきず。なので、短いフレーズに使うのが良いです;)

掩護カバー

SVGのtext要素で文字を表示させれば、SVGの機能が使えます。SVGでは、文字でも図形でも、塗り色はfill、線の色はstroke、線の太さはstroke-widthで適用できるので、ふくろ文字もなんのそのなのです。

<svg viewBox="0 0 82 20"><text x="1" y="16">ふくろ文字</text></svg>

SVGでもデフォルトでは線が塗りの手前に重なってしまいますが、先述のtext-strokeプロパティの時と同様に、paint-orderプロパティで、重ね順を指定できます。SVGならChromeでも大丈夫!:)

.outline-text text {
	fill: white;
	stroke: dimgray;
	stroke-width: 3;
	paint-order: stroke;
}

「ろ」の最初の曲がり角の内側が鋭角すぎて、つのみたいに飛び出しちゃってます…。これは、stroke-miterlimitプロパティで、尖らせる角度の制限を指定することで抑えられます。

.outline-text text {
	stroke-miterlimit: 3;
}

また、stroke-linejoinプロパティで線のかどを丸めれば、柔らかい感じのふくろになります。角丸にしておけば、つのが飛び出ることもなくて安心:)。もちろん明朝体も綺麗です。

.outline-text text {
	stroke-linejoin: round;
}

文章の中で使うとこんな感じになります。
文字数と相談しながらsvg要素のサイズや、text要素の位置をいちいち調整しなきゃならないので、あまり実用的ではないですけれど、表示するサイズがきっちり決まっているタイトルなどでなら使えそう。