レッスンページの表示改善 — テーブルは余白で区切り、コードブロックは折り返してhighlight.jsで着色する
この記事のポイント
- 昨日積み残した自作講座(Claude Codeスキルを教材化したSVG図解編)のレッスンページ検証を再開し、表示の粗を順に潰した
- テーブルは罫線を足すのではなく、余白と薄いグレー背景で領域を区切る方針にした
- コードブロックは素の
<pre>が28箇所。スタイル追加に加えて、横スクロールバーが出ないよう折り返しを指定した - シンタックスハイライトは Nuxt Content の shiki が使えない構成だったので、highlight.js をクライアント側で遅延ロードした
- メインのモデルは Fable 5、実装系タスクは Sonnet 5 のサブエージェントに振る運用方針を決めた
昨日の積み残しから再開
「そういえば昨日の積み残しがあったと思うんですけど」と切り出して、memo の記録を掘り出してもらった。自作講座のレッスンページは実装がほぼ終わっていて、残りは表示検証だけと分かった。
ここでモデルの運用を相談した。メインのセッションは Fable 5 で回すとして、実装は Sonnet 5 のサブエージェントに任せてもいいのではないか。返ってきた整理は「今回の残作業は検証中心なのでメインで進める。今後の実装系タスクは Sonnet 5 委任で問題ない」。この日はその方針で走らせた。
検証はブラウザ確認から。レッスン一覧のカード表示、2カラム(ミラーカラム)表示、ページャー、矢印キーでのセクション遷移と順に見ていった。配布物のDLリンクは zip と個別6件がすべて 200 を返し、未ログイン時のガードも cookie なしの curl で効いていることを確認してもらった。
ひとつ想定外だったのは、検証を始めた矢先にセッションリミットに当たったこと。リセット時刻の表示を眺めていても進まないので、アカウントを切り替えて続きを進めた。
テーブルが文字の壁になっていた
検証中のスクリーンショットを貼って指摘した。テーブルデータのつもりの領域に、折り返しもカラム境界の線もなく、文字がひと続きに貼り付いている。どの値がどのカラムに属するのか、目で追えない。
直し方は自分から指定した。罫線を引いて区切るのではなく、すでに入っているマージンを活かす。ヘッダーは色を変え、各領域に薄いグレーの背景を敷いて、スペースで区切られていることを示す。線を足すと画面の情報量が増えるが、余白と背景色なら要素を増やさずに区切れる。この方針で修正してもらい、HMR越しに反映を確認した。
コードブロックは2段階で直した
1回目 — 素の <pre> が28箇所
コードブロックのCSSを調べてもらったら、スタイルの当たっていない素の <pre> が28箇所見つかった。本文表示の ScrollArticle と Theater モードの TheaterViewer、両方のコンポーネントに pre/code のスタイルを追加させた。この時点で ESLint 指摘ゼロ、既存テスト2,631件PASSまで確認。
2回目 — 横スクロールバーを消す
別のページを見ていたら、コードブロックの下にスクロールバーが顔を出していた。長い行が折り返されずに右へ突き抜けている。「スクロールバーが下に出ないようにうまく改行してほしい」と投げて、折り返しを指定させた。
あわせて「mdx-playground と同じようにハイライトを付けられないか」と聞いた。調べてもらった答えはこうだった。
- eurekapu-nuxt4 にはハイライト系の依存がそもそも入っていなかった
- mdx-playground(apps/web)は Nuxt Content 組み込みの shiki でビルド時にハイライトしている
- eurekapu-nuxt4 は Nuxt Content 不使用でコードを v-html 描画しているため、同じ仕組みは持ち込めない
そこで highlight.js(v11.11.1)をクライアント側で導入することにした。遅延ロード式のハイライトディレクティブを書かせて、TheaterViewer の v-html コンテナ2箇所(Article モードの本文と Theater モードのキャプション)に適用。XML として38トークンが着色されるのをブラウザで確認し、コンソールエラーなし、テストの回帰なしまで見た。
レイアウト混在の疑問 — バグではなく仕様だった
隣り合う2つのセクションでレイアウトが違うことに気づいた。片方は右側に目次が出るパターン、もう片方は max-width でコンテンツ幅を決めるパターン。「これってなんで混在してるんですか?」と聞いて、データ構造とレイアウト分岐を追ってもらった。
答えは、ビューアーがセクション単位で2つの描画モードを切り替えている仕様だった。バグ修正ではなく仕様の理解で終わった一件。原因を確かめる前に「揃えて」と指示していたら、意図した切り替えを壊すところだった。
図スライドの境界 — 枠線案を取り下げて幅760pxに統一
図スライドと本文の境界が曖昧で、急にフォントが変わった感じがして気持ち悪い。最初は「細いグレーの線で囲ってもらえますか」と枠線を頼んだが、見た結果取り下げて、コンテンツ幅を本文と同じ760pxに統一する案だけ適用した。境界を線で主張するより、幅が揃っていれば同じ紙面の続きに見える。
仕上げに、目次あり・なしの両タイプのページでカラム位置を実測させたら8pxのズレが残っていた。オフセットを100pxちょうどに調整して解消。スライドSVGの背景を揃える一括スクリプトも回したが、34枚のうち12枚だけ背景rectの書き方が他と違うか背景そのものがなく、挿入位置を </svg> 直前(描画順で最前面)に変えるスクリプト修正で通した。
締め — 77ファイルをコミット
最後に全体を見て「じゃあこれでいいか。OK」とコミットを頼んだ。講座に関係する変更だけを選別して77ファイル・+6,554行。ミラーカラム用データ9本、ページ10枚、SVG34枚、配布物一式、レイアウト配線まで、2つのコミットに分けて入った。
学び
- 表の区切りは罫線より先に余白と背景色を試す。線は情報を足すが、余白は要素を増やさずに区切れる
- ハイライトは「フレームワークに入っているはず」と思い込まない。shiki は Nuxt Content とセットで、v-html 描画のプロジェクトには highlight.js のクライアント導入が別途要る
- レイアウトの混在を見つけても、直す前に「仕様か、バグか」を確かめる。今回は仕様だった
- 境界の曖昧さは枠線で囲うより、幅を揃える方が効くことがある。一度枠線を試して取り下げたからこそ比較できた
- 検証中心の日はメインモデル一本で足りる。実装をまとめて振る日に Sonnet 5 サブエージェント委任を使う、という切り分けができた