Search code examples
cssshapescss-shapes

CSS advanced shape (heart cut out of background)


Basically I want to create a shape in CSS only (so no images) that is the opposite of a heart shape. I don't know how to explain it properly so here is an image:

enter image description here

The blue is the background, as you can see, but the shape that I want to create is not a heart, it is the shape of the black rectangle.

If I would have the following shape (THE GRAY NOT THE BLACK)

enter image description here

I could duplicate it and then rotate it, that would give me the shape I am looking for.


Solution

  • Heart shape cut out using box-shadow

    Let's create this — the blue is the background color of <body>

    Screenshot

    The pieces

    Feel free to skip directly to the complete demo at the bottom of this answer :)

    1 - The rounded corners

    The rounded top left and top right corners are created with box-shadow on the two pseudo elements with border-radius: 50%.heart:before and .heart:after — They form two crescent shapes that look like this:

    Crescent Shapes

    2 - The angle

    The angled shape is created by the box-shadow on .heart. Combined with the two circles, it looks like this:

    Angled Shape

    3 - The filler

    We now need to fill in the gaps. This is done by the pseudo elements of the .box-shape container — .shape-box:before and .shape-box:after. The excess is cut-off neatly with overflow: hidden on the .shape-box. Combined with our pieces above, they look like this:

    The filler

    The Complete Example

    Combine it all together and we get this nicely cut out heart shape. It is all contained in .shape-box.

    body {
      background: #00A2F6;
    }
    .shape-box {
      height: 504px;
      width: 504px;
      position: relative;
      margin: 100px;
      overflow: hidden;
    }
    .shape-box:before,
    .shape-box:after {
      content: '';
      display: block;
      height: 100px;
      width: 120px;
      background: #2B2B2B;
      transform: rotate(45deg);
      left: 190px;
      position: absolute;
      top: 40px;
    }
    .shape-box:after {
      width: 760px;
      height: 750px;
      box-shadow: inset 0 0 0 220px #2B2B2B;
      top: -150px;
      left: -130px;
      background: none;
    }
    .heart {
      transform: rotate(45deg);
      height: 357px;
      width: 356px;
      box-shadow: inset 0 0 0 50px #2B2B2B;
      position: absolute;
      left: 74px;
      top: 34px;
    }
    .heart:before,
    .heart:after {
      content: '';
      display: block;
      width: 151px;
      height: 151px;
      border-radius: 50%;
      box-shadow: -40px -15px 0 20px #2B2B2B;
      position: absolute;
      left: 50px;
      top: 157px;
    }
    .heart:after {
      box-shadow: -15px -40px 0 21px #2B2B2B;
      left: 156px;
      top: 51px;
    }
    <div class="shape-box">
      <div class="heart"></div>
    </div>