[CSS] チェックボックスやラジオボタンの中央揃え2024年版

CSS でチェックボックスやラジオボタンなどを、並列する文字列に対して垂直方向に中央揃えできないといった問題に直面することがあります。

今回は、この問題に対処するための2024年現在における最適解の1つを紹介します。

デフォルトスタイルをリセットする

チェックボックスとラジオボタンには、デフォルトスタイルがあるので、まずはこれらをリセットします。

チェックボックスとラジオボタンの HTML は次のようになっています。

<p><input type="checkbox" checked /> チェックボックス</p>
<p><input type="radio" checked /> ラジオボタン</p>

そして、理解しやすいように次のスタイルが適用されています。

body {
  line-height: 2;
}
p, input {
  outline: dotted 1px;
}

リセットは次のようなコードでできます。

:where(input[type="checkbox"], input[type="radio"]) {
  font-size: inherit;
  line-height: inherit;
  margin: 0;
}

この時点では、並列している文字列に対して中央揃えになっているように見えます。

サイズを調整する

:where(input[type="checkbox"], input[type="radio"]) {
  font-size: inherit;
  line-height: inherit;
  margin: 0;
  block-size: 1.5em;
  inline-size: 1.5em;
}

フォントサイズの1.5倍の大きさに調整したら、上の方向に大きくなりました。これは垂直方向の配置のデフォルトがベースラインを基準にしているためです。そのため、小さくした場合には上に余白ができることになります。

配置を調整する

垂直方向の配置を変更するために vertical-align プロパティを設定します。

:where(input[type="checkbox"], input[type="radio"]) {
  font-size: inherit;
  line-height: inherit;
  margin: 0;
  block-size: 1.5em;
  inline-size: 1.5em;
  vertical-align: middle;
}

これで中央揃えになれば苦労しないのですが、画像のとおり、中央からずれた表示になっています。そこで、次のように手を加えます。

:where(input[type="checkbox"], input[type="radio"]) {
  font-size: inherit;
  line-height: inherit;
  margin: 0;
  margin-block: calc((1lh - 1.5em) / 2);
  block-size: 1.5em;
  inline-size: 1.5em;
  vertical-align: middle;
  vertical-align: bottom;
}

まずは、vertical-align: bottom; で行の下端に揃えます。そして、垂直方向のマージンで位置を調整します。

マージンのサイズは、[行の高さ (1lh)] – [要素のサイズ (1.5em)] で行内の要素に占有されていない余白量を求め、上の余白と下の余白に2等分 (/ 2) した値になります。

これで、中央揃えにすることができます。

中央揃えした要素が行からはみ出る場合の対処

今回は、チェックボックスとラジオボタンを行の高さ (line-height: 2;) に収まるサイズ (1.5em) に設定し、フォントサイズに応じて大きさが変化するようにしましたが、pxrem を使用してフォントサイズの影響を受けないサイズにしたい場合もあるかと思います。

:where(input[type="checkbox"], input[type="radio"]) {
  font-size: inherit;
  line-height: inherit;
  margin: 0;
  margin-block: calc((1lh - 3rem) / 2);
  block-size: 3rem;
  inline-size: 3rem;
  vertical-align: bottom;
}

その場合、マージンの計算値がマイナス値になり、行からはみ出てしまう場合があります。

はみ出て欲しくない場合は、max 関数値を使用して 0px 未満にならないようにします。ただし、行の高さより大きくなると中央揃えではなくなってしまうので、どちらを選ぶかは人によりけりですね。

margin-block: max(0px, (1lh - 3rem) / 2);

そもそも vertical-align: middle; でなぜ中央揃えにならないのか?

mdn によれば、vertical-align プロパティの middle は、baseline + (1ex / 2) だと説明されています。

ex は「x」のような小文字のアルファベットのサイズを1とする単位です。つまり、小文字のアルファベットに対しては中央揃えになり、大文字のアルファベットや日本語に対しては中央揃えにならず、少し下にずれて表示されるということです。

vertical-align プロパティは数値やパーセント値も設定できるけど、微調整が困難な、なかなかの困ったちゃん。

でも、今回の方法を使えば、チェックボックスやラジオボタンだけでなく、画像アイコンなども中央揃えにすることができます。

関連記事