Несколько прозрачных кругов, использующих только css (вырезы)

Я уже читал этот отличный вопрос прозрачный полый или вырезать кружок но я хочу!--5-->нарисуйте больше кругов (допустим, три).

поэтому я попытался использовать дополнительный элемент для круга вместо псевдо-элемента (поэтому я могу добавить больше), и он работает для одного круга, но не для большего. Проблема в том, что они не прозрачны, так как последний охватывает все. Вот моя попытка:

body{
  background-color:violet;
}
.shape{  
    height: 150px;
    width: 150px;
    position:relative;
    overflow:hidden;
}
.hole{
    position:absolute;
    border-radius:100%;
    width:30px; height:30px;
    color:red;
    box-shadow: 0px 0px 0px 2000px black;
}
.hole:nth-child(1) {
    left:25px; top:25px; 
}
.hole:nth-child(2) {
    left:65px; top:25px; 
}
.hole:nth-child(3) {
    left:55px; top:65px; 
}
<div class="shape">
  <div class="hole">1</div>
  <div class="hole">2</div>
  <div class="hole">3</div>
</div>

4 ответов


просто используйте svg. Черная часть маски удаляется из элемента, к которому она применяется, и сохраняется белая:

html, body {
  height: 100%;
  margin: 0;
  background: linear-gradient(to top, red, blue);
}

svg {
  display: block;
  width: 150px;
}
<svg viewBox="0 0 150 150">
  <mask id="circles" maskUnits="objectBoundingBox">
    <rect x="0" y="0" width="100%" height="100%" fill="white" />
    <circle cx="40" cy="40" r="15" fill="black" />
    <circle cx="80" cy="40" r="15" fill="black" />
    <circle cx="70" cy="80" r="15" fill="black" />
  </mask>
  
  <rect x="0" y="0" width="100%" height="100%" fill="green" style="mask: url(#circles)" />
</svg>

если вы действительно хотите сделать это с в CSS и если вы не боитесь несколько окне-тени, вы могли бы сделать это но вы должны знать, что это жестко закодированы и значения для box-shadow должны быть обновлены, когда cirlces изменить положение, размер или номер.

вот пример подхода, который вы можете использовать, значения для box shadow должны быть " оптимизированы" :

body {
  background: url('https://farm9.staticflickr.com/8760/17195790401_ceeeafcddb_o.jpg');background-size:cover;
}
.shape {
  height: 150px;
  width: 150px;
  position: relative;
  overflow: hidden;
}
.hole {
  position: absolute;
  border-radius: 100%;
  width: 30px;
  height: 30px;
  color: red;
}
.hole:nth-child(1) {
  left: 25px;
  top: 25px;
  box-shadow: -38px -33px 0px 55px black, 9px 14px 0px 0px black;
}
.hole:nth-child(2) {
  left: 65px;
  top: 25px;
  box-shadow: 76px -63px 0px 100px black, -7px 6px 0px 0px black;
}
.hole:nth-child(3) {
  left: 55px;
  top: 65px;
  box-shadow: -3px 91px 0px 100px black;
}
<div class="shape">
  <div class="hole">1</div>
  <div class="hole">2</div>
  <div class="hole">3</div>
</div>

кроме этого, я бы четко рекомендовать использование SVG либо с маскировкой / обрезкой, либо с путем, как показано в ответе, с которым вы связаны. Вот пример с несколькими вырезанными прозрачными кругами, использующими элемент path с командой arc:

body{background: url('https://farm9.staticflickr.com/8760/17195790401_ceeeafcddb_o.jpg');background-size:cover;}
svg{
  display:block;
  width:70%;
  height:auto;
  margin:0 auto;
}
path{
  transition:fill .5s;
  fill:#E3DFD2;
}
<svg viewbox="-10 -1 30 15">
  <path d="M-10 -1 H30 V15 H-10z 
           M 5 5 m -5, 0 
           a 5,5 0 1,0 10,0 
           a 5,5 0 1,0 -10,0
           M-3 10 m -2, 0
           a 2,2 0 1 ,0 4,0
           a 2,2 0 1 ,0 -4,0
           M15 8 m -2, 0
           a 2,2 0 1 ,0 4,0
           a 2,2 0 1 ,0 -4,0
           M-5 5 m -2, 0
           a 2,2 0 1 ,0 4,0
           a 2,2 0 1 ,0 -4,0"/>
</svg>

вышеуказанный код fomarted поэтому каждый круг в элементе пути "нарисован" с :

M cx cy m -r, 0
a r,r 0 1,0 (r * 2),0
a r,r 0 1,0 -(r * 2),0

центр круга -cx, cy и r - это его радиус. См.ответ для объяснений.
Первая строка (M-10 -1 H30 V15 H-10z) сделано для того чтобы сделать surounding прямоугольник и каждое cirlce "режет его вне".

преимущество этого подхода заключается в том, что он работает для всех браузеров, поддерживающих встроенный svg. Даже те, кто не поддерживает маскировку или обрезку.

чтобы понять, как это работает, вы должны взглянуть на :


вы можете использовать значения цвета rgba, указывающие непрозрачность, вместо использования одного цвета для вашей тени коробки, чтобы иметь желаемый эффект.

попробовать box-shadow: 0px 0px 0px 2000px rgba(0, 0, 0 , 0.1);


<!DOCTYPE html>
<html>
<head>
<style>
.shape{  
    height: 150px;
    width: 150px;
    position:relative;
    overflow:hidden;
	background-color:#333333;
}
.hole{
    position:absolute;
    border-radius:20px;
    width:20px; 
	height:20px;
    color:red;
    background-color:white;
	opacity:0.6; /* for transparency levels change between 0=invisible and 1=opaque */
	text-align:center;
}
.hole:nth-child(1) {
    left:25px; top:25px; 
}
.hole:nth-child(2) {
    left:65px; top:25px; 
}
.hole:nth-child(3) {
    left:55px; top:65px; 
}
</style>
</head>
<body>
	<div class="shape">
	  <div class="hole">1</div>
	  <div class="hole">2</div>
	  <div class="hole">3</div>
	</div>
</body>
</html>