✍️

CSSで文字に太いフチをつける方法

2024/07/07に公開1

完成イメージ

CSSで文字にキレイなフチをつける方法について書いていきます。
「CSS 文字 フチ」や「CSS 文字 枠線」などで検索すると以下のような方法でフチをつけるやり方が出てくると思います。

  • -webkit-text-strokeを使う
  • text-shadowを使う

-webkit-text-stroke

-webkit-text-strokeを使ってフチをつけてみます

-webkit-text-stroke: 1px #fff;
1pxであれば特に崩れることなく表示されます

-webkit-text-stroke: 2px #fff;
2px、まだ耐えられますがちょっと怪しいです

-webkit-text-stroke: 6px #fff;
6px、ここまでくると完全に文字が潰れてしまいます

1~2pxの細いフチをつけるならこれでもいいですが太いフチをつけるのは難しそうですね

text-shadow

text-shadow: -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff;

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

-webkit-text-strokeよりかはキレイに見えますがよく見ると頂点の部分がギザギザになっています

また、ぱっと見どこをどうしたらフチがつくのかが分かりにくいです

今回考えたやり方

同じ文字を重ねて、下の文字に-webkit-text-strokeを当ててフチをつける方法を考えました

Example

HTMLは以下のようにします

 <div class="content">
  <h1 class="h1-text">Hello World</h1>
  <p class="p-text">Hello World</p>
</div>
.content {
  position: relative;
}

.h1-text {
  color: blue;
  font-size: 10rem;
  font-weight: bold;
}

.p-text {
  color: red;
  font-size: 10rem;
  font-weight: bold;
} 

まずは同じ文字に同じスタイルを当てて上下に並べます

次に文字を重ねます
下にある文字がフチになるのでマイナスのz-indexで下に来るようにします

.p-text {
  color: red;
  font-size: 10rem;
  font-weight: bold;
  /* ↓追加 */
  position: absolute;
  inset: 0;
  z-index: -1;
}

あとは下になるテキストに-webkit-text-strokeでフチをつけるだけです

.p-text {
  color: red;
  font-size: 10rem;
  font-weight: bold;
  position: absolute;
  inset: 0;
  z-index: -1;
  /* 追加 */
    -webkit-text-stroke: 40px red;
}

下にあるテキストが太くなるだけで上に重なっているテキストには干渉しないので文字が潰れることがありません

上にあるテキストを消すとこのようになっています

最終的なHTML, CSSは以下になります
自由にコピペして使っていただいて大丈夫です!

<div class="content">
  <h1 class="h1-text">Hello World</h1>
  <p class="p-text">Hello World</p>
</div>

.content {
  position: relative;
}

.h1-text {
  color: blue;
  font-size: 10rem;
  font-weight: bold;
}

.p-text {
  color: red;
  font-size: 10rem;
  font-weight: bold;
  position: absolute;
  inset: 0;
  z-index: -1;
  -webkit-text-stroke: 40px red;
}

Discussion

こうこう

細かいところですが、セマンティクスを考慮すると縁取り用のpは疑似要素で代用しても良いかもと思いました。ご参考までに…

疑似要素を利用する例
<div>
	<p class="text">Hello World</p>
	<p class="use-attr" data-text="Konnichiwa">Konnichiwa</p>
</div>
<style>
	.text {
		position: relative;
		color: blue;
		font-size: 10rem;
		font-weight: bold;
	}
	/* 単純にテキストを指定する場合 */
	.text::before {
		content: "Hello World";
		color: red;
		position: absolute;
		inset: 0;
		-webkit-text-stroke: 1rem red;
		z-index: -1;
	}

	.use-attr {
		position: relative;
		color: lime;
		font-size: 10rem;
		font-weight: bold;
	}
	/* data属性の値をテキストに利用する場合 */
	.use-attr::before {
		content: attr(data-text);
		color: red;
		position: absolute;
		inset: 0;
		-webkit-text-stroke: 1rem red;
		z-index: -1;
	}
</style>