How could I create a border somewhere among the lines of this?
I've tried using linear gradients for backgrounds (found here) but can't seem to get it to draw the shape I'm looking for.
You could use before and after pseudo elements on the main element to create a background. One would be a red rectangle, and in front of it a white rectangle with CSS clip-path used to get the shape.
Here's an example. Obviously change the % values to be what you want (could be px if that is required).
body {
background: black;
width: 100vw;
height: 100vh;
}
div {
width: 30vmin;
height: 50vmin;
display: inline-block;
position: relative;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
}
div::before,
div::after {
position: absolute;
content: '';
left: 0;
right: 0;
width: 100%;
height: 100%;
z-index: -1;
}
div::before {
background: red;
}
div::after {
background: white;
clip-path: polygon(5% 5%, 50% 0, 95% 5%, 100% 30%, 100% 70%, 95% 95%, 70% 100%, 30% 100%, 5% 95%, 0 70%, 0 30%);
}
<div></div>
If you are looking for a gradient, here is an idea using conic-gradient. All you have to do is adjust a few variables to control the shape
.box {
--size: 15px;
--angle: 250deg;
--g: red var(--angle), lightblue 0; /* the colors here */
background:
conic-gradient(from calc(var(--angle)/-2 - 45deg)
at top var(--size) left var(--size),var(--g)) top left,
conic-gradient(from calc(var(--angle)/-2 + 45deg)
at top var(--size) right var(--size),var(--g)) top right,
conic-gradient(from calc(var(--angle)/-2 - 135deg)
at bottom var(--size) left var(--size),var(--g)) bottom left,
conic-gradient(from calc(var(--angle)/-2 + 135deg)
at bottom var(--size) right var(--size),var(--g)) bottom right;
background-size: 51% 51%;
background-repeat: no-repeat;
width: 300px;
height: 300px;
display: inline-block;
}
<div class="box"></div>
<div class="box" style="--size:10px; --angle: 255deg"></div>
Related
I want to create a blur effect like the blue and green in the image
.right-wrapper {
width: 50%;
display: flex;
justify-content: flex-start;
align-items: center;
position: relative;
}
.right-wrapper .backdrop-filter-top {
width: 70%;
height: 70%;
position: absolute;
left: 5%;
top: 5%;
background-color: #43d9ad;
clip-path: polygon(25% 0%, 75% 35%, 100% 100%, 75% 100%, 5% 90%, 0 20%);
opacity: 0.4;
filter: blur(87px);
}
.right-wrapper .backdrop-filter-bottom {
width: 70%;
height: 70%;
position: absolute;
right: 5%;
bottom: 5%;
background-color: #4d5bce;
clip-path: polygon(0 0, 80% 0, 100% 45%, 80% 100%, 10% 70%, 0 25%);
opacity: 0.4;
filter: blur(87px);
}
<div class="right-wrapper">
<div class="backdrop-filter-top" />
<div class="backdrop-filter-bottom" />
</div>
Dont want to add the radial gradients or even okay with radial gradients, but this kind of blur is not coming properly
It doesn't work, because i was using the clip-path, not sure why, so when i remove clip-path, it worked
I have used clip-path in the div, so the filter blur option doesn't work, after I remove the clip-path, the filter blur option works perfectly,
I was wondering if it was possible to split a screen into 2 parts diagonally as shown on the picture. Once I'd hover over Picture A, the diagonal line would shift a bit to the right, revealing more of picture A while hiding a bit of picture B (I'm thinking transition?), and when I'd hover over picture B the opposite would happen.
Thanks in advance,
Martin
The diagonal image transition effect is unique request. I tried my best, Can you please check revealing effect.
section {
border: 1px solid black;
display: flex;
width: 400px;
box-sizing: border-box;
}
.diagonalHover {
position: absolute;
width: 66%;
height: 200px;
transition: all 0.3s ease-out;
}
.diagonalHover.first,
.diagonalHover.second {
background-image: url(https://cdn.pixabay.com/photo/2016/07/20/22/33/vajdahunyadvar-1531470_960_720.jpg);
background-repeat: no-repeat;
background-size: cover;
}
.diagonalHover.second {
background-image: url(https://cdn.pixabay.com/photo/2020/02/05/22/17/vendetta-4822543__340.jpg);
}
.diagonalHover.first:hover {
width: 75%;
z-index: 1;
}
.diagonalHover.second:hover {
width: 75%;
z-index: 1;
}
.diagonalHover.first:hover + .second {
}
.diagonalHover.first {
left: 0;
top: 0;
-webkit-clip-path: polygon(0 0, 100% 0%, 50% 100%, 0% 100%);
clip-path: polygon(0 0, 100% 0%, 50% 100%, 0% 100%);
}
.diagonalHover.second {
right: 0;
top: 0;
-webkit-clip-path: polygon(50% 0, 100% 0%, 100% 100%, 0% 100%);
clip-path: polygon(50% 0, 100% 0%, 100% 100%, 0% 100%);
}
<section>
<div class="diagonalHover first">
</div>
<div class="diagonalHover second">
</div>
</section>
I am creating trapezoid using following CSS:
.trapezoid {
border-bottom: 100px solid red;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
height: 0;
width: 100px;
background: linear-gradient(red, yellow);
}
<div class='trapezoid'></div>
The linear-gradient attribute is not working. I want the trapezoid as shadow i.e its color should eventually fade away. Can anyone please help me on this?
Or use a transform on a suitably sized element (or pseudo-element).
.trapezoid {
width: 100px;
height: 100px;
margin: auto;
transform: perspective(100px) rotateX(40deg);
background: linear-gradient(red, yellow);
}
<div class='trapezoid'></div>
You cannot apply gradient in this way as you are using border and your element has a height of 0 so background won't be visible.
Instead you can try to use multiple gradient to create the shape:
.trapezoid {
height: 100px;
width: 200px;
background:
linear-gradient(to bottom left,white 50%,transparent 52%) 100% 0/40px 100% no-repeat,
linear-gradient(to bottom right,white 50%,transparent 52%) 0 0/40px 100% no-repeat,
linear-gradient(red, yellow);
}
<div class='trapezoid'></div>
Or use clip-path:
.trapezoid {
height: 100px;
width: 200px;
background: linear-gradient(red, yellow);
-webkit-clip-path: polygon(20% 0%, 80% 0%, 100% 100%, 0% 100%);
clip-path: polygon(20% 0%, 80% 0%, 100% 100%, 0% 100%);
}
<div class='trapezoid'></div>
Another method with skew and pseudo-element:
.trapezoid {
height: 100px;
width: 200px;
position: relative;
}
.trapezoid:before,
.trapezoid:after{
content: "";
position: absolute;
top: 0;
bottom: 0;
right: 0;
width: 60%;
background: linear-gradient(red, yellow);
transform:skew(20deg);
transform-origin:bottom right;
}
.trapezoid:after {
left: 0;
transform:skew(-20deg);
transform-origin:bottom left;
}
<div class='trapezoid'></div>
I would like to make a transparent arrow over an image. This triangle should be indented in a semi transparent block and show the background image.
Desired output:
.barShow {
background-color: #000;
opacity: 0.5;
}
.barShow:before {
top: 0%;
left: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border-top-color: #999;
border-width: 20px;
margin-left: -20px;
}
<div class="barShow"></div>
The transparent CSS Arrow should be transparent without color.
There are several approaches to make a transparent arrow over an image with CSS. The two I will describe involve pseudo elements to minimize markup and have the same output. You can also see an SVG approach at the end of this answer :
The transparent effect on the black part arround the arrow is made with rgba() colors that allow transparency. But you can use opacity on the pseudo elements if you prefer.
1. SkewX()
You can use the CSS3 skewX() property on two pseudo elements to make the transparent arrow. The main asset of this approach is that the transparent arrow can be responsive but it also allows you to put a border on the black shape and around the traingle.
The responsiveness of the shape is made with the padding-bottom property to maintain it's aspect ratio (this technique is described here).
DEMO
.wrap {
position: relative;
overflow: hidden;
width: 70%;
margin: 0 auto;
}
.wrap img {
width: 100%;
height: auto;
display: block;
}
.arrow {
position: absolute;
bottom: 0;
width: 100%;
padding-bottom: 3%;
background-color: rgba(0, 0, 0, 0.8);
}
.arrow:before,
.arrow:after {
content: '';
position: absolute;
bottom: 100%;
width: 50%;
padding-bottom: inherit;
background-color: inherit;
}
.arrow:before {
right: 50%;
-ms-transform-origin: 100% 100%;
-webkit-transform-origin: 100% 100%;
transform-origin: 100% 100%;
-ms-transform: skewX(45deg);
-webkit-transform: skewX(45deg);
transform: skewX(45deg);
}
.arrow:after {
left: 50%;
-ms-transform-origin: 0 100%;
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
-ms-transform: skewX(-45deg);
-webkit-transform: skewX(-45deg);
transform: skewX(-45deg);
}
<div class="wrap">
<img src="https://farm8.staticflickr.com/7187/6895047173_d4b1a0d798.jpg" />
<div class="arrow"></div>
</div>
Browser support for the transform : skew() property is IE9+ (see canIuse).
2. Border
The asset of this technique is browser support so if you need IE8 support this one is for you. The drawback is that the shape can't be responsive because border can't use % widths.
DEMO
.wrap {
position: relative;
overflow: hidden;
width: 70%;
margin: 0 auto;
}
.wrap img {
width: 100%;
height: auto;
display: block;
}
.arrow {
position: absolute;
bottom: 0;
width: 100%;
height: 20px;
background-color: rgba(0, 0, 0, 0.8);
}
.arrow:before,
.arrow:after {
content: '';
position: absolute;
bottom: 100%;
width: 50%;
box-sizing: border-box;
}
.arrow:before {
right: 50%;
border-bottom: 20px solid rgba(0, 0, 0, 0.8);
border-right: 20px solid transparent;
}
.arrow:after {
left: 50%;
border-bottom: 20px solid rgba(0, 0, 0, 0.8);
border-left: 20px solid transparent;
}
<div class="wrap">
<img src="https://farm8.staticflickr.com/7187/6895047173_d4b1a0d798.jpg" />
<div class="arrow"></div>
</div>
3. Play with it!
Example : if you can change the black transparent color to the same as your background color (white here), you can make an transparent triangle/arrow with the same background image as the block :
DEMO
.wrap {
position: relative;
overflow: hidden;
width: 50%;
margin: 0 auto;
background-color:#fff;
}
.wrap img {
width: 100%;
height: auto;
display: block;
}
.wrap:before, .wrap:after {
content:'';
position: absolute;
bottom: 0;
width: 50%;
background-color: inherit;
padding-bottom:3%;
}
.wrap:before {
right: 50%;
-ms-transform-origin: 100% 100%;
-webkit-transform-origin: 100% 100%;
transform-origin: 100% 100%;
-ms-transform: skewX(45deg);
-webkit-transform: skewX(45deg);
transform: skewX(45deg);
}
.wrap:after {
left: 50%;
-ms-transform-origin: 0 100%;
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
-ms-transform: skewX(-45deg);
-webkit-transform: skewX(-45deg);
transform: skewX(-45deg);
}
<div class="wrap">
<img src="https://farm8.staticflickr.com/7187/6895047173_d4b1a0d798.jpg" />
</div>
4. Tooltip with a triangle over an image.
If you need to use this shape over another image, background gradient or whatever non plain color, you will need to use a different approach in order to see the image all around the shape like this:
The point is to use the same image twice. Once in the div element and once in the triangle and to postion them exactly at the same place with absolute positioning. The arrow is made with transform:rotate();.
DEMO
body{
padding-top:100px;
background:url('https://farm8.staticflickr.com/7187/6895047173_d4b1a0d798.jpg')no-repeat center center;
background-size:cover;
}
.wrap, .img {
display:inline-block;
position:relative;
}
.tr{
position:absolute;
overflow:hidden;
top:-25px; left:100px;
width:50px; height:50px;
-webkit-transform:rotate(45deg);
-ms-transform:rotate(45deg);
transform:rotate(45deg);
}
.tr img{
position:absolute;
top:-15px; left:-100px;
-webkit-transform-origin: 125px 40px;
-ms-transform-origin: 125px 40px;
transform-origin: 125px 40px;
-webkit-transform:rotate(-45deg);
-ms-transform:rotate(-45deg);
transform:rotate(-45deg);
}
.img{
overflow:hidden;
width: 600px; height:100px;
}
.img img{
position:absolute;
top:-40px;
}
<div class="wrap">
<div class="img">
<img src="https://farm7.staticflickr.com/6092/6227418584_d5883b0948.jpg" alt="" />
</div>
<div class="tr">
<img src="https://farm7.staticflickr.com/6092/6227418584_d5883b0948.jpg" alt="" />
</div>
</div>
DEMO with box shadows.
5. SVG and cliPath
DEMO using an svg tag and clipPath.
This might be a semanticaly better approach if you are making graphics.
Simple Approach
Use pseudo element with box-shadow and transform: rotate();
Add overflow: hidden; to main div.
Snippet :
body {
margin: 0;
padding: 0;
background: url(http://i.imgur.com/EinPKO3.jpg);
background-size: cover;
}
div {
height: 100px;
width: 100%;
position: absolute;
bottom: 0;
overflow: hidden;
}
div:before {
position: absolute;
top: -50px;
left: calc(50% - 35px);
content: "";
height: 50px;
width: 50px;
background: transparent;
-webkit-transform-origin: 0% 100%;
-moz-transform-origin: 0% 100%;
-ms-transform-origin: 0% 100%;
transform-origin: 0% 100%;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
box-shadow: 0 0 0 5000px rgba(0, 0, 0, 0.6);
}
<div></div>
Here is a solution using CSS clip-path that doesn't overflow the wrapper.
.wrap {
position:relative;
width:480px;
height:270px;
background-image:url(http://placehold.it/480x270);
}
.wrap:after {
content:"";
display:block;
position:absolute;
left:0;
right:0;
bottom:0;
height:50px;
background-color:rgba(0, 0, 0, 0.7);
-webkit-clip-path:polygon(0 0, calc(50% - 30px) 0, 50% 50%, calc(50% + 30px) 0, 100% 0, 100% 100%, 0 100%);
-moz-clip-path:polygon(0 0, calc(50% - 30px) 0, 50% 50%, calc(50% + 30px) 0, 100% 0, 100% 100%, 0 100%);
clip-path:polygon(0 0, calc(50% - 30px) 0, 50% 50%, calc(50% + 30px) 0, 100% 0, 100% 100%, 0 100%);
}
<div class="wrap"></div>
We can make this with linear-gradients. No pseudo-element. I used some CSS variables to control everything easily. This is more flexible.
.a {
/* you can change these variables */
--arrow-width: 20px;
--rgba: rgba(0, 0, 0, 0.5);
--bottom-height: 50px;
width: 100%;
height: 300px;
background: linear-gradient(to right, var(--rgba) 0 calc(50% - var(--arrow-width)), transparent calc(50% - var(--arrow-width)) calc(50% + var(--arrow-width)), var(--rgba) 0 calc(50% + var(--arrow-width) * 2)) 0 calc(100% - var(--bottom-height)) / 100% var(--arrow-width),
linear-gradient(to bottom right, transparent 0 50%, var(--rgba) 50.1% 100%) calc(50% + (var(--arrow-width) / 2)) calc(100% - var(--bottom-height)) / var(--arrow-width) var(--arrow-width),
linear-gradient(to bottom left, transparent 0 50%, var(--rgba) 50.1% 100%) calc(50% - (var(--arrow-width) / 2)) calc(100% - var(--bottom-height)) / var(--arrow-width) var(--arrow-width),
linear-gradient(var(--rgba), var(--rgba)) 0 100%/ 100% calc(var(--bottom-height)),
url(https://picsum.photos/id/600/360) 50% 50% / cover;
background-repeat: no-repeat;
}
<div class="a"></div>
By changing the variables:
.a {
/* you can change these variables */
--arrow-width: 50px;
--rgba: rgba(0, 0, 0, 0.5);
--bottom-height: 70px;
width: 100%;
height: 300px;
background: linear-gradient(to right, var(--rgba) 0 calc(50% - var(--arrow-width)), transparent calc(50% - var(--arrow-width)) calc(50% + var(--arrow-width)), var(--rgba) 0 calc(50% + var(--arrow-width) * 2)) 0 calc(100% - var(--bottom-height)) / 100% var(--arrow-width),
linear-gradient(to bottom right, transparent 0 50%, var(--rgba) 50.1% 100%) calc(50% + (var(--arrow-width) / 2)) calc(100% - var(--bottom-height)) / var(--arrow-width) var(--arrow-width),
linear-gradient(to bottom left, transparent 0 50%, var(--rgba) 50.1% 100%) calc(50% - (var(--arrow-width) / 2)) calc(100% - var(--bottom-height)) / var(--arrow-width) var(--arrow-width),
linear-gradient(var(--rgba), var(--rgba)) 0 100%/ 100% calc(var(--bottom-height)),
url(https://picsum.photos/id/600/360) 50% 50% / cover;
background-repeat: no-repeat;
}
<div class="a"></div>
To better understand the trick here is the gradients with different colors:
.a {
/* you can change these variables */
--arrow-width: 50px;
--bottom-height: 70px;
width: 100%;
height: 300px;
background: linear-gradient(to right, red 0 calc(50% - var(--arrow-width)), transparent calc(50% - var(--arrow-width)) calc(50% + var(--arrow-width)), blue 0 calc(50% + var(--arrow-width) * 2)) 0 calc(100% - var(--bottom-height)) / 100% var(--arrow-width),
linear-gradient(to bottom right, transparent 0 50%, yellow 50.1% 100%) calc(50% + (var(--arrow-width) / 2)) calc(100% - var(--bottom-height)) / var(--arrow-width) var(--arrow-width),
linear-gradient(to bottom left, transparent 0 50%, green 50.1% 100%) calc(50% - (var(--arrow-width) / 2)) calc(100% - var(--bottom-height)) / var(--arrow-width) var(--arrow-width),
linear-gradient(purple, purple) 0 100%/ 100% calc(var(--bottom-height)),
url(https://picsum.photos/id/600/360) 50% 50% / cover;
background-repeat: no-repeat;
}
<div class="a"></div>
Masking:
.a {
/* you can change this variable */
--arrow-width: 30px;
width: 100%;
height: 300px;
--mask: linear-gradient(#000, #000) 0 0/100% calc(100% - var(--arrow-width)) no-repeat,
linear-gradient(to top right, transparent 0 50%, #000 50.1% 100%) calc(50% - var(--arrow-width) / 2) 100% / var(--arrow-width) var(--arrow-width) no-repeat,
linear-gradient(to top left, transparent 0 50%, #000 50.1% 100%) calc(50% + var(--arrow-width) / 2) 100% / var(--arrow-width) var(--arrow-width) no-repeat;
-webkit-mask: var(--mask);
mask: var(--mask);
background: url(https://picsum.photos/id/600/360) 50% 50% / cover;
}
<div class="a"></div>
I've found the following CSS in one of the answers here on SO and I was wondering why does it create the desired heart shape:
#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%;
}
<div id="heart"></div>
Please can someone explain?
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 with id="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>
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>