【カード型レイアウト】クリック要素が複数ある場合のカードのリンク設定方法

今回はこのようなカードの作り方について解説していきます。

目次

完成形のコード

See the Pen card by ゆき | Web制作 (@yukimum22) on CodePen.

一般的なカード型レイアウトと違うところ

今回のカードの場合、以下3つがクリック要素となります。

  • 記事詳細へのリンク(画像とタイトル:ホバーアクション付き)
  • お気に入り登録のためのボタン(クリップのアイコン)
  • 絞り込みのためのタグ(#⚪︎⚪︎の部分)

一般的にカード型レイアウトの1つのカードを作る時、カード全体をaタグで囲む場合が多いと思います。

カード全体をリンクにする際には問題ありませんが、今回のようにカードの中に複数クリック要素がある場合、基本的にaタグの中にaタグは入れられないので、少し工夫が必要です。

コード解説

HTML

<div class="columnItem">
  <div class="columnItem__link">
    <a href=""></a>
    <div class="columnItem__img"><img src="画像パス" alt=""><button class="clip-btn"></button></div>
    <p class="columnItem__title">タイトル</p>
  </div>
  <div class="columnItem__tags">
  <a href="">#タグ</a>
  <a href="">#タグ</a>
  <a href="">#タグ</a>
 </div>
</div>

画像(columnItem__img)とタイトル(columnItem__title)をまとめてリンクにしたいので、columnItem__linkで囲います。
columnItem__linkの直下に空のaタグを仕込みます。

カード全体をaタグで囲ってしまうと、bottonタグやcolumnItem__tags内のaタグが効きません!

リンクにしたい要素がカード全体の場合は、columnItem__linkは要りません。columnItem直下にaタグを仕込みます。(下の図で青枠がなくなると考えてください。)

カード全体をaタグで挟まなければ、bottonタグやcolumnItem__tags内のaタグも効きます!

CSS

.columnItem {
  width:300px;
  display: flex;
  flex-direction: column;
}

.columnItem__link {
  position: relative;
}

.columnItem__link a {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
}

.columnItem__img {
  padding-top: 57%;
  position: relative;
  margin-bottom: 16px;
  border-radius: 20px;
  border: 3px solid #6aaabf;
  overflow: hidden;
}

.columnItem__img img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: all 0.2s ease;
}

.columnItem__link a:hover ~ .columnItem__img img {
transform: scale(1.1);
}

.columnItem .clip-btn {
  position: absolute;
  bottom: 12px;
  right: 14px;
  z-index: 1;
}

.columnItem__title {
  font-size: 18px;
  line-height: 1.5;
  min-height: 55px;
  transition: all 0.2s ease;
}

.columnItem__link a:hover ~ .columnItem__title {
  color: #6aaabf;
}

.columnItem__tags a {
  font-size: 12px;
  line-height: 1.5;
  letter-spacing: 0.05em;
  display: inline-block;
  color: #a3c5d9;
  margin-right: 0.5em;
  text-decoration: none;
}

/* クリップのボタン*/
.clip-btn {
  display: block;
  width: 35px;
  height: 35px;
  border-radius: 50%;
  position: relative;
  background-color: #fff;
  border: 1px solid #6aaabf;
  cursor: pointer;
}

.clip-btn.clicked {
  background-color: #6aaabf;
  border: 1px solid #fff;
}

.clip-btn::after {
  content: "";
  display: block;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 22px;
  height: 20px;
  background: no-repeat center/contain url(画像URL);
}

.clip-btn.clicked::after {
  background: no-repeat center/contain url(画像URL);
}

各要素のスタイルについては説明を省略します。ポイントとしては、7行〜18行(色の変わった部分)で、columnItem__linkにposition:relativeを指定し、その直下のaタグ(columnItem__link > a)にposition:absoluteを指定してcolumnItem__linkに被せるところです。
aタグを被せることで、columnItem__link全体がリンクとなります。

JavaScript

  //クリップボタンの切り替え
  $(function () {
    var buttons = document.querySelectorAll(".clip-btn");

    buttons.forEach(function (button) {
      button.addEventListener("click", function () {
        button.classList.toggle("clicked");
      });
    });
  });

なぜaタグの中のaタグはダメ?

リンク要素の中にリンク要素を入れてしまうと、単純にどちらに遷移するかわからない状態になってしまうので、基本的に入れ子にはできません。

HTMLのタグは6種類のカテゴリーに分かれており、属するカテゴリーにより「そのタグがどのカテゴリーの要素を入れて良いか」という入れ子のルール(コンテンツモデル)が存在します。

ちなみにaタグは「インタラクティブ・コンテンツ」に分類されます。インタラクティブ・コンテンツには他にもbutton、input、iframeなどがあり、ユーザーが操作可能なコンテンツとされています。

入れ子のルールはたくさんあるので、その都度確認しましょう。

入れ子のルールに関しては、こちらのチートシートが便利です!

以上になります。

\Web制作コーダーの営業にオススメ!/

こんな不安を解決します!

  • Web制作の面談ってどんなこと聞かれるの?
  • どんな風に答えればいいの?
  • オンラインの面談って何を準備したらいいの?

"少しでも面談の不安を減らしたい"という方はぜひお手に取ってみてください!

ゆき
体育会系2児ママ
Web制作コーダー(元理学療法士)。子供の出産を機に働き方を考え直しWeb制作の学習を始める。現在はフリーランスとして在宅ワークで活動中。
よかったらシェアしてね!
  • URLをコピーしました!
目次