Search code examples
htmlcsssvgclip-path

clip-path speech bubble with transparent content background


I have created a speech bubble clip-path with border(very important.) Now I'm trying to make the content background transparent.

Here is my current solution:

.background {
  background: url(https://thumbs.dreamstime.com/b/birch-forest-sunny-day-green-woods-summer-spring-landscape-43067305.jpg) no-repeat;
  background-size: cover;
  text-align: center;
}

.clip-svg {
  width: 0;
  height: 0;
}

.clip-wrap {
  display: inline-block;
  vertical-align: top;
  padding: 3px;
  background-color: #639;
  background-color: rebeccaPurple;
  clip-path: url("#speechebubble-clip");
}

.clip {
  width: 180px;
  height: 180px;
  position: relative;
  background: #fff;
}

.clip {
  clip-path: url("#speechebubble-clip");
}
<div class="background">
  <div class="clip-wrap">
    <div class="clip">
      test
    </div>
  </div>
</div>

<svg class="clip-svg">
 <defs>
  <clipPath id="speechebubble-clip" clipPathUnits="objectBoundingBox">
  <path width="100%" height="100%" transform="scale(0.0045, 0.00385)" id="clip-mask" d="M34.1983772,243.81581 C35.2123618,243.81581 36.0373744,244.643759 36.0373744,245.661353 L36.0373744,260 L63.450348,244.064408 C63.7301493,243.901754 64.0488773,243.81581 64.3720879,243.81581 L233,243.81581 L233,2 L2,2 L2,243.81581 L34.1983772,243.81581 Z" />
  </clipPath>
 </defs>
</svg>

Would it be possible to make the white content div transparent?


Solution

  • If you are open to another idea, I would consider using multiple background and clip-path to achieve this:

    body {
      background: url(https://thumbs.dreamstime.com/b/birch-forest-sunny-day-green-woods-summer-spring-landscape-43067305.jpg) no-repeat;
      background-size: cover;
      text-align: center;
    }
    
    .bubble {
      width: 180px;
      height: 180px;
      margin:20px auto;
      position: relative;
      border:3px solid purple;
      background:
      linear-gradient(purple,purple) 0 100%/40px 20px no-repeat,
      linear-gradient(purple,purple) 100% 100%/100px 20px no-repeat,
      linear-gradient(to bottom right,transparent 50%,purple 50.5%) 40px 100%/40px 20px no-repeat;
      -webkit-clip-path: polygon(0% 0%, 100% 0%, 100% calc(100% - 19px), 80px calc(100% - 19px), 40px 100%, 40px calc(100% - 19px), 0% calc(100% - 19px));
    clip-path: polygon(0% 0%, 100% 0%, 100% calc(100% - 19px), 80px calc(100% - 19px), 40px 100%, 40px calc(100% - 19px), 0% calc(100% - 19px));
    }
    <div class="bubble">
     some text
    </div>

    And here is another idea using pseudo element to avoid the clip-path:

    body {
      background: url(https://thumbs.dreamstime.com/b/birch-forest-sunny-day-green-woods-summer-spring-landscape-43067305.jpg) no-repeat;
      background-size: cover;
      text-align: center;
    }
    
    .bubble {
      width: 180px;
      height: 180px;
      margin:20px auto 60px;
      position: relative;
      border:3px solid purple;
      border-bottom:none;
      background:
      linear-gradient(to right,purple 20px,transparent 20px,transparent 80px,purple 0)0 100%/100% 2px  no-repeat;
      position:relative;
    }
    .bubble:before {
      content:"";
      position:absolute;
      bottom:-38px;
      left:17px;
      width:62px;
      height:40px;
      border-left:3px solid purple;
      background:linear-gradient(to bottom right,transparent calc(50% - 2px),purple calc(50% - 2px),purple 50%,transparent 0);
    }
    <div class="bubble">
     some text
    </div>