マイナー番号が上がり、いろいろ変わったが、雰囲気は変わっていない。内部的な話で、少し前にやらかしたことから、画像を含めた静的ファイルもmainブランチに持っておくように戻す。いざとなったら再構築するだけで最新の状態を完全再現できる予定だ。それ以外にウェブサイト設定の持ち方を変えたりしてしまったのでマイナー番号を上げる。

また、ロゴとサイト・メニューで画面を縦いっぱいに使うようにする。今はサイト・メニューを真ん中寄せにしているが、スマートフォンでの操作性を考えると下寄せの方が良いかもしれない。メニューが別ページのウェブサイトがあって、ちょっといいなと思ったので、それに近いものへ移行する途中だ(けれど、断念しそうだ)。下位ページにはホームに戻るハンバーガー・ボタンを置き、あたかもフルスクリーン・メニューっぽく開けるようにしたい。

グリッドを1行目だけに

ところどころで利用しているShowcaseコンポーネントは幅に応じて2~4列の繰り返しグリッドになっている。つまり項目が12の倍数ではない場合は、幅によって不定な数の余りが出るということだ。通常はきっちり並ばなくても良いような使い方をしているが、ホームでは12にすると多すぎる(2列6行はかなり長い)ので4に項目を絞っている関係上、3列になる幅だと1つだけ2行目に送られてしまい、納まりがあまり良くない。:nth-row()セレクターなどがあれば話は速いが、ないものはないのでどうにかする。

.showcase {
  align-items: safe end;
  display: grid;
  grid-template-columns: repeat(...);
}

.showcase.oneline {
  grid-template-rows: 1fr 0 0 0;
  overflow: hidden;
  row-gap: 0;
}

1行目だけ高さを確保し、はみ出したものを隠し、項目間の縦の隙間を0する。1frに続く0の数は最大で何行になるかによって変えるが多めに指定しておくと安全かもしれない。これだけで済みそうだったが、align-itemsプロパティーでstartやそれに相当する値でない場合は、ブラウザーがなんとか表示しようと頑張ってしまうため、隠したつもりの項目が上に重なってしまう。そこで納まらない場合はstartとして配置するよう、明示的にsafeを追加しておく。safeキーワードはうっかり隠れてしまわないようにするものなので、使い方はとしては間違っているような気がしないでもない。

ショッピング・サイトのホームで各カテゴリから商品を少しだけ並べたり、商品ページで関連商品をちょっとだけ並べたり、複数行並べると多すぎそうな場合に使うよう考えた。商品検索結果などで使うグリッドの見た目を流用しつつ、1行だけに絞ることで、統一感と一覧性を確保できると思う。しかし、コードから見るといずれ破綻しそうなことがよく見え、グリッドでやるべきことではないようにも考えられる。

一番下の余白

シンプルなウェブページの場合、コンテンツが画面の下端付近まで続き、フッターが1行か2行あるだけということが多い。画面の下端付近にあるコンテンツは、横長、多分3:2 (Surface Pro)や4:3 (iPad)くらいまでの画面なら視界の範囲内なので、読みづらくなることはない。対して、縦長(2:3や3:4)の画面だと、首を動かすか、タブレット端末なら画面を持ち上げる必要が出てくると思う。Feedlyなどがそうで、Surface Proを縦にして見ているとかなり読みづらいと感じている。

このウェブサイトもそんな感じで読みづらいのではないかと仮説を立てたので、下の余白を大幅に増やしてみている。具体的にはポートレイトなiPadの真ん中に、16:9のやや狭い視界があると仮定し、それより下にコンテンツが来ないよう余白を計算している。

(1 - 3 / 16 * 9 / 4) / 2 * 100vh = 28.906vh

これからフッターの高さを引くと、コンテンツの終わりが視界に納まるようになるかもしれない。だがフッターの高さが不定なので、どうしようかと悩んでいる。とりあえずは1行分の高さを引いて誤魔化している。ただ、フッターを見たいこともあるので、引かなくても良いとも考えられる。加えておおむね画面の中央よりやや上に視界の中心があることも多そうなので、調整をせずともコンテンツの終わりが視界に入りそうな気もする。

配列からランダムに要素を切り出し

配列からランダムに要素を3つ切り出したい時に、シャッフルしてから先頭から3つ取り出していた。もうちょっとテキトウにできそうかなと、Array().fill().map()でやるように変える。パッと見に何をやっているのかわからない。

const pick3Articles = (articles) => Array(3)
  .fill(articles.length)
  .map((max) => articles[Math.floor(Math.random() * max)]);

Array()で作られる疎配列にmap()はうまくいかないので、fill()を噛ませている。スプレッド構文([...Array(3)])でも良いが、使う機会があまりないfill()を使いたくなった。問題は切り出す要素が被ることだが、それほど致命的でもなく確率的にも低いので良しとした。


他だと数千行の空行が出力されてしまうMustacheテンプレートの問題を修正したり、頻繁にValidatorをかけるようにしたりなどだ。購読中のウェブサイトもウェブサイトと著者を併記するように戻す。また、雑多な記録ページで概要を表示するようにした結果、狭い画面だと長い単語のせいでレイアウトが崩れてしまう問題があった。同様の問題は最近の様子ページにもあるが、こちらはCSSのoverflow-wrapプロパティーでanywhereを指定することで誤魔化し、雑記側は単語を修正することで直している。