2021/03/18

「横線+カギ型」の矢印を:before要素ひとつで描画する

予見してはいたけど、在宅勤務終了とともにもとの静かなブログに戻ってしまいました。大学生時代の多感さは有り余る時間の大半をCD買って聴いて過ごしたことと大いに関係があったのだな。そしてたった今直近の一番がんばった投稿の中の、正しい字を知っているはずのところで盛大な誤字を発見したので、この半月ちょっとを本当に返してほしい。

などとこのような過疎ブログで無意味に失態を詫びたところで、おおかたの人に無縁な内容を書く。

:before/:after疑似要素好きですか?空要素をできるだけ減らしたい旧型人間としては大いに濫用したい:before/:after疑似要素。
この手の矢印 をCSSのみで作るとき、今まではこのように

.arw1:before {
 content:"";
 display:block; width:10px; height:2px;
 position:absolute; top:calc(50% - 1px); left:0;
 background:#000;
}
.arw1:after {
 content:"";
 display:block; width:8px; height:8px;
 position:absolute; top:calc(50% - 5px); left:1px;
 border:#000 solid; border-width:2px 2px 0 0;
 transform:rotate(45deg);
}

横線とカギ型を別々に作ってくっつけていたのだけど、ブラウザやOSの設定でフォントサイズないし全体の拡大率が変えられているような環境では、微妙に1pxズレたりしてるのではないか?と不安なやり方ではあった。
最近、横線をlinear-gradientにすることで:beforeに一本化でき、形も確実に安定する方法を思いついて上手くいったので、以下メモ。

.arw2:before {
 content:"";
 display:inline-block; width:8px; height:8px;
 border:#000 solid; border-width:2px 2px 0 0;
 background:linear-gradient(to bottom right, transparent, transparent 40%, #000 40%, #000 60%, transparent 60%, transparent 100%);
 transform:rotate(45deg);
}

表示結果 はだいたい同じ。
線を太めに作ると、横線の左端が垂直に切り立ってないのがバレるかもしれないけど、線幅2pxならまったく表現されない。(と思ったけどRetinaディスプレイではばっちりバレた!左に1pxはみ出させてoverflow:hiddenで切れば対処できる)
position:absoluteでガチガチに配置せずinline-blockとして転がしておけるので、要素の縦中央ではなく1行目のベースラインに来てほしいときには重宝する。
親要素左端にパディング、この矢印を左側にネガティブマージンで引っ張っておけば(text-indentでも可)、リスト要素のマーカー的なポジショニングも簡単にできる。
このlinear-gradientを暗記で打ちするのは文字量的にも若干手間だから、どこかにコピペ用テンプレートを作っておくのがよい。

応用編で、矢印にマルを組み合わせたいとき、これ  ならマルが:before、カギ型が:afterで足りるけど、横棒付きの矢印にしようとすると空要素を作って丸背景(空要素)+横線(:before)+カギ型(:after)とするしかないかーと、これまではspan.arrowみたいなのを渋々挿入していた。

linear-gradientでいくやり方だと、マル背景と矢印に:beforeと:afterを割り当てて   このとおり、余計な空要素を追加しなくてもよい。位置合わせのため絶対配置にはなるけれど。

3px以上(とスマホ等の高解像度ディスプレイ)で横線の左端が尖ってしまう問題のほか、「カギ型を小さめ・横線長め」みたいな柔軟な調整ができず、常に正方形の2辺挟角からの対角線という長さ関係にしかできないのはマイナス点。だが1文字サイズの小さな矢印ならあまり問題にならないとは思う。
以上お試しあれ。