CSS clip-path doesn't stretch with path()

Viewed 370

I'm trying to use the clip-path property with an path value. But for some reason, the clipping isn't scaling with the element, like it does using an HTML svg as url().

Is there a way to make path() behave like url() does (stretching the clipping)

NOTE: i also tried to generate an url-encoded svg and used clip-path: url('data:image...') but it doesn't seem to work

.heart {
  background: red;
  color: white;
  display: grid;
  place-content: center;
  width: 180px;
  height: 100px;
  margin: 30px auto;
}

.svg {
  clip-path: url(#myPath)
}

.path {
  clip-path: path('M15,45 A30,30,0,0,1,75,45 A30,30,0,0,1,135,45 Q135,90,75,130 Q15,90,15,45 Z')
}
<div class="heart svg">With SVG</div>
<div class="heart path">With PATH</div>

<svg>
  <clipPath id="myPath" clipPathUnits="objectBoundingBox">
    <path d="M0.5,1
      C 0.5,1,0,0.7,0,0.3
      A 0.25,0.25,1,1,1,0.5,0.3
      A 0.25,0.25,1,1,1,1,0.3
      C 1,0.7,0.5,1,0.5,1 Z" />
  </clipPath>
</svg>

1 Answers

you can do that by scaling the content down to the size of the clip path, then clipping it, then scaling it back up

.heart {
    background: red;
    color: white;
    display: grid;
    place-content: center;
    width: calc(var(--desired-width) * 1px);
    height: calc(var(--desired-height) * 1px);
}
.heart-clip {
    clip-path: path("M0.5,1 C 0.5,1,0,0.7,0,0.3 A 0.25,0.25,1,1,1,0.5,0.3 A 0.25,0.25,1,1,1,1,0.3 C 1,0.7,0.5,1,0.5,1 Z");
    width: 1px;
    height: 1px;
}
.heart-scale-vars {
    --path-width: 1;
    --path-height: 1;
    --desired-width: 180;
    --desired-height: 100;
}
.scale-pre {
    transform: scale(
        calc(var(--path-width) / var(--desired-width)),
        calc(var(--path-height) / var(--desired-height))
    );
    transform-origin: top left;
}
.scale-post {
    transform-origin: top left;
    transform: scale(
        calc(var(--desired-width) / var(--path-width)),
        calc(var(--desired-height) / var(--path-height))
    );
}
.scale-postpost {
    width: calc(var(--desired-width) * 1px);
    height: calc(var(--desired-height) * 1px);
}
<div class="heart-scale-vars scale-postpost"><div class="scale-post heart-clip"><div class="scale-pre heart">With PATH</div></div></div>

or by using a url encoded svg as a mask

.heart {
    background: red;
    color: white;
    display: grid;
    place-content: center;
    width: 180px;
    height: 100px;
}
.heart-mask {
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1' preserveAspectRatio='none'%3E%3Cpath d='M.5 1C.5 1 0 .7 0 .3A .25.25 1 1 1 .5.3A.25 .25 1 1 1 1 .3C1 .7 .5 1 .5 1Z'/%3E%3C/svg%3E");
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1' preserveAspectRatio='none'%3E%3Cpath d='M.5 1C.5 1 0 .7 0 .3A .25.25 1 1 1 .5.3A.25 .25 1 1 1 1 .3C1 .7 .5 1 .5 1Z'/%3E%3C/svg%3E");
}
<div class="heart heart-mask">With MASK</div>

Related