Is it possible to dynamically cut out an area of an HTML div and see and interact with the HTML beneath it?
For example, say I have a div of mixed HTML content of 500x500 centered on top of other HTML content. Now I want to punch a round hole through the top content so I can see and interact with the content beneath it. Is it possible?
I think they call it masking or knock out.
If you need to interact with the portion beneath (through the cut-out area) then using clip-path
would be the correct option in my opinion. Masks show the portion beneath but they accomplish it by making the cut-out area of the top element as transparent. So when there is any sort of interaction (even in the cut-out area) it is essentially happening on the top element only. When using clip-path
the area that is cut-out is totally blank and the top element has nothing in there. So when that portion is hovered on, the interaction there is directly on the bottom element.
Clip-path Demo: (when the cut out area is hovered, the background of bottom element changes)
.example {
position: relative;
height: 200px;
width: 200px;
margin: 10px;
}
.example div {
position: absolute;
height: 100%;
width: 100%;
}
.bottom-layer {
background: beige;
}
.bottom-layer:hover {
background: chocolate;
}
.top-layer {
background: tomato;
}
.top-layer:hover {
background: hotpink;
}
#example1 .top-layer {
clip-path: url(#circle);
}
#example2 .top-layer {
clip-path: url(#pentagon);
}
<div class='example' id='example1'>
<div class='bottom-layer'>Some content</div>
<div class='top-layer'>Top content</div>
</div>
<div class='example' id='example2'>
<div class='bottom-layer'>Some content</div>
<div class='top-layer'>Top content</div>
</div>
<!-- the clip-path definition -->
<svg height="0" width="0">
<defs>
<clipPath id='pentagon' clipPathUnits='objectBoundingBox'>
<path d='M0.25,0.25 0.75,0.25 0.75,0.5 0.5,0.75 0.25,0.5 0.25,0 0,0 0,1 1,1 1,0 0.25,0z' />
</clipPath>
<clipPath id='circle' clipPathUnits='objectBoundingBox'>
<path d='M0.25,0.5 A0.25,0.25 0 1,1 0.75,0.5 L1,0.5 1,0 0,0 0,0.5 0.25,0.5
M0.75,0.5 A0.25,0.25 0 1,1 0.25,0.5 L0,0.5 0,1 1,1 1,0.5 0.75,0.5' />
</clipPath>
</defs>
</svg>
Sample Mask: (hovering on the cut out area has no impact on the bottom element)
.example {
position: relative;
height: 200px;
width: 200px;
margin: 10px;
}
.example div {
position: absolute;
height: 100%;
width: 100%;
}
.bottom-layer {
background: beige;
}
.bottom-layer:hover {
background: chocolate;
}
.top-layer {
background: tomato;
}
.top-layer:hover {
background: hotpink;
}
#example1 .top-layer {
-webkit-mask-image: radial-gradient(circle farthest-side at 50% 50%, transparent 50%, white 50%);
}
#example2 .top-layer {
-webkit-mask-image: linear-gradient(to top left, white 50%, transparent 50%);
}
<div class='example' id='example1'>
<div class='bottom-layer'>Some content</div>
<div class='top-layer'>Top content</div>
</div>
<div class='example' id='example2'>
<div class='bottom-layer'>Some content</div>
<div class='top-layer'>Top content</div>
</div>