Search code examples
htmlcsssvgblurclip-path

Clip Path applied to image doesn't show image


I have a website which needs a few titles with a decent hover effect (Stripped down in this example, but that's why I am doing everything with svgs)

I want the text when hovered to be reduced to its outline and a "frosted glass fill" (filled with translucent white and blurring the image behind) That why my svg has two paths:

  • A regular one for the border and the white (/ translucent white) fill.
  • And the same paths in a clipPath element, such that I have something to clip the copy of the background with.

Why is it that the second image (image one is set as the background of html) is clipped away completely? (it exits, is in the right place, correctly blurred, but the clip-path clips away the entirety of the image, not just the stuff outside of the path)

html {
    background-image: url(https://picsum.photos/id/210/480/270);
}

#navbar {
    list-style: none;
}

#navbar .letter-path {
    fill: white;
    stroke: transparent;
    stroke-width: 0.057;
}

#navbar svg:hover .letter-path {
    fill: rgba(255, 255, 255, 0.15);
    stroke: white;
}

#blurred-clip-background {
    position: absolute;
    top: 0;
    left: 0;
    clip-path: url(#blur-letter-paths);
    filter: blur(10px);
    z-index: -1;
}
<img id="blurred-clip-background" src="https://picsum.photos/id/210/480/270" alt="">
<ul id="navbar" class="relative inline-block">
    <li>
        <svg height="150" viewBox="-1 -1 4.036 4.036">
            <defs>
                <clipPath id="blur-letter-paths">
                    <path class="blur-letter-path letter-path-A"
                          d="m 1.4033687,5e-7 c 0.0882,0 0.1516899,0.042333 0.1834399,0.1269997 l 0.80433,2.3001061 c 0.0388,0.1128887 -0.007,0.1834441 -0.13052,0.1834441 h -0.37748 c -0.0917,0 -0.15169,-0.042333 -0.17991,-0.1305275 L 1.5938686,2.1589958 H 0.81775865 l -0.10936,0.3210271 c -0.0318,0.088194 -0.0917,0.1305275 -0.18345,0.1305275 h -0.381 c -0.12347,0 -0.16933,-0.070555 -0.13052,-0.1834441 l 0.80786,-2.3001061 C 0.85298865,0.0423342 0.91298865,5e-7 1.0011987,5e-7 Z m 0.0423,1.580441 -0.24342,-0.7231929 -0.22225005,0.7231929 z"
                          transform="translate(0, 0)"></path>
                </clipPath>
            </defs>
            <path class="letter-path letter-path-A"
                  d="m 1.4033687,5e-7 c 0.0882,0 0.1516899,0.042333 0.1834399,0.1269997 l 0.80433,2.3001061 c 0.0388,0.1128887 -0.007,0.1834441 -0.13052,0.1834441 h -0.37748 c -0.0917,0 -0.15169,-0.042333 -0.17991,-0.1305275 L 1.5938686,2.1589958 H 0.81775865 l -0.10936,0.3210271 c -0.0318,0.088194 -0.0917,0.1305275 -0.18345,0.1305275 h -0.381 c -0.12347,0 -0.16933,-0.070555 -0.13052,-0.1834441 l 0.80786,-2.3001061 C 0.85298865,0.0423342 0.91298865,5e-7 1.0011987,5e-7 Z m 0.0423,1.580441 -0.24342,-0.7231929 -0.22225005,0.7231929 z"
                  transform="translate(0, 0)"></path>
        </svg>
    </li>
</ul>


Solution

  • There is definitely something about the scale of the letter. I know you defined a very small viewBox matching the size of the letter, but that does not effect the same small letter in the clip path. When you refer to a clip-path you just refer to the element, not the entire SVG. Therefore it is difficult/impossible to reliably align the size of the letter in the SVG and the clipped image outside the SVG. Use the <image> element as an element inside the SVG, and clip that instead -- then the two letters will have the same size and be positioned on top of each other.

    html {
      background-image: url(https://picsum.photos/id/210/480/270);
    }
    
    #navbar {
      list-style: none;
    }
    
    #navbar .letter-path {
      fill: white;
      stroke: transparent;
      stroke-width: 0.057;
    }
    
    #navbar svg:hover .letter-path {
      fill: rgba(255, 255, 255, 0.15);
      stroke: white;
    }
    <ul id="navbar" class="relative inline-block">
      <li>
        <svg height="150" viewBox="-1 -1 199 214">
          <defs>
            <path id="pathA" 
              d="m 1.4033687,5e-7 c 0.0882,0 0.1516899,0.042333 0.1834399,0.1269997 l 0.80433,2.3001061 c 0.0388,0.1128887 -0.007,0.1834441 -0.13052,0.1834441 h -0.37748 c -0.0917,0 -0.15169,-0.042333 -0.17991,-0.1305275 L 1.5938686,2.1589958 H 0.81775865 l -0.10936,0.3210271 c -0.0318,0.088194 -0.0917,0.1305275 -0.18345,0.1305275 h -0.381 c -0.12347,0 -0.16933,-0.070555 -0.13052,-0.1834441 l 0.80786,-2.3001061 C 0.85298865,0.0423342 0.91298865,5e-7 1.0011987,5e-7 Z m 0.0423,1.580441 -0.24342,-0.7231929 -0.22225005,0.7231929 z"
              transform="scale(50)" />
            <clipPath id="blur-letter-paths">
              <use href="#pathA"/>
            </clipPath>
          </defs>
          <image style="filter:blur(10px)" href="https://picsum.photos/id/210/480/270"
            clip-path="url(#blur-letter-paths)"/>
          <use href="#pathA" class="letter-path"/>
        </svg>
      </li>
    </ul>