Back

VNovelテーマでKaTeX数式の括弧が崩れる問題を直してもらった話

※この記事はClaudeによって作成されました。

※この記事はClaudeによって作成されました。

何が起きたか

23話の養成学校のシーンで使われている軌道要素の数式をKaTeXで表示しようとしたところ、行列の大きな括弧が縦方向にバラバラに分裂してしまった。

括弧の上端・中間・下端が離れ離れになって、数式として読めない状態。パラメータ行(t = ... とか a = ...)は問題なく表示されるのに、\begin{pmatrix} を使った行列だけがおかしくなる。

原因:CSSクラス名 .mopen の衝突

結論から言うと、VNovelテーマのハンバーガーメニュー(モバイル用)のCSSクラス名が、KaTeXの内部クラス名と被っていたのが原因だった。

VNovelテーマの style.css には、ハンバーガーメニューのアニメーション用に .mopen というクラスが定義されていた。

1
2
3
/* テーマ側(旧バージョン) */
.mopen { position: relative; display: block; ... }
.mopen span { position: absolute; width: 40px; height: 2px; ... }

一方、KaTeXは数式の開き括弧を表すHTML要素に、内部クラスとして同じ .mopen を使っている。

1
2
<!-- KaTeXが生成するHTML -->
<span class="mopen delimsizing size4">(</span>

Tailwind CSSのビルドプロセスがテーマの .mopen スタイルをCSSバンドルに含めるので、KaTeXが生成した .mopen 要素にもハンバーガーメニュー用のスタイル(position: relative, display: block 等)が適用されてしまう。これで括弧のパーツ配置が崩壊していた。

要するに、メニューボタンのCSSが数式の括弧を壊していたという、なかなか気づきにくいバグだった。

workaroundの罠

最初、原因がわからなかったので math.html に以下のようなCSSを書いて力技で直そうとしていた。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
/* やってはいけない例 */
.katex, .katex * {
    line-height: 1.0 !important;
}
.katex .vlist-t, .katex .vlist-r, .katex .vlist, .katex .vlist-s {
    display: inline-table !important;
}
.katex .vlist-s {
    display: none !important;
}

これは症状を別の症状で相殺しているだけで、むしろ他の数式を壊すリスクがあった。

  • line-height: 1.0 の強制 → KaTeX自身が分数や添字の位置を line-height で精密計算しているので、全部上書きするとズレる
  • vlistdisplay 変更 → KaTeXの垂直リストは inline-block で精密配置されている。inline-table にするとブラウザのボックスモデルが変わって行列がおかしくなる
  • vlist-sdisplay: none → 高さ計算用のスペーサー要素なので、消すと括弧のサイズ調整が壊れる

教訓:外部ライブラリの内部CSSに !important で上書きをかけるのは最終手段。まず「なぜ崩れているか」の原因を調べるべき。

対処法

1. テーマを更新する

VNovelテーマの作者さんがIssue報告に対して .mopen.spmenu へのリネームで対応してくれていた(コミット 80d5d22)。迅速な対応に感謝。

1
2
3
cd themes/vnovel
git fetch origin
git checkout origin/main

これでKaTeXとのクラス名衝突が解消される。

2. math.html のCSS整理

根本原因が解消されたので、workaroundのCSSは全部消して、テーマ固有で本当に必要な最小限だけ残した。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
/* 小説テーマの字下げ・字間が数式内に波及するのを防ぐ */
.katex {
    text-indent: 0 !important;
    letter-spacing: normal !important;
}

/* 数式ページは本文コンテナを少し広げる */
#content-bg > .mx-auto.max-w-2xl {
    max-width: 56rem;
}

/* ディスプレイ数式のレイアウト */
.katex-display {
    margin: 2em 0 !important;
    text-align: center !important;
    text-indent: 0 !important;
    overflow-x: auto;
    overflow-y: hidden;
}

text-indent: 0letter-spacing: normal はVNovelが小説テーマなので、段落の字下げや字間が数式に波及するのを防ぐために必要。これはテーマ固有の事情であってKaTeX側の問題ではない。

3. 数式のレイアウト調整

パラメータ行は aligned 環境で = 揃え、行列行は別の $$ ブロックにして、それぞれが自然な幅で中央配置されるようにした。

まとめ

項目内容
症状\begin{pmatrix} の括弧が縦に分裂する
原因テーマのCSS .mopen とKaTeXの内部クラス .mopen が衝突
対処テーマ更新(.mopen.spmenu)+ workaround CSS削除
教訓外部ライブラリの内部CSSを !important で壊す前に原因を調べる

ブラウザのDevToolsで該当要素に「どのCSSルールが適用されているか」を見るのが、この手の問題を特定する最速の方法だと思う。

Built with Hugo
Theme Stack designed by Jimmy