How is it possible to create a hole in an overlay where you can see through to the actual website?
You can now achieve this with relatively good support in new webkit browsers using css clipping (see here for compatability).
For example, the following code would cut a hole with a radius of 100px (so 200px wide) in the center of your element (with a slightly feathered edge).
-webkit-mask-image radial-gradient(100px at 50% 50% , transparent 95%, black 100%)
Here's a codepen to demonstrate.
Yes, this effect is possible.
I would use the css box-shadow with a very large spread radius.
box-shadow: 0 0 0 9999px rgba(0, 0, 255, 0.2);
.hole {
position: absolute;
top: 20px;
left: 20px;
width: 200px;
height: 150px;
box-shadow: 0 0 0 9999px rgba(0, 0, 255, 0.2);
}
<p>Lorem ipsum dolor sit amet, ocurreret tincidunt philosophia in sea, at pro postea ullamcorper. Mea ei aeque feugiat, cum ut utinam conceptam, in pro partem veritus molestiae. Omnis efficiantur an eum, te mel quot perpetua. Ad duo autem dolore, vocent lucilius te cum, ut duo quem singulis.</p>
<p>Has ex idque repudiandae, an mei munere philosophia. Sale molestie id eos, eam ne blandit adipisci. Ei eam ipsum dissentiunt. Ei vel accusam dolores efficiantur.</p>
<div class="hole"></div>
This is possible, to a degree.
body, html{
height:100%;
width:100%;
padding:0;
margin:0;
background:blue;
}
#overlay{
height:100%;
width:100%;
position:fixed;
border:50px solid rgba(255,255,255,.3);
box-sizing:border-box;
top:0;
left:0;
}
<div id='overlay'></div>
content content content contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent
body,
html {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
position: fixed;
background: blue;
}
#overlay {
display: table;
height: 100%;
width: 100%;
position: absolute;
top: 0;
left: 0;
}
.row {
display: table-row;
}
.cell {
display: table-cell;
opacity: 0.9;
background: grey;
}
.row:nth-child(2) .cell:nth-child(2) {
opacity: 0;
}
<div id='overlay'>
<div class='row'>
<div class='cell'></div>
<div class='cell'></div>
<div class='cell'></div>
</div>
<div class='row'>
<div class='cell'> </div>
<div class='cell'> </div>
<div class='cell'> </div>
</div>
<div class='row'>
<div class='cell'></div>
<div class='cell'></div>
<div class='cell'></div>
</div>
</div>
content content content contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent
contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent
contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent contentcontent
Thank to CSS clip-path, it is now possible, even drilling any content of the overlay and its background-images / backdrop-filters and even pointer-events.
To do this, we need to define a path made of a first rectangle covering all the viewport, and then an inner shape that will represent our hole. Thanks to the even-odd
fill-rule, only our inner shape will actually be part of the clipping-area.
That should have been easy to draw any shape with the path()
<basic-shape>, but unfortunately, only Firefox supports it for clip-path
, so we have to fallback using the polygon()
function which means we have to define every points as vectors.
While it's still readable for a simple square hole:
.hole {
position: fixed;
width: 100vw;
height: 100vh;
top: 0px;
left: 0px;
--rect-size: 75px;
clip-path: polygon( evenodd,
/* outer rect */
0 0, /* top - left */
100% 0, /* top - right */
100% 100%, /* bottom - right */
0% 100%, /* bottom - left */
0 0, /* and top - left again */
/* do the same with inner rect */
calc(50% - var(--rect-size) / 2) calc(50% - var(--rect-size) / 2),
calc(50% + var(--rect-size) / 2) calc(50% - var(--rect-size) / 2),
calc(50% + var(--rect-size) / 2) calc(50% + var(--rect-size) / 2),
calc(50% - var(--rect-size) / 2) calc(50% + var(--rect-size) / 2),
calc(50% - var(--rect-size) / 2) calc(50% - var(--rect-size) / 2)
);
/* can cut through all this */
background-color: rgba(10, 161, 232, 0.3);
background-image: url(https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png);
background-size: 40px;
-webkit-backdrop-filter: blur(3px);
backdrop-filter: blur(3px);
display: flex;
justify-content: center;
}
.hole > p {
align-self: center;
font-size: 18px;
font-weight: bold;
}
.hole-text {
font-size: 100px;
}
body { color: black; }
<p>Lorem ipsum dolor sit amet, ocurreret tincidunt philosophia in sea, at pro postea ullamcorper. Mea ei aeque feugiat, cum ut utinam conceptam, in pro partem veritus molestiae. Omnis efficiantur an eum, te mel quot perpetua. Ad duo autem dolore, vocent
lucilius te cum, ut duo quem singulis.</p>
<p>Has ex idque repudiandae, an mei munere philosophia. Sale molestie id eos, eam ne blandit adipisci. Ei eam ipsum dissentiunt. Ei vel accusam dolores efficiantur.</p>
<div class="hole">
<p>There is an <span class="hole-text">HOLE</span> here</p>
</div>
Having all the points of a circle for instance would make for a far bigger rule, so if you don't need to cut through pointer-events, then the mask-image solution by Ed Hinchliffe should probably be preferred.
Anyway, here is a JS generator for a circle (the generated rule could still be hard-coded in a CSS file if needed).
function makeCircleHoleClipPathRule( radius ) {
const inner_path = [];
const circumference = Math.PI * radius;
const step = Math.PI * 2 / circumference;
// we are coming from top-left corner
const start_step = circumference * (5 / 8);
for( let i = start_step; i < circumference + start_step; i++ ) {
const angle = step * i;
const x = radius * Math.cos( angle );
const y = radius * Math.sin( angle );
const str = `calc( 50% + ${ x }px ) calc( 50% + ${ y }px )`;
inner_path.push( str );
}
// avoid rounding issues
inner_path.push( inner_path[ 0 ] );
return `polygon( evenodd,
/* outer rect */
0 0, /* top - left */
100% 0, /* top - right */
100% 100%, /* bottom - right */
0% 100%, /* bottom - left */
0 0, /* and top - left again */
${ inner_path.join( "," ) }
)`;
}
const hole_elem = document.querySelector( ".hole" );
// set the clip-path rule
hole_elem.style.clipPath = makeCircleHoleClipPathRule( 50 );
.hole {
position: fixed;
width: 100vw;
height: 100vh;
top: 0px;
left: 0px;
/* clip-path is set by JS */
background-color: rgba(10, 161, 232, 0.3);
background-image: url(https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png);
background-size: 40px;
-webkit-backdrop-filter: blur(3px);
backdrop-filter: blur(3px);
display: flex;
justify-content: center;
}
.hole > p {
align-self: center;
font-size: 18px;
font-weight: bold;
}
.hole-text {
font-size: 100px;
}
body { color: black; }
<p>Lorem ipsum dolor sit amet, ocurreret tincidunt philosophia in sea, at pro postea ullamcorper. Mea ei aeque feugiat, cum ut utinam conceptam, in pro partem veritus molestiae. Omnis efficiantur an eum, te mel quot perpetua. Ad duo autem dolore, vocent
lucilius te cum, ut duo quem singulis.</p>
<p>Has ex idque repudiandae, an mei munere philosophia. Sale molestie id eos, eam ne blandit adipisci. Ei eam ipsum dissentiunt. Ei vel accusam dolores efficiantur.</p>
<div class="hole">
<p>There is an <span class="hole-text">HOLE</span> here</p>
</div>
And for other shapes, I'll let the reader handle it ;-)
This is not possible.
But anyways you can do the border trick: The #overlay
itself is transparent but The borders are not. See the fiddle: http://jsfiddle.net/qaXRp/2/
No. This is not possible, not in most browsers.
CSS Masking
You can use masking
, if you are interested only in new browsers:
Specs: http://www.w3.org/TR/css-masking/
Compatibility: http://caniuse.com/css-masks
Border / Outline
You can also use border
or outline
css properties if you want to create simular effect and set color of them to transparent
so it looks simular.
Position Absolute
You can also use position:
<div z-index:20></div>
<div z-index:10>
<div z-index:30> // top div is over child of this one
</div>
Transparency and elements
http://css-tricks.com/non-transparent-elements-inside-transparent-elements/
http://css-tricks.com/examples/NonTransparentOverTransparent/
-- this is not what are you asking for, but it can helps you :)