お疲れ様です!るーぷのコーダー、三木です。
この間、弊社のブログ一覧を、珍しくスマホで眺めていたんですが、
スマホ表示だとサムネイルが結構大きく表示されますよね。
それで気づいたんですが、「あ、この記事ワイやな。。。」っていうのがサムネイル見てたら一発で分かっちゃうんですよね。
何故かって?
いや…そんなことより今日もCSSについてお話しさせてくださいよ。ね?
目次
今回実現したい内容
今回はお知らせのような一覧ページで、
- ・記事にホバー(マウスオーバー)したら、サムネイルが大きくなりつつタイトルに下線が引かれ、クリックしたら記事詳細へ遷移する。
- ・記事のタグの部分はタグの一覧ページへ遷移するので、サムネイルは大きくならないしタイトルに下線も引かない。
この挙動を実現します。
実際の動きは↓で確認できます。
失敗例
とりあえずaタグで囲んで、タグだけ更にaタグでええでしょ。

HTML
<li>
<a href=”記事のURL”>
<div class=”thumb”><img src=”./thumb01.jpg” alt=”></div>
<div class=”text_wrapper”>
<ul class=”tag_list”>
<li><a href=”タグ1のURL”>#タグ1</a></li><li><a href=”タグ2のURL”>#タグ2</a></li>
</ul>
<p class=”news_title”>タイトルが入ります01タイトルが入ります01タイトルが入ります01タイトルが入ります01</p>
</div>
</a>
</li>
<li>2つ目のliは割愛。</li>
</ul>
上記コードの結果はこちら↓
何故かサムネイルが表示されません。
↓検証モードで確認してみます。

aタグが何故かサムネイルを囲んだだけのところで一回閉じられています。
そして画像の横も縦も0pxになっているのでもう訳がわかりません…
失敗の原因
少し調べたところ、どうやらaタグにaタグを入れ子にすることはHTMLが許していないようです。
じゃあ、各パーツaタグにするしかないじゃない。
aタグの中にaタグを入れられないなら、諦めてサムネイル・タグ・タイトルの3パーツをそれぞれaタグで囲むしかないですよね。

でもこれだと、それぞれのaタグでしかホバーイベントを発生させられないので、
- ・記事にホバー(マウスオーバー)したら、サムネイルが大きくなりつつタイトルに下線が引かれ、クリックしたら記事詳細へ遷移する。
- ・記事のタグの部分はタグの一覧ページへ遷移するので、サムネイルは大きくならないしタイトルに下線も引かない。
この一つ目「サムネイルが大きくなりつつタイトルに下線が引かれ」という
2つの要素を同時に動作させることができないじゃないですか?
擬似クラス「:has()」で解決する。
CSSには、例えば先ほどから言っている「ホバーした時に…」という動作を実現する「:hover」という擬似クラスがあります。
CSS例
text-decoration: underline;
}
そして擬似クラスの中には、「〇〇が含まれていたら」を意味する「:has()」というものがあります。
例えば、先ほどのお知らせ一覧のような場合に
- ・サムネイルがある時は「横幅がサムネイル30%:テキスト領域65%」
- ・サムネイルがない時は「テキスト領域100%」
にすることができます。
CSS例
width: 30%;
}
.news_list li .text_wrapper{
width: 100%;
}
.news_list li:has(.thumb) .text_wrapper{
width: 65%;
}
結論
つまり、
- ・サムネイルをホバーしたら拡大
- ・「ホバーされたタイトル」を含んだliの中にあるサムネイルを拡大
- ・タイトルをホバーしたら下線を引く
- ・「ホバーされたサムネイル」を含んだliの中にあるタイトルに下線を引く
- ・タグをホバーしたらタグに下線を引く(本題にはあまり関係ないですが一応)
この内容をCSSに書ければ、冒頭でも紹介した動作が実件できます。
それでは実際のコードがこちら。
HTML
<ul class=”news_list”>
<li>
<a href=”記事のURL” class=”thumb”><img src=”./thumb01.jpg” alt=””></a>
<div class=”text_wrapper”>
<ul class=”tag_list”>
<li><a href=”タグ1のURL”>#タグ1</a></li><li><a href=”タグ2のURL”>#タグ2</a></li>
</ul>
<a href=”記事のURL” class=”news_title”><p>タイトルが入ります01タイトルが入ります01タイトルが入ります01タイトルが入ります01</p></a>
</div>
</li>
<li>2つ目のliは割愛。</li>
</ul>
CSS (重要な部分以外は割愛)
.news_list > li:has(.news_title:hover) .thumb img{
transform: scale(1.1);
}
.news_list > li .news_title:hover,
.news_list > li:has(.thumb:hover) .news_title{
text-decoration: underline;
}
おわりに
今回ご紹介した「:has」はちょうど3年ほど前に初登場した、比較的新しい要素ですが、
最近では主要ブラウザの多くのバージョンに対応しています。
ほぼ問題なく動作するはずですが、弊社は地域密着型のWEB制作会社であり、中には古いPCをお使いのお客様もいらっしゃるので、比較的新しいコードの使用は慎重になります。
しかし今回のような用途で使用する場合、仮に「サムネイルをホバーしてもタイトルに下線が引かれない」としても、サイトの機能としては困らないため、積極的に使用することができます。
このように「これが機能しなかった場合ユーザーに不便をかけるか。」を判断材料にしつつ、新しい技術を使っていきたいですね。