使用CSS穿透背景

时间:2019-01-08 14:24:43

标签: css svg

这个问题确实很奇怪,所以让我用一个片段来说明:

.container {
  width: 200px;
  height: 200px;
  background: rgba(200, 200, 200, .87);
}

.pin {
  position: absolute;
  left: 50px;
  top: 20px;
}

.overlay {
  position: absolute;
  left: 25px;
  top: 40px;
  background: grey;
  border: 1px solid white;
  padding: 12px;
  padding-top: 30px;
}

.overlay:before {
  content: '';
  position: absolute;
  border: 1px solid white;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  top: -30px;
  left: 10px;
}
<div class="container">
  <div class="pin">
    <svg width="24" height="36" viewBox="0 0 192 290" xmlns="http://www.w3.org/2000/svg">
      <path d="
        M11 138
        a 94 94 0 1 1 170 0
        l -85 150
        l -85 -150
      " fill="white" stroke="black" stroke-width="2" stroke-opacity="0.9" opacity="0.9" />
    </svg>
  </div>
  <div class="overlay">
    Content
  </div>
</div>

如您在此代码段中所见,有一个图钉,前面有一些内容。

我希望图钉包含在白色圆圈中,而内容不与该圆圈重叠。就像,如果圈子突破了内容,并删除了其中的一小部分。

我曾考虑为内容容器创建一个SVG而不是DIV(以便该容器的顶部少半个圆),但是我不确定是否适合这种情况(内容会是动态的,内容的宽度可以更改)。

有没有一种方法可以实现我想要的,仅使用CSS?

先谢谢您。

3 个答案:

答案 0 :(得分:2)

这对于使用径向渐变的图像蒙版(IE或Edge <18不支持)是可能的

.container {
  width: 200px;
  height: 200px;
  background: rgba(200, 200, 200, .87);
}

.pin {
  position: absolute;
  left: 50px;
  top: 20px;
}

.overlay {
  position: absolute;
  left: 25px;
  top: 40px;
  background: grey;
  border: 1px solid white;
  padding: 12px;
  padding-top: 30px;
}

.overlay:before {
  content: '';
  position: absolute;
  border: 1px solid white;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  top: 0;
  transform: translateY(-50%);
}

.masked-circle {
  -webkit-mask-image: radial-gradient(circle at 50% 0%, transparent 0, transparent 25px, black 25px);
}
<div class="container">
  <div class="pin">
    <svg width="24" height="36" viewBox="0 0 192 290" xmlns="http://www.w3.org/2000/svg">
      <path d="
        M11 138
        a 94 94 0 1 1 170 0
        l -85 150
        l -85 -150
      " fill="white" stroke="black" stroke-width="2" stroke-opacity="0.9" opacity="0.9" />
    </svg>
  </div>
  <div class="overlay masked-circle">
    Content
  </div>
</div>

答案 1 :(得分:2)

您可以在灰色框阴影前的:::之前填充.overlay.overlayoverflow:hidden;,所以阴影一直留在里面。

.container {
  width: 200px;
  height: 200px;
  background: rgba(200, 200, 200, .87);

}

.pin::before{
  content: '';
  position: absolute;
  border: 1px solid white;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  top: -10px;
  left: -12px;
}

.pin {
  position: absolute;
  left: 50px;
  top: 20px;
}

.overlay {
  position: absolute;
  left: 25px;
  top: 40px;
  border: 1px solid white;
  border-top:none;
  padding: 12px;
  padding-top: 30px;
  overflow:hidden;
  z-index:1
}

.overlay:before {
  content: '';
  position: absolute;
  border: 1px solid white;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  top: -30px;
  left: 12.3345px;
  background:transparent;
  box-shadow: 0 0 0 100px grey;
  z-index:-1;
}
<div class="container">
  <div class="overlay">
    Content
  </div>
  <div class="pin">
    <svg width="24" height="36" viewBox="0 0 192 290" xmlns="http://www.w3.org/2000/svg">
      <path d="
        M11 138
        a 94 94 0 1 1 170 0
        l -85 150
        l -85 -150
      " fill="white" stroke="black" stroke-width="2" stroke-opacity="0.9" opacity="0.9" />
    </svg>
  </div>
  
</div>

答案 2 :(得分:2)

由于叠加层属于元素,因此您可以考虑径向渐变和CSS变量,以使某些东西具有动态性(无边框)。

为简单起见,我移除了该图钉,但您可以轻松地调整其位置以使其位于圆内,或将其用作叠加元素的背景:

.container {
  width: 200px;
  height: 120px;
  background: linear-gradient(red,yellow);
  display: inline-block;
  position: relative;
}

.overlay {
  --top: -3px;
  --left: 35px;
  --radius: 24px;
  position: absolute;
  left: 25px;
  top: 40px;
  background: radial-gradient(circle at var(--left) var(--top), transparent 0, transparent var(--radius), grey var(--radius));
  padding: 12px;
  padding-top: 30px;
}

.overlay:before {
  content: '';
  position: absolute;
  border: 1px solid white;
  width: calc(2*var(--radius));
  height: calc(2*var(--radius));
  border-radius: 50%;
  top: var(--top);
  left: var(--left);
  transform: translate(-50%, -50%);/*to keep the same origin*/
  background:url('data:image/svg+xml;utf8,<svg width="24" height="36" viewBox="0 0 192 290" xmlns="http://www.w3.org/2000/svg"><path d=" M11 138 a 94 94 0 1 1 170 0 l -85 150 l -85 -150" fill="white" stroke="black" stroke-width="2" stroke-opacity="0.9" opacity="0.9" /></svg>') center no-repeat;
}
<div class="container">
  <div class="overlay">
    Content
  </div>
</div>
<div class="container">
  <div class="overlay" style="--top:10px;--left:5px">
    Content
  </div>
</div>

<div class="container">
  <div class="overlay" style="--top:50px;--left:5px;--radius:30px;">
    Content
  </div>
</div>
<div class="container">
  <div class="overlay" style="--top:50px;--left:50px;--radius:40px;">
    Content
  </div>
</div>
<div class="container">
  <div class="overlay" style="--top:50px;--left:120px">
    Content
  </div>
</div>

如果您想要任何背景,也可以使用遮罩:

.container {
  width: 200px;
  height: 120px;
  background: linear-gradient(red,yellow);
  display: inline-block;
  vertical-align:top;
  position: relative;
  --top: -3px;
  --left: 35px;
  --radius: 24px;
}
.pin {
  position:absolute;
  text-align:center;
  border: 1px solid white;
  width: calc(2*var(--radius));
  height: calc(2*var(--radius));
  border-radius: 50%;
  top: calc(40px + var(--top));
  left: calc(25px + var(--left));
  transform: translate(-50%, -50%);/*to keep the same origin*/
}
svg {
 margin-top:10px;
}
.overlay {
  position: absolute;
  left: 25px;
  top: 40px;
  -webkit-mask-image: radial-gradient(circle at var(--left) var(--top),     transparent 0, transparent var(--radius), black var(--radius));
  background: linear-gradient(yellow,blue);
  padding: 12px;
  padding-top: 30px;
}

.overlay:before {
  content: '';
  position: absolute;
  border-radius: 50%;
}
<div class="container">
  <div class="pin">
    <svg width="24" height="36" viewBox="0 0 192 290" xmlns="http://www.w3.org/2000/svg">
      <path d="
        M11 138
        a 94 94 0 1 1 170 0
        l -85 150
        l -85 -150
      " fill="white" stroke="black" stroke-width="2" stroke-opacity="0.9" opacity="0.9" />
    </svg>
  </div>
  <div class="overlay">
    Content
  </div>
</div>
<div class="container" style="--top:50px;--left:5px;--radius:30px;">
<div class="pin">
    <svg width="24" height="36" viewBox="0 0 192 290" xmlns="http://www.w3.org/2000/svg">
      <path d="
        M11 138
        a 94 94 0 1 1 170 0
        l -85 150
        l -85 -150
      " fill="white" stroke="black" stroke-width="2" stroke-opacity="0.9" opacity="0.9" />
    </svg>
  </div>
  <div class="overlay" >
    Content
  </div>
</div>

<div class="container" style="--top:50px;--left:5px;--radius:30px;">
<div class="pin">
    <svg width="24" height="36" viewBox="0 0 192 290" xmlns="http://www.w3.org/2000/svg">
      <path d="
        M11 138
        a 94 94 0 1 1 170 0
        l -85 150
        l -85 -150
      " fill="white" stroke="black" stroke-width="2" stroke-opacity="0.9" opacity="0.9" />
    </svg>
  </div>
  <div class="overlay" >
    Content
  </div>
</div>
<div class="container" style="--top:50px;--left:50px;--radius:40px;">
<div class="pin">
    <svg width="24" height="36" viewBox="0 0 192 290" xmlns="http://www.w3.org/2000/svg">
      <path d="
        M11 138
        a 94 94 0 1 1 170 0
        l -85 150
        l -85 -150
      " fill="white" stroke="black" stroke-width="2" stroke-opacity="0.9" opacity="0.9" />
    </svg>
  </div>
  <div class="overlay" >
    Content
  </div>
</div>
<div class="container" style="--top:50px;--left:120px">
<div class="pin">
    <svg width="24" height="36" viewBox="0 0 192 290" xmlns="http://www.w3.org/2000/svg">
      <path d="
        M11 138
        a 94 94 0 1 1 170 0
        l -85 150
        l -85 -150
      " fill="white" stroke="black" stroke-width="2" stroke-opacity="0.9" opacity="0.9" />
    </svg>
  </div>
  <div class="overlay" >
    Content
  </div>
</div>