上付き文字 sup と下付き文字 sub を正しく表示させる
ブログで上付き文字 sup
や下付き文字 sub
を使うと、場合によって正しく表示されないことがありました。本記事ではその原因と解決方法について述べていきます。
上付きにも下付きにもならないことがあった
ある日、上付き文字(superscript)や下付き文字(subscript)をブログで表示させる方法を調べていると、自分の想定する用途だと HTML タグの sup
と sub
を使えばいいことがわかりました。
- <sup>: 上付き文字要素 - HTML: HyperText Markup Language | MDN
- <sub>: 下付き文字要素 - HTML: HyperText Markup Language | MDN
どっちも存在をおぼろげに知っていたものの、どういう用途で使うのかわからなかったタグです。おそるおそるテストブログで使ってみると、以下のようにちゃんと上付きや下付きで表示されました。
Cr2O72- + 14H+ + 6e- → Cr3+ + 7H2O
<p>Cr<sub>2</sub>O<sub>7</sub><sup>2-</sup> + 14H<sup>+</sup> + 6e<sup>-</sup> → Cr<sup>3+</sup> + 7H<sub>2</sub>O</p>
この時点で目的は達成できたのですが、ふと、他のテーマではどう表示されるのか気になりました。試しにテストブログに別のテーマを適用させてみると以下のように表示されました(状況再現のために sup
と sub
の代わりに span
を使用)。
Cr2O72- + 14H+ + 6e- → Cr3+ + 7H2O
ちゃんとタグを使ったはずなのに上付きにも下付きにもならず、文字サイズも通常の文字と同じように表示されています。
犯人はリセット CSS
CSS が原因だと検討がついたので、上付きにも下付きにもならなかったほうのテーマのソースコード内を「sup」で検索すると、テーマの CSS の中に以下のような記述を見つけました(コードの一部を省略、整形済み)。
[前略], sub, summary, sup, [中略] {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent
}
上記のコードはいわゆるリセット CSS と呼ばれるものの一部です。リセット CSS とは、ブラウザ固有のデフォルト CSS である user agent stylesheet を打ち消してブラウザ間の表示を揃えるための CSS のことを指します。
他の箇所の記述も照らし合わせたところ、このテーマでは HTML5 Doctor Reset CSS をベースとしたリセット CSS を採用していることがわかりました。
上に示した CSS の中で特に注目したいのが以下の 2 行です。
font-size: 100%;
vertical-align: baseline;
1行目で通常の文字と同じ文字サイズに変更され、2行目で要素のベースライン(基準線)が親要素のベースラインに揃えられています。この記述が原因で、sup
と sub
が通常の文字と同じように表示されてしまったわけです。
sup と sub に対しての各ブラウザの user agent stylesheet
主要ブラウザである Chrome, Safari, Firefox, Edge の sup
と sub
における user agent stylesheet を調べたところ、どのブラウザでも以下のように記述されていました。
sub {
vertical-align: sub;
font-size: smaller
}
sup {
vertical-align: super;
font-size: smaller
}
- Chrome:Source/core/css/html.css - chromium/blink - Git at Google
- Safari:webkit/trunk/Source/WebCore/css の html.css – WebKit
- Firefox:html.css - mozsearch
- Edge:公式文書が見つからなかったため、Windows 版のバージョン 112.0.1722.58 で検証
vertical-align
を sub
にすると下付きの位置に、super
にすると上付きの位置に文字を移動できます。
また、font-size
に smaller
を指定することで、文字サイズを親要素よりも 1 段階小さくしています。下記のリンク先によると、文字サイズが 1 段階上がるごとに 1.2 倍になるとのことなので、smaller
の場合はその逆数の 1/1.2 = 0.83333... ≒ 0.83 倍です。
sup と sub を正しく表示させる CSS
ここまでの内容を踏まえ、リセット CSS で打ち消された sup
と sub
をちゃんと上付きや下付きにさせる CSS について考えてみます。
まず手っ取り早く表示させるなら、前項でも紹介した、主要ブラウザの user agent stylesheet に採用されているこちらを使うのがいいでしょう。
sub {
vertical-align: sub;
font-size: smaller
}
sup {
vertical-align: super;
font-size: smaller
}
個人的には font-size
が smaller
(親要素の文字サイズの約 0.83 倍)だと少し大きめに感じるので、.75em
や 75%
くらいがちょうどいいかなと思います。
ただし、上記の CSS には少し厄介な問題があります。sup
と sub
が上下にはみ出ることで、行間 line-height
がずれてしまうのです。
これを防ぐための方法はいくつかありますが、ここでは、リセット CSS Destyle.css の sup
と sub
に関わる CSS を紹介します。
/*! destyle.css v4.0.0 | MIT License | https://github.com/nicolas-cusan/destyle.css */
sub, sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline
}
sub {
bottom: -.25em
}
sup {
top: -.5em
}
vertical-align: baseline
で文字の垂直方向の位置をベースラインに揃え、position: relative
で sup
と sub
が相対的な位置をとるよう設定します。sub
を bottom
で下方向に、sup
を top
で上方向に位置をずらすことで、デフォルトの行間に影響を与えずに上付き文字、下付き文字を使うことができます。
ちなみに、相対位置を em
(現在のフォントサイズが基準)ではなく ex
(小文字の x の高さが基準)で指定する場合もあるようです。
あとがき
sup
と sub
を使った文字が正しく表示されないことがあったため調査してみると、ブログのテーマで使用されていたリセット CSS が原因であることがわかりました。また、各ブラウザの user agent stylesheet や別のリセット CSS などを参考にし、正しく上付き・下付きになるような CSS を紹介しました。
便利なものとして認識していたリセット CSS が、こうして HTML の表示に悪影響を与えてしまうこともあるのだと学びました。記述内容をちゃんと理解しないで闇雲に使ってはいけませんね。
最後に念のため言っておくと、じゃあ HTML5 Doctor Reset CSS が劣っていて、Destyle.css が優れているという話では全然ありません!! どちらにもメリット・デメリットはあると思うので、それを踏まえたうえで自分好みのリセット CSS を使うのがおすすめです。