skip to Main Content

I’m trying to create a heart-shaped button with this code:

MENU

.heart {
  --c: red;
  width: 200px;
  aspect-ratio: 1;
  background:
   radial-gradient(at 70% 31%,var(--c) 29%,#0000 30%),
   radial-gradient(at 30% 31%,var(--c) 29%,#0000 30%),
   linear-gradient(var(--c) 0 0) bottom/100% 50% no-repeat;
  clip-path: polygon(-43% 0,50% 91%, 143% 0);
  transition: all .5s;
}
.heart:hover {
  --c: blue;
  width: 200px;
  aspect-ratio: 1;
  background:
   radial-gradient(at 70% 31%,var(--c) 29%,#0000 30%),
   radial-gradient(at 30% 31%,var(--c) 29%,#0000 30%),
   linear-gradient(var(--c) 0 0) bottom/100% 50% no-repeat;
  clip-path: polygon(-43% 0,50% 91%, 143% 0);
}
<div class="heart">
    <button id="widget-toggle" class="widget-toggle-open drawer-toggle widget-toggle-style-default" data-toggle-target="#widget-drawer" data-toggle-body-class="showing-widget-drawer" aria-expanded="false" data-set-focus=".widget-toggle-close">
        <span class="widget-toggle-label">MENU</span>
        <span class="widget-toggle-icon">
        </span>
    </button>
</div>

But the no matter how I try it, the transition doesn’t work. Is there a way to make this and have the color change on hover have a duration?

Old posts said this may not have been possible. I did look around and didn’t see any recent Question/Answers that said this may have changed, So I’m hopeful that maybe there’s been some modernization?

2

Answers


  1. You can use the @property css at-rule for that, but firefox has only partial support.
    https://caniuse.com/?search=@property

    @property --c {
        syntax: '<color>';
        initial-value: red;
        inherits: false;
    }
    .heart {
        width: 200px;
        aspect-ratio: 1;
        background: 
            radial-gradient(at 70% 31%,var(--c) 29%,#0000 30%),
            radial-gradient(at 30% 31%,var(--c) 29%,#0000 30%),
            linear-gradient(var(--c) 0 0) bottom/100% 50% no-repeat;
        clip-path: polygon(-43% 0,50% 91%, 143% 0);
        transition: --c .5s;
    }
    .heart:hover {
        --c: blue;
    }
    <div class="heart">
        <button id="widget-toggle" class="widget-toggle-open drawer-toggle widget-toggle-style-default" data-toggle-target="#widget-drawer" data-toggle-body-class="showing-widget-drawer" aria-expanded="false" data-set-focus=".widget-toggle-close">
            <span class="widget-toggle-label">MENU</span>
            <span class="widget-toggle-icon">
            </span>
        </button>
    </div>

    Specs: https://developer.mozilla.org/en-US/docs/Web/CSS/@property

    Login or Signup to reply.
  2. No, you cannot transition a background.

    The simplest solution is to use an SVG element in your HTML. This is what SVG is good at: vector graphics. You then apply styles to that element using CSS.

    .heart {
      width: 200px;
      aspect-ratio: 1;
      transition: 1.5s;
      fill: red;
    }
    .heart:hover {
      fill: blue;
    }
    <svg class="heart" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
      <path d="M 200 60 C 200 75.138 194.394 88.967 185.144 99.523 L 100 200.009 L 14.856 99.523 C 5.606 88.967 0 75.138 0 60 C 0 26.863 26.863 0 60 0 C 75.367 0 89.385 5.777 100 15.278 C 110.615 5.777 124.633 0 140 0 C 173.137 0 200 26.863 200 60 Z"/>
    </svg>

    But if you are stuck with HTML from somewhere else and therefore want to do it all in CSS, you could achieve it using two pseudo-elements and animating the opacity of one of them.

    .heart {
      width: 200px;
      aspect-ratio: 1;
      position: relative;
    }
    .heart::before, .heart::after {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: -1;
    }
    .heart::before {
      background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M 200 60 C 200 75.138 194.394 88.967 185.144 99.523 L 100 200.009 L 14.856 99.523 C 5.606 88.967 0 75.138 0 60 C 0 26.863 26.863 0 60 0 C 75.367 0 89.385 5.777 100 15.278 C 110.615 5.777 124.633 0 140 0 C 173.137 0 200 26.863 200 60 Z' style='fill: red;'/%3E%3C/svg%3E");
    }
    .heart::after {
      background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M 200 60 C 200 75.138 194.394 88.967 185.144 99.523 L 100 200.009 L 14.856 99.523 C 5.606 88.967 0 75.138 0 60 C 0 26.863 26.863 0 60 0 C 75.367 0 89.385 5.777 100 15.278 C 110.615 5.777 124.633 0 140 0 C 173.137 0 200 26.863 200 60 Z' style='fill: blue;'/%3E%3C/svg%3E");
      opacity: 0;
      transition: 1.5s;
    }
    .heart:hover::after {
      opacity: 1;
    }
    <div class="heart">
        <button id="widget-toggle" class="widget-toggle-open drawer-toggle widget-toggle-style-default" data-toggle-target="#widget-drawer" data-toggle-body-class="showing-widget-drawer" aria-expanded="false" data-set-focus=".widget-toggle-close">
            <span class="widget-toggle-label">MENU</span>
            <span class="widget-toggle-icon">
            </span>
        </button>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search