Permalink
Fetching contributors…
Cannot retrieve contributors at this time
198 lines (135 sloc) 13.5 KB
layout page_type page_datetime page_id page_tag page_description page_title
./src/jade/_post.jade
post
2017-01-03T22:05:10
87
CSS
first-letter擬似要素とfont-feature-settingsで行頭の約物半角を対応してみる。
CSSで行頭の約物を半角にする

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

約物を半角にするオプションはCSSのfont-feature-settingsプロパティーに"palt"値を指定すればできる。約物とは文字や数字以外のグリフと考えていい。

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

本文エリア全体に約物半角をかけたい人たちは一定数いるのだろうが、僕はそれはやりすぎだと思う。かと言って和文フォントはベタ組みで読みやすくなっているという話も諸手を挙げて賛成もできない。グリフによってアキはまちまちだし、個性が出にくい約物はやはり半角にしたほうが見栄えがいいなと思う場面もあるからだ。行頭の括弧などは強くそう思う。というわけでこの記事を書いている。

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

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

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

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

::first-letterfont-feature-settings: "palt"を組み合わせれば、行頭の一文字目の約物を半角にできるはずだ。

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

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

あまり使われていないので知らない人も多いかもしれないが、first-letter擬似要素はCSS1から使える古参のセレクタで、CSS2まではコロンは一つだった。CSS Selectors Level 3でダブルコロンになった。IE8ではダブルコロンの擬似要素を解釈できないのでbeforeやafterにおいてもシングルコロンで記述しなければならないという童話がある。

さらに、IE6はfirst-letterとfirst-line擬似要素のコロンはいくつ書いても解釈されるという神話がある。想像してごらん、div::::::first-letterなどというバカげたセレクタを解釈するブラウザを。

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

紫borderのボックスの背景には全角1文字幅の方眼を敷いている。::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でもMax 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もMax 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のどちらに起因している問題なのかよくわからない。そもそものフォントファイルに起因している可能性もゼロではなさそう。主要な欧文フォントに差し替えてテストしたら何も問題ないとかだと悲しい。

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