DEV Community

Discussion on: Make a beating heart using CSS: beginner-friendly tutorial

Collapse
 
rolandixor profile image
Roland Taylor

Love it!

Tempted to try it and add sparkles (because why not) lol

Collapse
 
larainnepasion profile image
La Rainne Pasion

Oh my gosh, please add sparkles and let me know how it goes!

Collapse
 
rolandixor profile image
Roland Taylor • Edited

FINALLY got around to this lol

<body>
    <div class="heart">
      <div class="sparkle">
      </div>
      <div class="sparkle">
      </div>
      <div class="sparkle">
      </div>
      <div class="sparkle">
      </div>
      <div class="sparkle">
      </div>
      <div class="sparkle">
      </div>
    </div>
  </body>
Enter fullscreen mode Exit fullscreen mode

body {
  align-items: center;
  display: flex;
  justify-content: center;
  height: 100vh;
}

@keyframes heartbeat {
  0% {
    opacity: 1;
    transform: rotate(-45deg) scale(1);
  }
  50% {
    opacity: .735;
    transform: rotate(-45deg) scale(.765);
  }
  100% {
    opacity: 1;
    transform: rotate(-45deg) scale(1);
  }
}

.heart {
  animation: heartbeat 1.8235s infinite;
  aspect-ratio: 1/1;
  height: 25vh;
  background-color: red;
  position: relative;
  transform: rotate(-45deg) scale(5);
}

.heart::after,
.heart::before {
  aspect-ratio: 1/1;
  background-color: red;
  border-radius: 50%;
  content: '';
  height: 25vh;
  position: absolute;
}

.heart::after {
  left: 12.5vh;
}

.heart::before {
  top: -12.5vh;
}

@keyframes sparkle {
  0% {
    border: 3px solid red;
    transform: scale(0);
  }
  50% {
    border: 1px solid white;
  }
  100% {
    border: 1px solid transparent;
    transform: scale(1) translateX(7.5vh) translateY(-7.5vh);
  }
}

.sparkle {
  animation: sparkle 2.75s infinite;
  aspect-ratio: 1/1;
  border-radius: 50%;
  position: absolute;
  width: 3.35vh;
  z-index: 1;
}

@keyframes sparklebars {
  0% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 1;
    transform: scale(0);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes sparklebars2 {
  0% {
    opacity: 1;
    transform: scale(1) rotate(90deg);
  }
  50% {
    opacity: 0;
    transform: scale(0) rotate(90deg);
  }
  100% {
    opacity: 1;
    transform: scale(1) rotate(90deg);
  }
}

.sparkle::after,
.sparkle::before {
  animation: sparklebars .5s infinite;
  background-color: white;
  content: '';
  height: 5px;
  inset: 50% -50% 0 -50%;
  position: absolute;
}

.sparkle:after {
  animation: sparklebars2 .5s infinite;
  transform: rotate(90deg);
}

.sparkle:nth-child(1) {
  inset: calc(50% - 2.5vh);
}

.sparkle:nth-child(2) {
  inset: calc(50% - 2.5vh) 0 calc(50% - 2.5vh) auto;
}

.sparkle:nth-child(3) {
  inset: 0 calc(50% - 2.5vh) calc(50% - 2.5vh) auto;
}

.sparkle:nth-child(4) {
  inset: 100% 25% auto calc(50% - 2.5vh);
}

.sparkle:nth-child(5) {
  inset: 75% 100% auto auto;
}

.sparkle:nth-child(6) {
  inset: 75% 50% auto auto;
}

Enter fullscreen mode Exit fullscreen mode

The result:

Image description

I didn't bother to add randomness to their positions since that would require JS (unless there's some new CSS features I missed lol). Some day when I'm not busy (or lazy), I might circle back to this and spruce it up some more, just for fun.