こんにちはwebエンジニアのtakaです。
皆さんこんなデザインをコーディングしないといけない経験ありませんか?
カードの枠をクリックすると記事の詳細ページに遷移し、「HTML」や「CSS」のタグをクリックすると、「HTML」のタグが付いた記事一覧に飛ばしたい状況です。
このようなaタグを入れ子(ネスト)しないといけない場合の対処法をこの記事では伝えていきます!
間違った例
先ほどのデザインを素直にコーディングするとだいたいこんな感じかと思います。
// HTML
<a class="card" href="・・・">
<img src="・・・" width="100%" heght="auto">
<ul class="tag_wrapper">
<li class="tag_list">
<a href="・・・" class="tag_anchor">HTML</a>
</li>
<li class="tag_list">
<a href="・・・・" class="tag_anchor">CSS</a>
</li>
</ul>
<p class="card_text">テキストテキストテキストテキスト・・・・</p>
</a>
// CSS
.card {
background-color: #ccc;
display: block;
padding: 12px;
width: 200px;
}
.tag_wrapper {
display: flex;
list-style: none;
margin-top: 12px;
width: 200px;
}
.tag_wrapper .tag_list {
background-color: orange;
margin-right: 4px;
}
.card .card_text {
margin-top: 12px;
}
しかしGoogleChromeの検証で確認すると、画像のようにtag_anchor
クラスがついたaタグが強制的にcardクラスがついたaタグの外に出されてしまいます。
ちなみにtag_anchorクラス
がついたaタグを削除するとカードのデザインです。
// HTML
<a href="・・・" class="card">
<img src="https://t-file.blog/wp-content/uploads/2021/09/3225884_m-1024x664.jpg" width="100%" height="auto">
<ul class="tag_wrapper">
<li class="tag_list">HTML</li>
<li class="tag_list">CSS</li>
</ul>
<p class="card_text">テキストテキストテキストテキスト・・・・</p>
</a>
tips!
CSSはa~z順に記載すると、後でコードを見る際に探しやすいよ!チームで開発するなら当たり前のようにできるようにしよう!
tips!
このようにクラス名ではなくpという風にhtmlタグをcssのセレクタに設定すると、レンダリングの速度が遅くなることが多いよ!(ファイル内の全てのpタグを検索し、その親要素にcardが設定されているものを探します。pタグをたくさん利用していると、cardというクラスを親要素に持っているか確認する際に母数が多くなるので時間がかかってしまいます。)
// CSS
.card p {
margin-top: 12px;
}
なるべくクラス名を指定して下のように記載しよう!
// CSS
.card .card_body {
margin-top: 12px;
}
なぜaタグを入れ子にできないのか?
htmlタグにはコンテンツモデルというものが存在します。
「divのようなフローコンテンツの中にはほとんどのタグを入れることができる」などタグそれぞれにルールが決まってあります。
aタグは、他のインタラクティブ・コンテンツを入れ子にすることはできません。
※インタラクティブ・コンテンツで代表的なものはaタグやinputタグやselectタグです。
なのでaタグにaタグを入れ子にしたり、buttonタグなどを aタグの子孫として設置することはできません。
普通に考えてaタグが入れ子の場合、どっちに遷移したらいいか判別できませんよね。
解決策は?
まずaタグは入れ子にできないのでこのようにしましょう。
// HTML
<a href="・・・" class="card">
<img src="https://t-file.blog/wp-content/uploads/2021/09/3225884_m-1024x664.jpg" width="100%" height="auto">
<ul class="tag_wrapper">
<li class="tag_list" data-tag="html">HTML</li>
<li class="tag_list" data-tag="css">CSS</li>
</ul>
<p class="card_text">テキストテキストテキストテキスト・・・・</p>
</a>
jQueryを利用し以下のように記載します。
// jQuery
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> // jQueryを読み込む
<script>
$(function() {
$('.tag_list').on('click', function() { // tag_listクラスをクリックした時に以下を実行する
var tag = $(this).data('tag'); // クリックしたtag_listクラスを持つタグのdata-tagに格納されている値を変数に格納
if (tag == 'html') {
window.location.href = "https://・・・"; // htmlタグ押した時のURLを記載する
} else if (tag == 'css') {
window.location.href = "https://・・・"; // cssタグ押した時のURLを記載する
}
return false; // これがないと、window.lacation.hrefが実行される前に、aタグの遷移が実行される
});
});
</script>
jQueryを利用することであたかもaタグが入れ子しているように見せました。
tips!
以下のようにonではなくclickイベントで記載することもできます。
$('.tag_list').click(function() {
しかし、clickイベントは、JavaScript(jQuery)を利用して追加したHTMLタグには効かないので、onを利用するのをお勧めします。