モードの変更

CSSで行頭の約物を半角にする

CSS

2023 年 1 月 3 日追記。
具体的にどのバージョンからかはわからないのだけど、現在は主要ブラウザなら行頭の約物を半角にすることが可能になったもようだ。

画面キャプチャは割愛するが、記事中にある下記の CSS で表現可能になっていることを確認した。

.article-body p::first-letter {
  font-feature-settings: "palt";
}

@font-face を使った手法だと上記ブラウザでも対応が完全ではないものの、この手法はもともと上記 CSS で対応できなかった場合の対策として考えた手法で、しかも対応できなかったものなので、もう気にしなくて良いだろう。一応現時点の状況をまとめておく。

ブラウザ ::first-letterfont-feature-settings: "palt"
使った行頭約物半角
@font-face を使った行頭約物半角
Google Chrome 108 効く 効かない
Firefox 108 効く 効く
Safari 16.1 効く ヒラギノ角ゴ ProN だけ効く
Microsoft Edge 108 効く 効かない

IE11 が役目を終えた今、CSS で行頭の約物を半角にすることは「できる」と言っていい。

ということで、下記本文は 2017 年までの記録として読んでいただければ幸いだ。追記ここまで。


あけましておめでとうございます。

約物を半角にするオプションは CSS の font-feature-settings プロパティーに "palt" 値を指定すればできる。約物とは大まかに、漢字・仮名・アルファベット・数字以外のグリフと考えていい。

約物の一部は全角幅の場合にアキが生じてテキスト全体が間伸びしたように感じることがある。そこで約物半角というオプションを適用すると括弧や句読点のアキが詰まるので、テキストが締まった印象になる。

ウェブタイポグラフィでは和文フォントはベタ組みで読みやすくなっていると言われているけど、個性の出にくい約物なら詰めたほうが見栄えすることもある。行頭の括弧などは強くそう思う。というわけでこの記事を書いている。

行頭にマッチするセレクタ

CSS には ::first-letter 擬似要素というものがある。要素の最初の文字にマッチするセレクタで、英語圏などで一文字目を大きく装飾する「ドロップキャプス」という表現に使われることを想定して考えられたセレクタだ。

.lede::first-letter {
  float: left;
  color: tomato;
  font-size: 3em;
}

このように記述することで .lede 要素の一文字目だけを装飾できる。この ::first-letter を本文エリア内の p 要素につければ、段落ごとの一文字目に約物半角のオプションを当てられるようになる。

これを利用して下記のような CSS を考えてみた。

.article-body p::first-letter {
  font-feature-settings: "palt";
}

::first-letterfont-feature-settings: "palt" を組み合わせれば、行頭の一文字目の約物だけを半角にできるはずだ。一文字目が約物でなければ見た目に変化は起こらない。

論理的にはこれでいいはずだが、結論から言うとリアルワールドはそう甘くなかった。

次のデモをいろんなブラウザで見てほしい。

紫 border のボックスの背景には全角一文字幅の方眼を敷いている。::first-letter を赤色にしつつ約物半角オプションを指定した。ボックスのフォントファミリーは左から游ゴシック、游明朝、ヒラギノ角ゴシック ProN を指定した。

ブラウザ検証

確認した主要ブラウザのキャプチャを羅列した。画像はリンクになっているので個別に拡大表示されたい。

Google Chrome 55
/ Mac OS X 10.11(El Capitan)
Google Chrome 55はfirst-letterへのfont-feature-settingsが効いていない。
Google Chrome 55
/ Windows 10
Google Chrome 55はWindows 10でもMac OS X 10.11(El Capitan)でも効かないようだ。
Firefox 50
/ Mac OS X 10.11(El Capitan)
Firefox 50は期待通り効いているように見えるが$記号があるとfirst-letter自体が無効になってしまう。
Firefox 50
/ Windows 10
Firefox 50で$があるときにfirst-letterが無効になってしまうのはMacでもWindowsでも同じなようだ。
Safari 10
/ Mac OS X 10.11(El Capitan)
Safari 10では約物半角は効いているがその直後との文字間が詰まりすぎて読めない。
IE11
/ Windows 10
IE11では約物半角が効いているが、游明朝だとなぜか効かない。
Edge 14
/ Windows 10
Edge 14では約物半角が効いているが、游フォントとヒラギノで半角になる約物が異なる。

まず気づくのは、::first-letter で行頭の一文字目だけにスタイルを当てているつもりが、後に続く文字にも適用されていることだろう。

約物が一文字目のときはその次の文字も、約物以外が一文字目で約物が二文字目のときはその約物も、約物が一文字目から連続しているときはその全てが ::first-letter の対象になっている。

つまりグリフによっては ::first-letter の対象が二文字やそれ以上の文字数になるということ。これは直感に反しているが、仕様通りなのでそういうものだと思うしかない。

それぞれ見ていくと現状ではまともに使うことができなさそうというのがわかる。

Chrome 55 では ::first-letter への font-feature-settings: "palt" が効かない。Windows 10 の一番右のボックスでは効いているように見えるがこれは僕の環境でヒラギノがないので MS P ゴシックが当てられているだけだ。MS P ゴシックはそもそも約物が字詰めされているグリフを持っている。

Firefox 50 では奇妙なことに、 記号が入ると ::first-letter 自体が効かなくなる。 がなければ期待通り動いているだけに惜しい。もしかしたら他の約物でも起こるかもしれない。

Safari 10 では ::first-letter の一文字目の約物は半角にならないが、::first-letter に含まれる二文字目以降の約物には半角が効いている。そして ::first-letter 直後が詰まりすぎている。font-family の宣言をコメントアウトすると詰まりすぎがなくなる。フォントに依るのかもしれない。詰まっていないときのフォントは何が適応されているのかよくわからない。計算値では -webkit-standard というファミリーだった。現象が謎すぎて Firefox を超えている。段落の一文字目の約物半角が効かないのは ::first-letter が対象でなくても同じだった。

IE11 ではどういうわけか分からないが游明朝で ::first-letter への font-feature-settings: "palt" が効いていない。

Edge では期待通りに全てできているように見えるが、游フォントとヒラギノで半角になる約物が異なる。

ブラウザ ::first-letterfont-feature-settings: "palt" の対応状況
Google Chrome 55 first-letter に約物半角が効かない
Firefox 50 約物半角は効くが、$が入るとおかしい
Safari 10 (El Capitan) 一文字目の約物が半角にならない。游ゴ、游明、ヒラギノで first-letter 直後が詰まりすぎる
IE11 游明の first-letter に約物半角が効かない
Edge 游フォントとヒラギノで半角になる約物が異なる

対応状況としてはカオスだ。 記号に気をつければ Firefox では問題なさそう。Edge も行頭約物半角をかけたい要素はフォントファミリーが統一されているだろうからそこまで問題ではないだろう。Chrome と IE11 は約物半角が first-letter で効かないだけなのでまだいい。しかし Safari では読めなくなってしまうのできつい。

あっさり出来ると思ったけど、すくなくとも Safari で詰まりすぎるのが修正されなければ普通には使えない。

約物半角されたフォントを@font-face で作る

なんとかして対応したいと思って次に試したのが、@font-face ルールを使って約物半角したフォントファミリーを作る方法だ。

@font-face {
  font-family: "YuGothicYH";
  font-feature-settings: "palt";
  src: local("游ゴシック"),
    local("YuGothic-Medium"),
    local("Yu Gothic Medium"),
    local("YuGothic-Regular"),
    local("YuGothic"),
    local(YuGothic);
}

@font-face {
  font-family: "YuMinchoYH";
  font-feature-settings: "palt";
  src: local("游明朝"),
    local("YuMincho-Medium"),
    local("Yu Mincho Medium"),
    local("YuMincho-Regular"),
    local("YuMincho"),
    local(YuMincho);
}

@font-face {
  font-family: "HiraginoYH";
  font-feature-settings: "palt";
  src: local("ヒラギノ角ゴシック ProN"),
    local("Hiragino Kaku Gothic ProN");
}
.test1 p::first-letter { font-family: "YuGothicYH" }
.test2 p::first-letter { font-family: "YuMinchoYH" }
.test3 p::first-letter { font-family: "HiraginoYH" }

このように @font-facefont-feature-settings: "palt" を指定したフォントファミリーを設定し、それを対象の段落の ::first-letter に指定する。

しかしというかやはりというか、リアルワールドは甘くなかった。

主要ブラウザのキャプチャは次の通り。

Google Chrome 55
/ Mac OS X 10.11(El Capitan)
Google Chrome 55は@font-faceを使ってもfirst-letterへのfont-feature-settingsが効いていない。
Google Chrome 55
/ Windows 10
Google Chrome 55は@font-faceを使っても、Windows 10とMac OS X 10.11(El Capitan)には効かない。
Firefox 50
/ Mac OS X 10.11(El Capitan)
Firefox 50は期待通り効いているように見える。しかし@font-faceを使っても$記号があるとfirst-letter自体が無効になってしまうのは変わらなかった。
Firefox 50
/ Windows 10
Firefox 50で$があるときにfirst-letterが無効になってしまうのはMacとWindowsで同じ。
Safari 10
/ Mac OS X 10.11(El Capitan)
Safari 10では@font-faceを使うと約物半角が効かなくなってしまった。
IE11
/ Windows 10
IE11も@font-faceの約物半角が効かなくなった。
Edge 14
/ Windows 10
Edge 14も@font-faceの約物半角が効かなくなった。

Chrome 55 で ::first-letterfont-feature-settings: "palt" が効かないのは @font-face を使っても変わらない。

Firefox 50 では @font-face を使っても 記号でおかしくなるのは変わらない。

Safari 10 は @font-face を使うと ::first-letterfont-feature-settings: "palt" が効かなくなってしまった。

IE11 も効かなくなった。

Edge 14 も効かなくなった。

ブラウザ @font-face を使った行頭約物半角の対応状況
Google Chrome 55 効かない
Firefox 50 約物半角は効くが、$が入るとおかしい
Safari 10 (El Capitan) 効かない
IE11 効かない
Edge 効かない

@font-face を使うと使わないときより状況が悪化してしまった。つらい結果としか言いようがない。

いろいろ確かめるのに疲れてこれ以上の検証はしていないが、約物のグリフが半角な専用フォントを作ってウェブフォントで読み込み、::first-letter に指定する方法がまだ残っている。

壁写真活動家の誰かがそんなフォントを 2 年くらい前から作っている気がする。そろそろリリースされて欲しい。


落ち着いたらバグ報告しようと思うが、これが ::first-letterfont-feature-settings のどちらに起因している問題なのかよくわからない。そもそものフォントファイルに起因している可能性もゼロではなさそう。主要な欧文フォントに差し替えてテストしたら何も問題ないとかだと悲しい。

今年もよろしくお願いいたします。