こなさんみんばんわ。
どうやら世間ではゴールデンウィークに突入したようですが、僕はそろそろ一年半近く続こうかという超長い休暇を今も絶賛満喫中、しかもまだまだ続きそうです。ドヤァ…😭
そんな話はさておき、このサイトの Explore JF.org ってページには年月別アーカイブのリストが置いてあるんですが、年ごとに横 1 列固定のままでは当然スマホなどでは入りきらないので、そういった狭い画面では月のリストが 2 列や 3 列になるように、@media
で切り分けて調整しています。
ですが、この月リストの数字部分は liquid タグによる単純な 1 から 12 までの for
ループで出力してるだけで、「1〜9 月の場合にはゼロ埋めして常に二桁の値にする」というような処理を入れてないんですね。なので、複数列になると一桁の月と二桁の月(10〜12 月)の縦列が漢字の「月」の位置で揃わないという問題がありました。
もちろんこれは text-align: right
で右寄せにすれば上の画像のように揃いますが、そうすると今度は左側に広めのすき間ができてしまいます。特に iPhone の Pro Max のような大きな画面だとけっこうな空白になるので、ちょっとバランス的によろしくない(個人の感想です)。かといってゼロ埋めするのもちょっと嫌(これも個人の感想ですが「04 月」とかテキストとして不自然じゃないですか)なのでやりたくないし…
ということで、とりあえず桁揃えはあきらめて、そこそこバランスが良さそうに見えた text-align: center
にして長いことごまかしてたんですが😅 先日ふと「::before
擬似要素で 1ch
幅の空白を挿入する」というのを思いつきました。ch
というのはその要素に指定されたフォントのグリフ “0” の送り幅を 1 とする CSS の単位なので、テキスト自体には変化を与えることなく実質的にゼロ埋めをするのと同じ効果を得られるんじゃない? という訳です。
See the Pen Alignment using 1ch wide ::before pseudo element by Jeffrey Francesco (@jforg) on CodePen.
☝️ のデモはこのサイトのコードそのままではなくてちょっと簡略化してあるのと、揃えを変えても機能することを示すためにあえて text-align: center
を掛けてあったりしますが、キモの部分はまったく同じで次のコードです。
li:nth-last-child(n + 4)::before {
content: '';
display: inline-block;
height: 1em;
width: 1ch;
}
いちおう解説しておくと li:nth-last-child(n + 4)
で最後から 4 番目以前の li
要素を選択して、その ::before
擬似要素を display: inline-block
で生成して幅を 1ch
に設定。これが li
要素内のテキストの前に挿入されることで「1 月」から「9 月」までのテキストがグリフ “0” の幅分後ろに押し出されるため、「10 月」から「12 月」と縦の位置がざっくり揃う、というロジックです。
注意点があるとすれば、たまに数字部分がデフォルトでプロポーショナルになってるフォントがあるので(このサイトで使ってる Inter がまさにそうですが)もしそのフォントが固定幅数字のグリフを持っているのであれば CSS で font-variant-numeric: tabular-nums
と指定しておく必要があります。ない場合は…あきらめて他のフォントに変えるしかないですかね😭
という訳で、実際に CSS にコードを加えて確認してみたところ、左右の空間のバランスも含めてけっこううまくいってるように感じましたので、先日よりサイトの方に反映しております。
まぁ :nth-last-child
で要素選択している関係上、こういった月のリストのような決まった数字しか並ばないと分かってる場面でないと使えないので汎用性には乏しいですが、とりあえず長年の課題が解決したので個人的には由としておきます。
…全部書き終わってから思いついたけど、li:not(:nth-child(n + 10))
の方がまだ少し汎用的かもしれない。涙