🕹️

[備忘録]ボタン風リンクには inline-block を付けるのを忘れない

2025/02/23に公開

半年に一回くらい忘れて「何が起こってるんだ……」となるのでメモ。

今回遭遇した環境は React + Tailwind CSS だが、これに限らない問題のはず。

Button(buttonタグ) と Link(aタグ) で同じような見た目にしたいケースがある。
しかし、同じ CSS 記述を適用すると、Link だと意図と異なる見た目になることがある。

  • 高さがおかしくなる(想定より小さくなる)
  • 親の padding がおかしくなる(想定より小さくなる)

これは、Button はデフォルトで display: inline-block が指定されているが、Link は display: inline が指定されているため。

サンプルコード(CodePen): ※これは素の CSS & HTML

現象1:高さがおかしくなる(想定より小さくなる)

Button と Link(inline-block あり) と Link(inline-block なし) を並べると Link(inline-block なし) だけ高さが小さい

同じ padding を指定しているのに、Button と Link で高さが異なる場合がある。
これは、display: inline-block である Button だと line-height が効いているが、display: inline である Link だと効いていないため。

例では、

  • font-size は 16px
  • line-height は 24px
  • padding-y は 8px

その結果、
Button は 24 + 8 * 2 = 40px の高さになるが、
Link は 16 + 8 * 2 = 32px の高さになっている。

Button Link (inline-block あり) Link (inline-block なし)
40px 40px 32px

(これを意外に思ってしまったのは、今まで line-height はデザイナ任せでちゃんと意識できていなかったせいかもしれない……)

現象2:親の padding がおかしくなる(想定より小さくなる)

Link だと、親の padding が貫通?しているように見える

親に padding がある場合、Link だと、ボタン部分が親の padding に貫通?しているようで、結果的に親の padding の見た目が想定より小さくなる。
これはよく見ると、Link では padding を含めた領域ではなく、line-height (現象1だと無視されてたのに!) の部分が親の padding の内側に収まるようになっているように見える。

例では、先の例に加えて、

  • 親の padding は 16px

その結果、
Button の親は 24 + 8 * 2 + 16 * 2 = 72px の高さになるが、
Link の親は 24 + 16 * 2 = 56px の高さになっている。

(これは開発者ツールで見たときに何が起こっているのかわかりにくい……
また、padding が全く効いていないわけではないので、記述だけ見ているとズレてること自体に気付かないかもしれない。)

番外:改行の問題

そもそも上記のような問題がなかったとしても、ボタンの輪郭が歪む形での改行を防ぐために display: inline-block を指定しておいた方が良い。

(display: inline-block の指定を入れて wrap してるだけの、ButtonLink コンポーネントが欲しくなってきた……)

最後に

デザインシステムがしっかり整備されている環境であればエンジニア側が気にする場面は少ないのかもしれないが、そんな環境ばかりではないので……

他のケースだと、span でタグ風の見た目を作った場合などでも陥るかもしれない。

CSS は最も難しいプログラミング言語である……

ちなみに、久々の記事投稿 & Zenn での初投稿でした 🙏

Discussion