CSSだけで文字装飾


CSSだけで描画できることが増え、グラフィックソフトを使わなくてもある程度装飾的なことが出来るようになりました。
[前回](https://qiita.com/noqua/items/fd6f5a0d5b7706b6d5e9)はボックス要素で試してみましたが、今回はテキストを装飾してみました。

CSSグラデーションで描く背景を```-webkit-background-clip: text;```でテキストに適用しています。

装飾のためにタグを入れ子にしたり空タグを使うのが好きではないので、基本的に```span```タグ1つを使います。
ただし、```span```の疑似要素```:before```、```:after```は利用しています。

※モダンブラウザのみ検証しています。

<img src="https://qiita-image-store.s3.amazonaws.com/0/62022/d8295f48-cf09-f324-6278-51a6fdb4c22c.png" alt="pure css text decoration samples">


## コード
### HTML

```html
<p><span class="decorated sample-1">LOLLIPOP</span></p>
<p><span class="decorated sample-2">ROCK YOU</span></p>
<p style="background-color: #222;"><span class="decorated sample-3">NEON</span></p>
<p><span class="decorated sample-4">Shadow</span></p>

<script>
// 疑似要素のcontentを親要素（span）と同じ文字列にするスクリプト
// .decorated というclass名の要素を対象に
// data-text属性を追加しspanのテキストと同じ文字列を値に設定
deco = document.querySelectorAll('.decorated');
deco.forEach(function(element) {
	element.setAttribute('data-text', element.textContent);
});
</script>

```

JavaScriptを使いたくなければ

```html
<p><span class="decorated sample-1" data-text="LOLLIPOP">LOLLIPOP</span></p>
```

というように、```data-text```属性に同じテキストを設定すればOK。

### 基本CSS

```css
/* Googleフォント */
@import url('https://fonts.googleapis.com/css?family=Abril+Fatface|Alfa+Slab+One|Audiowide|Bevan|Coiny|Poiret+One|Squada+One');

body {
	font-size: 100px;
}

p {
	margin: 30px 0;
}

/* base */
.decorated {
	display: inline-block;
	position: relative;
	z-index: 1;
	margin: 0;
}

.decorated:before {
	content: attr(data-text);
	position: absolute;
	z-index: 2;
	-webkit-background-clip: text;
	-webkit-text-fill-color: transparent;
}

.decorated:after {
	content: attr(data-text);
	position: absolute;
	z-index: 3;
	-webkit-text-fill-color: transparent;
}
```

### サンプル1

![lollipop.png](https://qiita-image-store.s3.amazonaws.com/0/62022/5ca9402e-d316-a2a4-c5ec-3f4634b7b95f.png "lollipop.png")

```css
/* sample : LOLLIPOP */
.sample-1 {
	color: #FEBA61;
	font-family: 'Coiny', cursive;
}

.sample-1:before {
	top: 0;
	left: 0;
	background:
		radial-gradient(white 25%, transparent 0),
		radial-gradient(circle farthest-side, #FD9BE2, #FEBA61);
	background-size: 20px 20px, 100% auto;
	-webkit-background-clip: text;
}

.sample-1:after {
	top: -6px;
	left: -6px;
	-webkit-text-stroke: 5px #F32B93;
}
```

### サンプル2
![rockyou.png](https://qiita-image-store.s3.amazonaws.com/0/62022/4150cfc0-b89b-ec1c-f1c5-94dd05ba3e95.png "rockyou.png")

```css
/* sample : ROCK YOU */
.sample-2 {
	font-family: 'Squada One';
	font-size: 1.2em;
	letter-spacing: .05em;
	background: linear-gradient(to right, #AA201B 50%, #841A16 0);
	background-size: 6px 100%;
	-webkit-background-clip: text;
	-webkit-text-fill-color: transparent;
	filter:
		drop-shadow(1px 1px 0 #222)
		drop-shadow(1px 1px 0 #222)
		drop-shadow(2px 2px 0 #222)
		drop-shadow(2px 2px 0 #222)
}

.sample-2:before {
	-webkit-text-stroke: 4px #AA201B;
	filter: drop-shadow(1px 1px 0 #222);
}

.sample-2:after {
	display: none;
}
```

### サンプル3
![neon.png](https://qiita-image-store.s3.amazonaws.com/0/62022/cf3263d7-6834-e843-1ae1-5e97e49e3936.png "neon.png")

```css
/* sample : NEON */
.sample-3 {
	font-family: 'Audiowide';
	font-weight: bold;
	filter:
		drop-shadow(10px 10px 5px rgba(255, 255, 255, .1))
		drop-shadow(10px 10px 10px rgba(255, 255, 255, .05));
}

.sample-3:before {
	left: 0;
	top: 0;
	background: linear-gradient(to right, #bfe5ff 0%,#87ffdb 100%);
	-webkit-background-clip: text;
	-webkit-text-fill-color: transparent;
	filter: blur(10px);
	opacity: .6;
}

.sample-3:after {
	left: 0;
	top: 0;
	background: linear-gradient(to right, #bfe5ff 0%,#87ffdb 100%);
	-webkit-background-clip: text;
	-webkit-text-fill-color: transparent;
	-webkit-text-stroke: 2px rgba(255, 255, 255, .2);
}
```

### サンプル4
![shadow.png](https://qiita-image-store.s3.amazonaws.com/0/62022/e5336178-cb43-d3d0-0caf-703ffe0ee8f5.png "shadow.png")

```css
/* sample : Shadow */
.sample-4 {
	left: 8px;
	top: 8px;
	background: linear-gradient(-45deg, #CDC6FF 25%, #fff 25.1%, #fff 50%, #CDC6FF 50.1%, #CDC6FF 75%, #fff 75.1%, #fff 0);
	background-size: 4px 4px;
	-webkit-background-clip: text;
	-webkit-text-fill-color: transparent;
	font-family: 'Abril Fatface';
}

.sample-4:before {
	left: -8px;
	top: -8px;
	-webkit-text-fill-color: #CDC6FF;
	-webkit-text-stroke: 1px #B4AFE2;
}
```

## CodePen

今回のコードは[CodePen](https://codepen.io/noqua/full/VBbBNq)にまとめています。

<p data-height="265" data-theme-id="0" data-slug-hash="VBbBNq" data-default-tab="result" data-user="noqua" data-pen-title="Pure CSS Text Decoration" class="codepen">See the Pen <a href="https://codepen.io/noqua/pen/VBbBNq/">Pure CSS Text Decoration</a> by noqua (<a href="https://codepen.io/noqua">@noqua</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


---

以上です。

```background```と```text-shadow```を併用すると、当たり前ですが```text-shadow```が```background```より上に描画されてしまうので、疑似要素と```z-index``` を使って調整が必要だなと感じました。
画像なしで、しかもタグ1つでこれだけ表現できるのはすごいですね。
```-webkit-background-clip: text;```に非対応のブラウザを考慮する場合は```support```でスタイルを分け、ベタ塗り+シャドウくらいで代替えすれば最低限の対応は出来るのではないでしょうか。

参考になりましたら幸いです。