見出し画像

【Flexbox】孫要素まで高さを揃える方法 #2 li全体をリンクにしたい場合

備忘的に書いた以前の記事で、「詳しくはこちら」のようなボタンがあることを前提にFlexboxで良くあるサンプルを作りましたが、稀に良くある要望として「リスト全体をリンクにしたい」というものがあると思います。
以前の書き方の場合、階層が深くなるために以前の書き方では解決しないので、解決策を考えてみました。

「li > a > 高さをそろえたい要素」にするとうまく行かない

画像1

↑の画像のようにリストのボックス全体をリンクにしたいと要望があった場合、よくある書き方は下記のような形だと思います。

<li>
  <a href="xxx">
    リスト内要素
  </a>
</li>

この書き方の場合、前回記事で言う「孫要素」がaタグになってしまうので解決しません。
前回記事のコードをこの形に修正するとこうなります。

<html>
<head></head>
<body>
<style type="text/css"> 
 .wrapper {
   width: 1024px;
   margin: 0 auto;
   padding: 60px 20px;
   background-color: #ddd;
 }
 .archive-list {
   display: flex;
 }
 .archive-list a {
   color: #000;
 }
 .archive-item {
   width: 30%;
   padding: 10px;
   background-color: #fff;
   display: flex;
   flex-direction: column;
   
 }
 .archive-img-wrap {
   width: 100%;
   height: 150px;
   margin-bottom: 10px;
 }
 .archive-img-wrap img {
   width: 100%;
   height: 100%;
   object-fit: cover;
 }
 .archive-item:not(:nth-child(3n)) {
   margin-right: 20px;
 }
 .archive-ttl {
   margin-bottom: 10px;
   line-height: 1.5;
   background-color: skyblue;
   flex-grow: 1;
 }
 .btn-more {
   display: block;
   margin: 0 auto;
   height: 40px;
   line-height: 40px;
   border-radius: 20px;
   padding: 0 20px;
   text-align: center;
   background-color: navy;
   color: #fff;
 }

 </style>

 <div class="wrapper">
   <ul class="archive-list">
     <li class="archive-item">
       <a href="">
         <div class="archive-img-wrap">
           <img src="./thum.png" alt="">
         </div>
         <p class="archive-ttl">タイトルタイトルタイトルタイトル</p>
         <span href="" class="btn-more">詳しくはこちら</span>
       </a>
     </li>
     <li class="archive-item">
       <a href="">
         <div class="archive-img-wrap">
           <img src="./thum.png" alt="">
         </div>
         <p class="archive-ttl">タイトルタイトルタイトルタイトルタイトルタイトルタイトルタイトルタイトルタイトルタイトルタイトルタイトルタイトル</p>
         <span href="" class="btn-more">詳しくはこちら</span>
       </a>
     </li>
     <li class="archive-item">
       <a href="">
         <div class="archive-img-wrap">
           <img src="./thum.png" alt="">
         </div>
         <p class="archive-ttl">タイトルタイトルタイトルタイトルタイトルタイトルタイトル</p>
         <span href="" class="btn-more">詳しくはこちら</span>
       </a>
     </li>
   </ul>
 </div>
   
</body>
</html>

この書き方だと、残念ながらこうなります。

キャプチャ

aタグを階層構造にしないことで解決

aタグの下層に画像やタイトルを入れることができなくなるので、無理やりですがこんなやり方で解決してみました。

HTMLの変更箇所

  <li class="archive-item">
   <div class="archive-img-wrap">
     <img src="./thum.png" alt="">
   </div>
   <p class="archive-ttl">タイトルタイトルタイトルタイトル</p>
   <span href="" class="btn-more">詳しくはこちら</span>
   <a href=""></a>
 </li>

CSSの変更箇所

  .archive-item {
   width: 30%;
   padding: 10px;
   background-color: #fff;
   display: flex;
   flex-direction: column;
   position: relative;
 }
 .archive-item a {
   position: absolute;
   top: 0;
   left: 0;
   display: block;
   width: 100%;
   height: 100%;
 }

これで解決しました。

(読み飛ばし可)簡単な説明

aタグの下層に画像やタイトルを入れ子できないので、画像などと並列の位置にaタグを移動しました。
aタグでクリックできる範囲をリスト全体に広げるために、
・絶対配置にして座標0,0に配置
・幅と高さを100%に設定
ということをしています。

これだけだと、HTML全体の座標0,0にぶっ飛んで行ってしまうため、aタグの親要素であるliタグにposition:relativeを追加することで、絶対配置の基準位置をliタグの0,0に変更しています。
参考までに修正後のソースも貼っておきます。

<html>
<head></head>
<body>
<style type="text/css"> 
 .wrapper {
   width: 1024px;
   margin: 0 auto;
   padding: 60px 20px;
   background-color: #ddd;
 }
 .archive-list {
   display: flex;
 }
 .archive-item {
   width: 30%;
   padding: 10px;
   background-color: #fff;
   display: flex;
   flex-direction: column;
   position: relative;
 }
 .archive-item a {
   position: absolute;
   top: 0;
   left: 0;
   display: block;
   width: 100%;
   height: 100%;
 }
 .archive-img-wrap {
   width: 100%;
   height: 150px;
   margin-bottom: 10px;
 }
 .archive-img-wrap img {
   width: 100%;
   height: 100%;
   object-fit: cover;
 }
 .archive-item:not(:nth-child(3n)) {
   margin-right: 20px;
 }
 .archive-ttl {
   margin-bottom: 10px;
   line-height: 1.5;
   background-color: skyblue;
   flex-grow: 1;
 }
 .btn-more {
   display: block;
   margin: 0 auto;
   height: 40px;
   line-height: 40px;
   border-radius: 20px;
   padding: 0 20px;
   text-align: center;
   background-color: navy;
   color: #fff;
 }

 </style>

 <div class="wrapper">
   <ul class="archive-list">
     <li class="archive-item">
       <div class="archive-img-wrap">
         <img src="./thum.png" alt="">
       </div>
       <p class="archive-ttl">タイトルタイトルタイトルタイトル</p>
       <span href="" class="btn-more">詳しくはこちら</span>
       <a href=""></a>
     </li>
     <li class="archive-item">
       <div class="archive-img-wrap">
         <img src="./thum.png" alt="">
       </div>
       <p class="archive-ttl">タイトルタイトルタイトルタイトルタイトルタイトルタイトルタイトルタイトルタイトルタイトルタイトルタイトルタイトル</p>
       <span href="" class="btn-more">詳しくはこちら</span>
       <a href=""></a>
     </li>
     <li class="archive-item">
       <div class="archive-img-wrap">
         <img src="./thum.png" alt="">
       </div>
       <p class="archive-ttl">タイトルタイトルタイトルタイトルタイトルタイトルタイトル</p>
       <span href="" class="btn-more">詳しくはこちら</span>
       <a href=""></a>
     </li>
   </ul>
 </div>
   
</body>
</html>

メリット・デメリット

このやり方の場合、HTMLの文章構造的には正しくない(あるべき姿ではない)気がしますが、完成目前で「やっぱり全体をクリックできるようにしてほしい」という要望が出たときでも階層構造を変える必要が無いということがあると思います。
a:hoverにスタイルを設定している際はそのスタイルが効かなくなってしまいますので、liタグに改めて設定する必要がある点が若干面倒な感じでしょうか。

おわりに

前回記事同様、記事系のサイトを制作する際はよくあるシチュエーションですし、モバイル端末を意識するとクリッカブルなエリアは多い方が良いという結論になることも多いですので、こちらの書き方の方がよく使うことになるかもしれません。

この記事が気に入ったらサポートをしてみませんか?