How to create a heart shape using CSS?
A new idea with less of code:
.heart {
display:inline-block;
width: 200px;
aspect-ratio: 1;
border-image: radial-gradient(red 69%,#0000 70%) 84.5% fill/100%;
clip-path: polygon(-41% 0,50% 91%, 141% 0);
}
<div class="heart"></div>
<div class="heart" style="width:100px"></div>
<div class="heart" style="width:50px"></div>
Using mask, we can apply it to an image:
img {
width: 200px;
aspect-ratio: 1;
object-fit: cover;
--_m: radial-gradient(#000 69%,#0000 70%) 84.5% fill/100%;
-webkit-mask-box-image: var(--_m);
mask-border: var(--_m);
clip-path: polygon(-41% 0,50% 91%, 141% 0);
}
/* fallback until better support for mask-border */
@supports not (-webkit-mask-box-image: var(--_m)) {
img {
--_m:
radial-gradient(circle at 60% 63%,#000 64%,#0000 65%) top left /50% 50% no-repeat,
radial-gradient(circle at 40% 63%,#000 64%,#0000 65%) top right/50% 50% no-repeat,
linear-gradient(#000 0 0) bottom/100% 50% no-repeat;
-webkit-mask: var(--_m);
mask: var(--_m);
}
}
body {
margin: 0;
min-height: 100vh;
display: grid;
grid-auto-flow: column;
place-content: center;
gap: 30px;
background: pink;
filter: drop-shadow(0 0 10px #ff3e60)
}
<img src="https://picsum.photos/id/1027/300/300" alt="the face of a beautiful girl">
<img src="https://picsum.photos/id/64/300/300" alt="another beautiful girl">
Here is another idea using one element and relying on multiple backgrounds to achieve the heart shape. You can also easily adjust the size by only changing the width:
.heart {
width:200px;
background:
radial-gradient(circle at 60% 65%, red 64%, transparent 65%) top left,
radial-gradient(circle at 40% 65%, red 64%, transparent 65%) top right,
linear-gradient(to bottom left, red 43%,transparent 43%) bottom left ,
linear-gradient(to bottom right,red 43%,transparent 43%) bottom right;
background-size:50% 50%;
background-repeat:no-repeat;
display:inline-block;
}
.heart::before {
content:"";
display:block;
padding-top:100%;
}
<div class="heart">
</div>
<div class="heart" style="width:100px">
</div>
<div class="heart" style="width:60px">
</div>
<div class="heart" style="width:30px">
</div>
You can also use mask
and you can have any kind of coloration:
.heart {
width:200px;
display:inline-block;
-webkit-mask:
radial-gradient(circle at 60% 65%, red 64%, transparent 65%) top left,
radial-gradient(circle at 40% 65%, red 64%, transparent 65%) top right,
linear-gradient(to bottom left, red 43%,transparent 43%) bottom left ,
linear-gradient(to bottom right,red 43%,transparent 43%) bottom right;
-webkit-mask-size:50% 50%;
-webkit-mask-repeat:no-repeat;
mask:
radial-gradient(circle at 60% 65%, red 64%, transparent 65%) top left,
radial-gradient(circle at 40% 65%, red 64%, transparent 65%) top right,
linear-gradient(to bottom left, red 43%,transparent 43%) bottom left ,
linear-gradient(to bottom right,red 43%,transparent 43%) bottom right;
mask-size:50% 50%;
mask-repeat:no-repeat;
background:linear-gradient(red,blue);
}
.heart::before {
content:"";
display:block;
padding-top:100%;
}
<div class="heart">
</div>
<div class="heart" style="width:100px;background:linear-gradient(45deg,grey 50%,purple 0)">
</div>
<div class="heart" style="width:60px;background:radial-gradient(red,yellow,red)">
</div>
<div class="heart" style="width:30px;background:blue">
</div>
How does it works?
The whole shape is combined using 4 gradients: 2 gradients to create the top part and 2 for the bottom parts. each gradient is taking 1/4 of size and placed at a corner.
Use a different color for each gradient to clearly identify the puzzle
.heart {
width:200px;
background:
radial-gradient(circle at 60% 65%, red 64%, grey 65%) top left,
radial-gradient(circle at 40% 65%, blue 64%, black 65%) top right,
linear-gradient(to bottom left, green 43%,black 43%) bottom left ,
linear-gradient(to bottom right,purple 43%,grey 43%) bottom right;
background-size:50% 50%;
background-repeat:no-repeat;
display:inline-block;
border:5px solid yellow;
}
.heart::before {
content:"";
display:block;
padding-top:100%;
}
<div class="heart">
</div>
CSS3 Mon Amour - A 4 Step Love Afair
There are a few steps for creating heart shape using CSS3:
Create a block-level element such as a
<div>
in your DOM and assign it withid="heart"
and apply CSS:#heart { position:relative; width:100px; height:90px; margin-top:10px; /* leave some space above */ }
Now using pseudo-element
#heart:before
we create a red box with one rounded edge like this:#heart:before { position: absolute; content: ""; left: 50px; top: 0; width: 52px; height: 80px; background: red; /* assign a nice red color */ border-radius: 50px 50px 0 0; /* make the top edge round */ }
Your heart should now look like this:
Let us assign a little rotation to that by adding:
#heart:before { -webkit-transform: rotate(-45deg); /* 45 degrees rotation counter clockwise */ -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); -webkit-transform-origin: 0 100%; /* Rotate it around the bottom-left corner */ -moz-transform-origin: 0 100%; -ms-transform-origin: 0 100%; -o-transform-origin: 0 100%; transform-origin: 0 100%; }
And we now get:
Already starting to come together :).
Now for the right part we basically need the same shape only rotated 45 degrees clockwise instead of counter clockwise. To avoid code duplication we attach the css of
#heart:before
also to#heart:after
, and then apply the change in position and in angle:#heart:after { left: 0; /* placing the right part properly */ -webkit-transform: rotate(45deg); /* rotating 45 degrees clockwise */ -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); -webkit-transform-origin: 100% 100%; /* rotation is around bottom-right corner this time */ -moz-transform-origin: 100% 100%; -ms-transform-origin: 100% 100%; -o-transform-origin: 100% 100%; transform-origin :100% 100%; }
And voilà! a complete heart shaped
<div>
:
Snippet without any prefix:
#heart {
position: relative;
width: 100px;
height: 90px;
margin-top: 10px;
}
#heart::before, #heart::after {
content: "";
position: absolute;
top: 0;
width: 52px;
height: 80px;
border-radius: 50px 50px 0 0;
background: red;
}
#heart::before {
left: 50px;
transform: rotate(-45deg);
transform-origin: 0 100%;
}
#heart::after {
left: 0;
transform: rotate(45deg);
transform-origin: 100% 100%;
}
<div id="heart"></div>