skip to Main Content

Creating a heart shape is not a problem. A few examples can be found here:
How to create a heart shape using CSS?

The problem with these solutions is if you want the heart shape to be clickable, the whole HTML element is clickable (a DIV tag or an IMG tag) and not only the heart shape.

I found a solution to create a clickable heart here: https://codepen.io/bailey_jones/pen/jONaONK

Code snippet:

    
    #heart {
      position: relative;
      width: 100px;
      height: 90px;
    }
    #heart:before,
    #heart:after {
      position: absolute;
      content: "";
      left: 50px;
      top: 0;
      width: 50px;
      height: 80px;
      background: red;
      border-radius: 50px 50px 0 0;
      transform: rotate(-45deg);
      transform-origin: 0 100%;
    }
    #heart:after {
      left: 0;
      transform: rotate(45deg);
      transform-origin: 100% 100%;
    }
<a id="heart" href="#"></a>

Here position: absolute is used. I want to use position: relative and the size of the heart to be relative to the parent container and I want it to be centered in the parent container. which should not be difficult, but my heart shape is malformed.

Code snippet:

body {
  width: 90vw;
  height: 90vh;
}

body,
#container {
  display: flex;
  align-items: center;
  justify-content: center;
}

#container {
  width: 400px;
  height: 400px;
  background: yellow;
}

#heart {
  position: relative;
  --width: 100%; /* was 100px, is 400px */
  --height: 90%; /* was 90px, is 360px */
  --x: calc(.5 * var(--width)); /* was 50px, is 200px */
  --y: calc(8/9 * var(--height)); /* was 80px, is 320px */
  width: var(--width); /* was 100px, is 400px */
  height: var(--height); /* was 90px, is 360px */
  border: 1px dotted blue;
}
#heart:before,
#heart:after {
  position: absolute;
  content: "";
  left: var(--x);
  top: calc(var(--height) - var(--y)); /* Does this make sense? */
  width: var(--x);
  height: var(--y);
  background: red;
  border-radius: var(--x) var(--x) 0 0;
  transform: rotate(-45deg);
  transform-origin: 0 100%;
}
#heart:after {
  left: 0;
  transform: rotate(45deg);
  transform-origin: 100% 100%;
}
<div id="container">

<a id="heart" href="#"></a>

</div>

The worst of all, now not only the heart shape is clickable. Why and how to fix this?

2

Answers


  1. My heart shape works well with some adjustment. There is a little space at the top that is clickable but I don’t think it’s a big deal.

    .heart {
      display: inline-block;
      width: 200px;
      aspect-ratio: 1;
      border-image: radial-gradient(var(--c,red) 69%, #0000 70%) 84.5%/50%;
      clip-path: polygon(-41% 0, 50% 91%, 141% 0);
      border-radius: 30%;
    }
    
    a:hover {
      --c: blue;
    }
    <a class="heart" href="#"></a>

    A more complex clip-path can eliminate that space:

    .heart {
      display: inline-block;
      width: 200px;
      aspect-ratio: 1;
      border-image: radial-gradient(var(--c,red) 69%, #0000 70%) 84.5%/50%;
      clip-path: polygon(-41% 0,40% 0,50% 8%,60% 0,141% 0,50% 91%);
      border-radius: 30%;
    }
    
    a:hover {
      --c: blue;
    }
    <a class="heart" href="#"></a>
    Login or Signup to reply.
  2. Use an SVG which contains the link you want.

    svg {
      transform:rotate(-135deg);
      stroke: red;
      stroke-width:0;
      height: 50vh;
      margin: 1.5rem;
    }
    
    path {
    fill: red;
    transition: fill 1s ease;
    }
    
    path:hover {
    fill: blue;
    }
    <svg
    xmlns="http://www.w3.org/2000/svg" viewbox="0 0 300 300 " >
      <a href="#">
      <path
        d="M0 200 v-200 h200 
        a100,100 90 0,1 0,200
        a100,100 90 0,1 -200,0
        z" />
      </a>
    </svg>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search