Question

Fixing Transparent Line Between Div with Clip-Path and Parent Div

A thin, transparent line appears between the triangular div and its parent div when zoomed. I believe this is likely caused by anti-aliasing in the browser. If there is a way to fix this, I would appreciate it. I have also tried using SVG instead of clip-path, but the issue persists.

<script src="https://cdn.tailwindcss.com"></script>

<div class="bg-red-500 h-[30rem] relative">
  <div class="w-1/2 h-10 md:h-20 bg-inherit absolute transform -translate-y-full [clip-path:polygon(0%0%,100%100%,0%100%)]"></div>
  <div class="w-1/2 h-10 md:h-20 bg-inherit absolute transform -translate-y-full right-0 [clip-path:polygon(100%0%,100%100%,0%100%)]"></div>
  <div class="w-1/2 h-10 md:h-20 bg-white absolute bottom-0 [clip-path:polygon(0%0%,100%100%,0%100%)]"></div>
  <div class="w-1/2 h-10 md:h-20 bg-white absolute bottom-0 right-0 [clip-path:polygon(100%0%,100%100%,0%100%)]"></div>
</div>

The line is more visible when viewed directly rather than from image btw enter image description here

 3  81  3
1 Jan 1970

Solution

 2

Reproduce the problem only in Chrome, and I suspect this problem is caused by subpixel rendering inconsistencies.

Seems like the issue only happens when the div's position is moved/pushed to a y-position with subpixels (such as a previous sibling with height:80vh and a screen height that can't be divided by 1.25). This is also the reason why zooming causes this problem to appear/disappear.

For example, as shown below in Chrome the follow snippet will show the thin spaces in some specific screen size and zoom.

<script src="https://cdn.tailwindcss.com"></script>

<div class="h-[80vh] border-2 border-sky-500 m-2"></div>
<footer>
  <div class="bg-red-500 h-[30rem] relative">
    <div id="top-left" class="w-1/2 h-10 md:h-20 bg-inherit absolute transform -translate-y-full [clip-path:polygon(0%0%,100%100%,0%100%)]">
    </div>
    <div class="w-1/2 h-10 md:h-20 bg-inherit absolute transform -translate-y-full right-0 [clip-path:polygon(100%0%,100%100%,0%100%)]">
    </div>
    <div class="w-1/2 h-10 md:h-20 bg-white absolute bottom-0 [clip-path:polygon(0%0%,100%100%,0%100%)]"></div>
    <div class="w-1/2 h-10 md:h-20 bg-white absolute bottom-0 right-0 [clip-path:polygon(100%0%,100%100%,0%100%)]">
    </div>
  </div>
</footer>

If subpixel rendering is indeed the problem in your case, this can be fixed by forcing the use of GPU rendering such as using will-change-transform as shown below. (Using a tiny rotate forces subpixel rendering as well, which is setting --tw-rotate in this case.)

<script src="https://cdn.tailwindcss.com"></script>

<div class="h-[80vh] border-2 border-sky-500 m-2"></div>
<footer>
  <div class="bg-red-500 h-[30rem] relative will-change-transform">
    <div id="top-left" class="w-1/2 h-10 md:h-20 bg-inherit absolute transform -translate-y-full [clip-path:polygon(0%0%,100%100%,0%100%)]">
    </div>
    <div class="w-1/2 h-10 md:h-20 bg-inherit absolute transform -translate-y-full right-0 [clip-path:polygon(100%0%,100%100%,0%100%)]">
    </div>
    <div class="w-1/2 h-10 md:h-20 bg-white absolute bottom-0 [clip-path:polygon(0%0%,100%100%,0%100%)]"></div>
    <div class="w-1/2 h-10 md:h-20 bg-white absolute bottom-0 right-0 [clip-path:polygon(100%0%,100%100%,0%100%)]">
    </div>
  </div>
</footer>

Or, you can simply move the four triangles 1px closer to the edge as a quick solution without any performance disadvantage:

<script src="https://cdn.tailwindcss.com"></script>

<div class="h-[80vh] border-2 border-sky-500 m-2"></div>
<footer>
  <div class="bg-red-500 h-[30rem] relative">
    <div id="top-left" class="w-1/2 h-10 md:h-20 bg-inherit absolute transform -translate-y-full [clip-path:polygon(0%0%,100%100%,0%100%)] top-px">
    </div>
    <div class="w-1/2 h-10 md:h-20 bg-inherit absolute transform -translate-y-full right-0 [clip-path:polygon(100%0%,100%100%,0%100%)] top-px">
    </div>
    <div class="w-1/2 h-10 md:h-20 bg-white absolute bottom-0 [clip-path:polygon(0%0%,100%100%,0%100%)] bottom-[-1px]"></div>
    <div class="w-1/2 h-10 md:h-20 bg-white absolute bottom-0 right-0 [clip-path:polygon(100%0%,100%100%,0%100%)] bottom-[-1px]">
    </div>
  </div>
</footer>

Or, just use clip-path or SVG to draw the same shape instead of using transform:

.clipped {
  height: calc(100% + var(--h));
  top: calc(-1 * var(--h));
  clip-path: polygon(0 0, 50% var(--h), 100% 0, 100% calc(100% - var(--h)), 50% 100%, 0 calc(100% - var(--h)));
}
<script src="https://cdn.tailwindcss.com"></script>

<div class="h-[80vh] border-2 border-sky-500 m-2"></div>
<footer>
  <div class="h-[30rem] relative">
    <div class="clipped bg-red-500 relative [--h:2.5rem] md:[--h:5rem]"></div>
  </div>
</footer>

2024-07-11
SyndRain