3^2 / 2^3の答えである1.125を基本の比にし、様々な大きさをすべて計算しなおす。「黄金比なんて誰も設計に使っていない」というような本を読み、黄金比を使っているのがちょっと恥ずかしくなったからだ。4乗していくとなんとなく大きくなっていくようで、キリの良い数字が増え、自己満足度が上がる。結局は黄金比に近い(1.125^4 = 1.602)ので、最終的な結果は変わらない。
巨大なハイパーリンク
まず、かつてTwitterとして知られていたプラットフォームへ投稿する時に使う、短めの概要を別に作るようにする。それに使うだけではもったいないので、ホームの投稿一覧をリストからセクションに変えて、そこでも使うようにする。その流れでsection
要素全体をハイパーリンクにするようにし、その結果CSSが複雑になる。ここで言う「複雑」とは、やりたいことと実装に大きな乖離があり、レンダリング結果とコードのどちらからも互いに見通しが悪いというような意味だ。
親のa
要素が持つtext-decoration
プロパティーを、子孫要素で上書き(に近いことが)できるのに削除できないことによる。この場合だと日付や短い概要の下線を消したいだけなのに、一旦すべて消してから見出しでのみ改めて引くという大回りな実装になってしまう。何を言っているのかわからないかもしれないし、なぜそうなのかもわからないかもしれないし、正直なぜそういう仕様になっているのかは僕も知らない。まだまだ世のウェブサイトで「続きを読む」やら「Read more」やらが多い理由は、最終的にこの辺に求められるのではないかと思っている。
HTML側でsection
要素の各子孫要素へa
要素をばらまくと、それぞれにtabindex
属性が必要になるし、各子孫要素の外側の余白がハイパーリンクではなくなるし、CSSは複雑なままだし、良いことが無い。消したい要素のみdisplay: inline-block
にする(仕様的に言うならatomic inlineにする)という手段もあるが、目に見えない何かが壊れそうな気がする。
また、この過程でCSSを簡単にするため:has()
を解禁したが、再封印する。Firefox ESRを使っているわけではないが、これを安全ラインとしたい気持ちになっている。年1回くらいは更新されるようなので、そうそう時代遅れとはならないし、良い落としどころであり、かつ忘れがちなFirefoxのことを思い出す役にも立つ。たまにFirefoxだけで実装されているものをうっかり使ってしまい失敗することもある(overflow-inline
プロパティーでやらかした)。
fs.glob()
内部的にはfs.glob()
への書き換えがある。isaacs/node-globパッケージでは配列でPromiseが履行されるが、fs.glob()
ではAsyncIteratorで返ってくるので、そのまま置き換えることはできない。AsyncIteratorをきちんと扱うように書き直すか、Array.fromAsync()
で配列に直す。配列をPromise.all()
とArray.map()
で並行処理をするように書いていた場合は、Array.fromAsync()
の第二引数にArray.map()
に渡していた関数を指定するだけで良い。
import fs from "node:fs/promises"
import { glob } from "glob"
const toLowerCase = (str) => str.toLowerCase();
const isaacsGlob = async () => {
const files = await glob("**/*");
return Promise.all(files.map(toLowerCase));
};
const fsGlob = async () => {
const files = await fs.glob("**/*");
return Array.fromAsync(files, toLowerCase);
};
Fluid Typographyの見送り
いわゆるFluid Typographyなどと呼ばれている描画領域に応じて文字サイズが変わる機能も復活させていたが、結局はまた見送る。利用者の文字サイズ設定には追随するものの、その動機とはうまく噛み合っていないと感じるからだ。利用者が文字サイズを変えているのなら、Fluid Typographyが行う読みやすさの提供は利用者が既に行っていると見做せると思う。
また、rem
単位での実装とすると、大きくしているとそれに応じて文字サイズが二重に大きくなってしまうし、小さくしているなら忌避したはずの標準の大きさをいとも簡単に超えてしまう。もちろんpx
単位で実装した場合はそういう問題は起きないが、文字サイズの設定を完全に無視する。どちらの場合でもウェブサイトのさじ加減として許せる範囲を超えていると利用者が感じてしまうかもしれない。
このウェブサイトが112.5%
くらいに抑えている理由もこの辺りにある。これなら利用者が12px
くらいにしていても13.5px
、32px
にしていても36px
に抑えられる。小さくしている場合に既定の16px
を超えることはまずないし、大きくしている場合でも6px
以上巨大化することはまずない。おおむね「さじ加減」として許容されるのではないかと思う。
clamp()
などでinitial
キーワードを利用できれば、Fluidしつつユーザー設定とも比較できるので、うまく馴染ませられそうだが、できないものはできない。メディア・クエリーで利用者の文字サイズ設定が引ければ良いのかもしれない。アクセシビリティーという観点からの実装になりそうなので、例えばprefers-text-size
メディア特性などがあり、prefers-contrast
メディア特性のようにno-preference
という値を取れれば、その中でのみFluid Typographyを実装できるだろう。現状では、JavaScriptを使って既定の16px
ではなさそうな場合はFluidしない、というあたりが現実的な落としどころだろうか。
:root {
--ratio-1: calc((3 * 3) / (2 * 2 * 2));
--ratio-2: calc(var(--ratio-1) * var(--ratio-1));
--ratio-4: calc(var(--ratio-2) * var(--ratio-2));
font-size: clamp(
var(--ratio-1) * 1rem,
1rem / var(--ratio-1) + 1vi / var(--ratio-4) / var(--ratio-2),
var(--ratio-4) * var(--ratio-2) * 1rem
);
}
実装は上記のようなコードになっていた。すべて計算されていて楽しい、というくらいしかない。文字サイズの拡大は750px
くらいから始まり、3700px
くらいで最大値に到達する。ブラウザーの文字サイズ設定が既定の16px
の場合、横長で幅1280px
の画面だと20px
くらい、幅1920px
の画面だと24px
くらいになり、3700px
くらいで最大値の32px
くらいになる。Firefox ESRが更新されて、CSSの計算でpow()
が気軽に使えるようになると読みやすくなりそうだ。
まとめると以下のようなボヤキのようだ。
- Decoration Boxという概念は一体何なのか、そしてどこから生まれたのか
fs.glob()
にreturnArray
オプションが欲しい- 最大多数の最大幸福(Fluid Typography)と多様性の尊重(ユーザー設定の尊重)が競合していそう
他、色が多少変わっている。特に暗色の方で大きく変わり、青っぽい背景から褐色っぽい背景になる。文字色も褐色になり、全体的に黄ばんだと言える。ファビコンも四角い背景をやめて、アウトラインを描いておくように戻す。両端揃えや三点リーダーによる省略を導入しつつ、すぐにやめたりもする。日本語・横書き・両端揃えは、1カラムの中央揃えや段組みでこそ威力を発揮する思いを強くした。三点リーダーに限らず、省略されたものに対する扱いがSafariでは独特なので、できうる限り避けるようにしたい。