I'm trying to prototype a simple "like" button using FontAwesome 5. Clicking it should toggle between a filled red heart icon and an unfilled black border heart icon. The thing is that I want the black border to stay around the heart when it fills. The JS is easy enough, but to create the border, I'm stacking a Regular styled FontAwesome heart on top of a Solid one, yet they're not lining up correctly. I get the red inner heart overflowing the border and spilling out the sides of the outline.
[...document.querySelectorAll('.like')].forEach(heart => {
heart.addEventListener('click', () => {
heart.classList.toggle('liked');
let fill = heart.querySelector('.fill');
if (heart.classList.contains('liked')) {
fill.style.opacity = '100%';
} else {
fill.style.opacity = '0%';
}
});
});
.like {
display: inline-block;
cursor: pointer;
user-select: none;
}
.like > .fill {
color: red;
opacity: 0%;
transition: opacity 0.25s;
}
<script src="https://use.fontawesome.com/releases/v5.0.0/js/all.js"></script>
<div class="like fa-stack">
<i class="fas fa-heart fa-stack-1x fill"></i>
<i class="far fa-heart fa-stack-1x border"></i>
</div>
Since FA5 replaces the icons with SVG, things like border and text-shadow don't work. I even tried things like targeting the path element inside and setting its stroke width and color, but I can't fade out the middle like that, and using it with this stack still has misalignment problems.
How do I make a simple bordered heart with FA5 whose solid interior can fade in and out on click?
Instead of stacking, set a stroke on the SVG itself, and toggle the fill color instead of opacity.
[...document.querySelectorAll('.like')].forEach(heart => {
heart.addEventListener('click', () => {
heart.classList.toggle('liked');
});
});
.like {
display: inline-block;
cursor: pointer;
user-select: none;
}
.like > .fill {
color: transparent;
transition: color 0.25s;
stroke: black;
/* The stroke width is huge because the svg itself is ~512x512, which is then scaled down */
stroke-width: 50px;
}
.like.liked > .fill {
color: red;
}
<script src="https://use.fontawesome.com/releases/v5.0.0/js/all.js"></script>
<div class="like fa-stack">
<i class="fas fa-heart fa-stack-1x fill"></i>
</div>