装飾のためのタグを書くのはやめて正しいHTMLを書こう

「そのフロントエンドの不具合、もしかしたらタグの書き方が原因かも？」ということが度々あるので、より正しいHTMLを書いて不具合の種を潰そう！という話です。

# 1. \<button> の中に \<a> を書くのをやめよう！
最もよく見る誤りの例。
HTMLのルール的に正しくない（後述）というのは勿論のこと、様々な不具合の原因になります。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="LEVZQEY" data-pen-title="001" data-user="Sekappy" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/Sekappy/pen/LEVZQEY">
  001</a> by SekappyOfficial (<a href="https://codepen.io/Sekappy">@Sekappy</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

\<button> の中に \<a> が書かれているボタンっぽい見た目のリンク。
ボタンの中を押しても無反応な箇所と、正しくリンクが動作する箇所が存在します。

どうしてそうなるのか、 \<button> \<a> それぞれにoutlineを表示するようにして再度ボタンを押して確認してみます。
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="bNdeLwa" data-pen-title="002" data-user="Sekappy" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/Sekappy/pen/bNdeLwa">
  002</a> by SekappyOfficial (<a href="https://codepen.io/Sekappy">@Sekappy</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

\<a> のoutline（赤線）の中をクリックしたときだけリンクが効いていることがわかります。
デフォルトで \<a> は[インライン要素](https://developer.mozilla.org/ja/docs/Glossary/Inline-level_content)のため、「click」の文字だけが \<a> 要素の範囲になっています。（たとえブロック要素だったとしても \<button> が持っている padding などの余白周辺はクリックしても反応しない領域が生まれます）
これが「見た目は正しいのに押しても反応しない箇所がある」というような不具合が頻発する要因となります。


一応 \<a> の中に \<button> を書けばどこを押しても動作するようになりますが、これも文法的に間違っているので良くないです。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="PwqzQbK" data-pen-title="003" data-user="Sekappy" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/Sekappy/pen/PwqzQbK">
  003</a> by SekappyOfficial (<a href="https://codepen.io/Sekappy">@Sekappy</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

また、 \<button> はデフォルトのtypeがsubmitのため \<form> の中にこのようなリンクがあった場合「別の画面に遷移させたいだけなのにボタンを押したらフォームが送信されてしまう」という事象が起きてしまう可能性もあります。

# 2. HTMLを正しく書こう！
 [ボタン要素（＜button＞）](https://developer.mozilla.org/ja/docs/Web/HTML/Reference/Elements/button) の中に記述して良いとされているコンテンツは “記述コンテンツ、 **但し対話型コンテンツがあってはならない** ” とあり、[アンカー要素（＜a＞）](https://developer.mozilla.org/ja/docs/Web/HTML/Reference/Elements/a) のコンテンツカテゴリは “フローコンテンツ、記述コンテンツ、 **対話型コンテンツ** 、知覚可能コンテンツ” であるため \<button> の中に \<a> を記述することは許可されていないため誤りです。

逆の場合もアンカー要素の中に許可されている要素が “透過的コンテンツ、ただし子孫に対話型コンテンツ または a 要素をがないもの（略）” であり、ボタン要素は対話型コンテンツかつ透過的コンテンツではないため \<a>\<button>ボタンリンク\</button>\</a> という記述は誤りということになります。

このようにHTMLの要素にはコンテンツのカテゴリが決まっていて、要素ごとに中に記述することが許可されている／されていない要素が定められているため、それに沿って記述されたHTMLがより正しいHTMLということになります。
全部覚えていれば最高ですが、あまり現実的ではないので主要なタグだけ覚えて残りは想定した通りに表示がされないと思ったときに一度確認してみる程度で良いと私は思っています。

# 3. まとめ：「特定の見た目にしたい」という理由でタグを使うのはやめよう！スタイルはCSSでつけよう！
HTML（HyperText Markup Language）は構造を表すためのものなので、構造ではなく見た目のためだけに特定のタグを使用するというのは不適切です。
「ボタンの見た目にするために \<button> タグを使う」「文字を太字にしたいから \<strong> タグを使う」といったタグの使い方は図が描けるからとPowerPointやExcelで画面設計書を作るようなもので、本来の用途として正しくないし、正しくないので不都合が起こりやすいのです。
\<button> はボタンを表すためだけに使用され、\<strong> は[重要な文字を強調するため](https://developer.mozilla.org/ja/docs/Web/HTML/Reference/Elements/strong)に使用されなければなりません。
HTMLで記述された要素の見た目の表現をするためにCSSが存在するので、見た目を変えたい場合はCSSで調整しましょう。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="pvJbaRx" data-pen-title="Untitled" data-user="Sekappy" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/Sekappy/pen/pvJbaRx">
  Untitled</a> by SekappyOfficial (<a href="https://codepen.io/Sekappy">@Sekappy</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

今回の例では \<button> と \<a> の見た目を同じにしたいので、 同じスタイルで表示されるように .button-style のclassを追加したCSSを追加するのがベストとなります。