ブログの overflow 時のスタイル設定を見直す

Posted on 月 15 4月 2019 in 運用

ブログの CSS で,幅がはみ出るような要素のスタイルを幾つか修正したので,その対応記録.

経緯

うちのブログではタイプライタ体や数式をよく使う.これは僕がプログラミングと数学寄りの記事を良く書くからだけど,ちょっと問題も起きていた.パソコンでの閲覧時はそれほど大きな問題にはならないんだが,スマフォなどの画面幅が短いモバイル端末ではタイプライタ体の文字が画面幅からはみ出て表示されて,閲覧の快適さがあまりなかった (誰から言われたとかではなく,単に僕が見る時不便だと感じていた).

問題となっていた要素は,以下のもの:

インラインリテラル
``inline literal`` で書けるやつ.プログラム片とかを書くのに使っていて, tt タグを使って変換される.
数式

以下の記法で書けるやつ:

.. math::

  \forall x.\, x = x

これは,うちのブログだと MathML に変換して, MathJax でもフォールバック描画している.

ハイライト付きコードブロック

以下の記法で書けるやつ:

.. code-block::

  some code

うちのブログだと,デフォルトで行番号を付けている.行番号は, table タグで付けるのとインラインに付加するのの 2 通りが選べ,このブログでは table タグを使っている.

これらは,表示範囲内に収まらない場合でも関係なく,表示枠を超えて表示される.特に,ハイライト付きコードブロックと数式は,テーマで対応されていないため問題が起きている.

CSS で表示範囲を超える場合のスタイルを指定する

CSS には内容が表示範囲を超える場合の挙動を設定するプロパティがある.

まず表示範囲を超える場合の改行制御を指定する, overflow-wrap プロパティがある. overflow-wrap では,

normal
空白などの通常の単語分割位置で分割する.
anywhere
任意の場所で分割を行うが,一応最小固有寸法を計算する時折り返し可能位置というものが考慮されるらしい.ブラウザの対応状況がよろしくないので,ないものと思って良さそう.
break-word
anywhere と同じだが,最小固有寸法を計算する時に折り返し可能位置を考慮しない.

正直固有寸法とか良く分からんがとりあえず, break-word を指定しておけば良さそう.デフォルトでは normal になる.インラインリテラルの方はこのプロパティを使った:

article.single tt {
  overflow-wrap: break-word;
}

これで,折り返しを強制的にできる.

もう1つ,ブロック単位で使えるのが, overflow プロパティだ.特に今回は,左右の境界に関する条件で,これは overflow-x で指定できる. overflow-x では,

visible
表示範囲を超える場合でも,そのまま表示する.
hidden
表示範囲を超える部分は,切り取って表示しない.
scroll
hidden と同じく内容を切り取るが,スクロールバーで内容をスクロールできるようにする.
auto
ブラウザごとの仕様に任せる.大抵は scroll と同じになる.

を指定できるらしい.デフォルトは, visible になっている.今回は, overflow-x: auto を使うことにした.数式の方はこのプロパティが特に指定されていなかったので,指定するようにした.また,ハイライト付きコードブロックには既にこのプロパティは指定されていて,とある事情でこのプロパティが機能していなかった.なのでその事情をなんとかした.

数式の方は以下のスタイルを追加した:

article.single mjx-container,
article.single math {
  overflow-x: auto;
}

math タグは MathML のブロック, mjx-container は MathJax が MathML を解釈後に挿入するブロックだ.これで,スクロールされるようになる.

さて,問題のハイライト付きコードブロックだが, table タグは表示幅がデフォルトで固定じゃないため,いい感じに表示幅が広がってしまうらしい.そのため,テーブルの中のコードブロックでは overflow-x プロパティが指定されているんだが,そのコードブロックの表示幅に合わせてテーブルが広がってしまうため,結果表示幅を超えてしまうっぽい.で,テーブルの表示幅を固定したい場合, table-layout: fixed; width: 100%; を使うといいらしい.このプロパティ自体は,表の列幅をいい感じに調整しないで固定幅にするプロパティらしいのだが,結果的にテーブルの幅も固定されるらしい.このままだと,行番号はいい感じに表示してくれないので,最終的に次のスタイルを指定した:

article.single table.highlighttable {
  width: 100%;
  table-layout: fixed;
}

article.single table.highlighttable td {
  border-style: none;
  padding: 0px;
}

article.single table.highlighttable td.linenos {
  width: 2.5em;
}

article.single table.highlighttable td.linenos pre {
  border-left: 0px;
  padding-right: 0.8em;
  background-color: inherit;
  text-align: right;
}

まあテーマの元々のテーブル設定を無効にするため色々やった.この対応は,本家に PR も投げておいた.マージされれば修正されるだろう.

まとめ

画面幅が短い時にもいい感じになるよう, Flex テーマの CSS に修正を加えた.これで,スマフォの閲覧体験は改善されるはずだ.

追記 (2019/04/15)

Chrome だと, a タグもうまく改行されないっぽいので, a タグにも overflow-wrap: break-word; を追加する必要があるっぽかった.

あと,その関係でテーブルを使ってる footnote もダメみたいなので, footnote の方はハイライト付きコードブロックと同じ対応をした.