DEV Community

Douglas Berkley
Douglas Berkley

Posted on

Make a Card Clickable in CSS

On the surface, this one seems straight forward: a grid of clickable cards, easy right? Well as you may have seen when we use an anchor tag, it comes with some default styling we don't necessary want.

Image description

The Start

First, let's get a good looking card we can use. Let's take this one from the Le Wagon UI Kit.
Card
Looks sharp, right? But let's see what happens when we wrap the same code inside of an anchor tag.

<a href="#">
  <!-- card html -->
</a>
Enter fullscreen mode Exit fullscreen mode

Or the Rails way...

<%= link_to card_path do %>
  <!-- card html -->
<% end %>
Enter fullscreen mode Exit fullscreen mode

Image description

The Problem

This just ruined all of our style. We can click on it, but all the text had that text-underline and unfortunate blue. So, let's take a step back and take a different approach.

The Solution

This might seem strange at first, but we're not going to wrap the card in the link. We're going three dimensional here. We're going to place the link over the card.

First: we build a link inside of our card with no text inside of our link to display. Let's also create a new class called card-link

<a href="#" class='card-link'></a>
Enter fullscreen mode Exit fullscreen mode

Or the Rails way...

<%= link_to '', card_path, class: 'card-link'  %>
Enter fullscreen mode Exit fullscreen mode

Second: we make our card position: relative, then we can make our link position: absolute

Third: we stretch the link over the entirety of the card. Our link won't take up an space, so we have to give it some special css attributes. Pin it to the corners then stretch over the entire width like this:

top: 0;
bottom: 0;
left: 0;
width: 100%;
Enter fullscreen mode Exit fullscreen mode

Now we have a clickable card that looks like our original
Card

CSS

.card-trip {
  overflow: hidden;
  background: white;
  box-shadow: 0 0 15px rgba(0,0,0,0.2);
  position: relative; // NEEDED FOR THE LINK
}

.card-trip > img {
  height: 200px;
  width: 100%;
  object-fit: cover;
}

.card-trip h2 {
  font-size: 16px;
  font-weight: bold;
  margin: 0;
}

.card-trip p {
  font-size: 12px;
  opacity: .7;
  margin: 0;
}

.card-trip .card-trip-infos {
  padding: 16px;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  position: relative;
}

.card-trip-infos .card-trip-user {
  position: absolute;
  right: 16px;
  top: -20px;
  width: 40px;
}

// To stretch the link on top of the card div
.card-link {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

The ERB Way

<div class="card-trip">
  <%= image_tag "https://raw.githubusercontent.com/lewagon/fullstack-images/master/uikit/greece.jpg" %>
  <div class="card-trip-infos">
    <div>
      <h2>Title here</h2>
      <p>Short description here!</p>
    </div>
    <h2 class="card-trip-pricing">£99.99</h2>
    <%= image_tag "https://kitt.lewagon.com/placeholder/users/dmbf29", class: "card-trip-user avatar-bordered" %>
  </div>
  <%= link_to '', card_path(element), class: 'card-link'  %>
  <!-- You need to replace card_path with your appropriate route  -->
</div>
Enter fullscreen mode Exit fullscreen mode

The Pure HTML way

<div class="card-trip">
  <img src="https://raw.githubusercontent.com/lewagon/fullstack-images/master/uikit/greece.jpg" />
  <div class="card-trip-infos">
    <div>
      <h2>Title here</h2>
      <p>Short description here!</p>
    </div>
    <h2 class="card-trip-pricing">£99.99</h2>
    <img src="https://kitt.lewagon.com/placeholder/users/dmbf29" class="card-trip-user avatar-bordered" />
  </div>
  <a href="#" class='card-link'></a>
  <!-- You need to replace the href # with your appropriate route -->
</div>
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
gtoroap profile image
Gustavo Toro

I was looking for water and I found gold. Awesome trick. It works flawlessly.

Collapse
 
dani_el-dev profile image
Daniel Oyola

Hey, what a cool trick. I never would have imagined such a simple solution for this issue. I tried it and it worked perfectly. Thanks man!!!