Definition of Hole in a div - An element or a method by which you can show the background, only for a particular area, behind the content of a <div>
element.
Creating a hole in a element
Asked
Active
Viewed 3.4k times
38
Brian Webster
- 30,033
- 48
- 152
- 225
Sussagittikasusa
- 2,525
- 9
- 33
- 47
-
1
you mean creating a mask? best thing would split the div up in portions and make the opacity 0 in the part where you want to unmask
– Breezer
Dec 03 '10 at 11:07
-
Not like a mask, something like a see through lens.
– Sussagittikasusa
Dec 03 '10 at 11:09
-
k but my answer stays the same split the div up in portions and make the opacity 0 in the part where you want to lens :P
– Breezer
Dec 03 '10 at 11:10
-
Its going to be really difficult splitting that div up man, there has to be another way.
– Sussagittikasusa
Dec 03 '10 at 11:12
-
4
Is it an option to create a GIF with a transparent area and use this as background-image of the div(background-color of the div has to be set to transparent)?
– Dr.Molle
Dec 03 '10 at 11:13
-
Yeah, then after that? How do we make it seethrough in a particular area?
– Sussagittikasusa
Dec 03 '10 at 11:16
-
nope trust me when i say it's not possible, you have to see a page as layers of boxes where you can do anything to the entire box but nothing with just a portion of it
– Breezer
Dec 03 '10 at 11:24
-
Hmmmm... maybe the background of this div element can be broken into smaller boxes... and I can achieve what I'm looking for.
– Sussagittikasusa
Dec 03 '10 at 11:27
-
could you possible show us your page and maybe tell us what you want to be able to see through the lens
– Breezer
Dec 03 '10 at 11:29
-
regarding to my comment above: the transparent area of the background-image will be the area you can see trough.
– Dr.Molle
Dec 03 '10 at 12:26
10 Answers
56
CSS box-shadow
is supported in almost all modern browsers, so you can do what you want (I hope, I understood you right) this way:
body {
margin: 0;
padding: 0;
}
.hole {
position: absolute;
left: 50px;
top: 50px;
width: 100px;
height: 100px;
box-shadow: 0 0 0 99999px rgba(0, 0, 0, .8);
}
<img src="http://upload.wikimedia.org/wikipedia/commons/5/51/Fox_Head.jpg" alt="" style="width: 100%;">
<div class="hole"></div>
So, the block will be transparent, and all around it will be highlighted with its shadow.
Anurag Srivastava
- 14,077
- 4
- 33
- 43
equinox
- 701
- 5
- 8
-
3
-
2
-
1
@equinox outline-width appears to max out at 65534px on Chrome version 40.0, so "outline: 65534px solid rgba(0, 0, 0, .8)" is fine, but higher values of outline-width result in no outline. There's a similar, though higher, limit with FF, too.
– Paul Pepper
Feb 18 '15 at 22:19
-
Outline seems not to support border-radius, it is block. Beware of using accidentally big blur radius eg. 0rem 0rem 4000rem 4000rem hsla(0, 0%, 0%, 0.6). In Mac Chrome Version 41.0.2272.104 (64-bit) causes significant slowness if background has eg. a table with few tens of cells. Scrolling and responsiveness to mouse is slow. Also it causes random rendering errors. Using blur radius 0 or outline is fast.
– Timo Kähkönen
Apr 04 '15 at 19:50
-
Making a huge box-shadow spread doesn't work on ios - disappears altogether when it exceeds some limit. equinox's solution: `outline: 9999px solid rgba(0, 0, 0, .8);` works great on ios. Although, as Paul Pepper points out, `99999px` probably exceeds an outline limit... but why would anyone want an outline 100,000px???
– sterfry68
Jul 01 '17 at 17:47
-
On iOS Safari I see an upper limit of `box-shadow` combined with `border-radius: 50%` at `951px`. After that, it just disappears. The `outline` combined with `border-radius` does not work for me on iOS.
– jkettmann
Jul 08 '18 at 08:01
-
1
Instead of setting an impossible high size like 99999px, for my use case, `calc(100vw + 100vh)` worked pretty well (also on iOS).
– Jefrey Sobreira Santos
Sep 02 '19 at 20:28
35
A new way to solve this, using blend modes, and supporting border-radius, multiple elements... but without support in IE
.back {
background-color: lightblue;
width: 400px;
height: 300px;
background-image: repeating-linear-gradient(45deg, white 0px,lightblue 40px);
}
.base {
position: relative;
left: 10px;
top: 10px;
width: 200px;
height: 200px;
border: solid 1px black;
background-color: white;
mix-blend-mode: hard-light;
}
.hole {
width: 80px;
height: 50px;
margin: 10px;
border: solid 1px red;
border-radius: 10px;
background-color: gray;
}
<div class="back">
<div class="base">
<div class="hole">ONE</div>
<div class="hole">TWO</div>
</div>
</div>
vals
- 61,425
- 11
- 89
- 138
-
This is some great information to know - I had not heard of `mix-blend-mode` beforehand. This should be the accepted answer.
– Gershom Maes
Oct 07 '15 at 22:56
-
-
@vals, Why is this only working with "gray" color for the Hole (any other color will not create a hole)???
– Gil Epshtain
Jun 26 '18 at 15:45
-
@GilEpshtain the **hard-light** blend-mode , when the channel intensity is 0.5 (or 128 in rgb scale), will reproduce the color of the background. gray is 0.5 in all chanels, so it reproduces fully the background
– vals
Jun 26 '18 at 17:18
-
4
It should be noted though that this **significantly decreases font quality** on both Firefox and Chrome (at least on Manjaro Linux) and that any color **other than `white`, `black`, `red`, `blue`, `lime`, `cyan`, `magenta` and `yellow`** become (partly) transparent. This affects not only the background color, but also text, borders, etc.
– Aloso
Aug 09 '18 at 15:36
-
@vals what would be the solution if you wanted the **base** div to be of any other color, for example pink? also the children?
– sima ghoreyshi
Dec 04 '21 at 06:09
-
@simaghoreyshi You can not choose any color , only colors with RGB values of 0 or 255 are supported (so, red or green is ok, also yellow, but not pink)
– vals
Dec 04 '21 at 18:47
13
You can construct a set of frame divs in the following format:

So, one container div, with no/little style applied to it.
Then a set of 4 'border' divs with style applied to them, leavin the central area transparent.
Tom Gullen
- 61,249
- 84
- 283
- 456
-
Not what i was looking for, but i guess i can make your answer work. Thanks man.
– Sussagittikasusa
Dec 03 '10 at 11:44
-
No problem, I'm not sure if there is a way to take a generic div and punch holes in it, I think you have to do it this way I am afraid.
– Tom Gullen
Dec 03 '10 at 11:47
-
2
Google has once created something like that... The hole followed your mouse as it moved over your site. Check http://googlecode.blogspot.com/2009/12/introducing-google-browser-size.html
– xtofl
Dec 03 '10 at 12:04
-
-
Making this work with round div, round hole (border-radius:50%) will be very hard to implement
– Gil Epshtain
Jun 26 '18 at 15:34
4
Found it!
- Parent div with a relative position, a transparent background and
hidden overflow.
- Child div with absolute position, with colored,
super big borders to fill the background of the parent, and a
transparent background.
The hole will be composed of a transparent child, with borders so big they fill up the parent's background. The positioning of the child will depend of the size of the borders. Set a background to whatever is behind the parent, and it will show through!
In this example you can see the red through the yellow faux background (which is actually a huge border).
#parent{overflow:hidden; position:relative;}
#child {position:absolute; border:9000px yellow solid; top:0; left:0;}
http://jsfiddle.net/CarambaMoreno/UrbhS/
What do you think?
CarambaMoreno
- 61
- 5
3
I designed something on code pen that I think you are/were looking for. I was looking for the same... couldn't find anything so this is what I made
Lucian Adamson
- 39
- 2
3
You can use a png with alpha channel transparency as the background image of your div.
<div style="background-image:url(pngwithtransparentarea.png);width:100px;height:100px;">
</div>
Bazzz
- 26,427
- 12
- 52
- 69
2
There's one approach, albeit it can only do mostly rectangular borders, with the following mark-up as a demo:
html:
<div id="wrap">
<div id="frame">
</div>
<img src="http://farm3.static.flickr.com/2232/2299184911_ea1091968b_z.jpg?zz=1" />
</div>
css:
#wrap {
overflow: hidden;
position: relative;
}
#frame {
border: 60px solid #000;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(255,255,255,0.5);
}
While there's no way to truly 'cut' a hole in a div
, there is the possibility of using -webkit-mask-box-image
to apply masks directly to images. Albeit this only works in, so far as I'm aware, Webkit browsers (I know that it's a -webkit
vendor-prefixed property, but I don't believe that there's a -moz
or -o
equivalent, sadly).
Demo using the above, -webkit-mask-box-image
property, at JS Fiddle.
David Thomas
- 249,100
- 51
- 377
- 410
-
Hey David thanks though this is not what i wanted. Suppose your '#wrap', or any outside container had a background color. The code should've been able to penetrate through the image and show the background color of the outside container.
– Sussagittikasusa
Dec 03 '10 at 11:25
-
@Sussagittikasusa: ah, in which case I may have completely misunderstood your question.
– David Thomas
Dec 03 '10 at 11:28
1
The larger issue is not actually the background of the element you want to see through (which would just be background-color:transparent) but instead its ancestor element(s). For instance, a div with a background-color: transparent is still going to look as if it has a white background if its containing element has a white background. The best approach then is to define the background colors at lower levels in the page. For instance, if you want to see through div#see-through and it's a child of div#content which is in between div#header and div#footer, you could give #header and #footer background colors but define #content as transparent. Then assign background colors to the individual sibling elements of #see-through. One more thing: it might be helpful to remember when defining the transparent element that even a transparent element can have "colored" borders, meaning that you might be able to reach into in-between spots without adding extra elements.
DavidH
- 34
- 1
-
Just asking, is it possible to cut a hole through an element with having the element a background color gradient?
– Green
Feb 20 '21 at 23:32
0
After really thinking this through best thing i could come up with is if you use an iframe
it could be the "lens" that views whatever you desire but ofcourse it wont work like a real lens but close to
Breezer
- 10,410
- 6
- 29
- 50
0
If it's acceptable to use an SVG element instead of a div, SVG provides a flexible mechanism for cutting holes using the fill-rule="evenodd"
attribute. You can create as many transparent regions of any shape as you'd like.
Here's an example that cuts two square holes into a gray square (also available as a JSFiddle):
<img
src="http://upload.wikimedia.org/wikipedia/commons/5/51/Fox_Head.jpg"
style="position: absolute; width: 300px;"
>
<svg style="position: absolute; width: 300px; height: 300px;">
<!--
This `path` element draws 3 squares:
1. A gray 300x300 square
2. A transparent 100x100 square
3. Another transparent 100x100 square
The key mechanism for creating transparent regions in the shape is
`fill-rule="evenodd"`. This attribute affects pixel colors in the following
way. Pick a pixel and draw an infinitely long line in any direction:
- If the line crosses an odd number of lines, the pixel receives the fill
color. In this fiddle, the infinite line extending from any gray pixel
crossed an odd number of lines -- for example, just the line that is the
perimeter of the gray rectangle.
- If the line crosses an even number of lines, the pixel is transparent.
In this fiddle, the infinite line extending from any transparent pixel
crossed an even number of lines -- for example, the perimeters of the
transparent square and the gray square.
-->
<path
fill="grey"
fill-rule="evenodd"
d="
M 0 0
h 300
v 300
h -300
Z
M 25 50
h 100
v 100
h -100
Z
M 175 50
h 100
v 100
h -100
Z
"
/>
</svg>
rigdern
- 103
- 4

- 30,033
- 48
- 152
- 225

- 2,525
- 9
- 33
- 47
-
1you mean creating a mask? best thing would split the div up in portions and make the opacity 0 in the part where you want to unmask – Breezer Dec 03 '10 at 11:07
-
Not like a mask, something like a see through lens. – Sussagittikasusa Dec 03 '10 at 11:09
-
k but my answer stays the same split the div up in portions and make the opacity 0 in the part where you want to lens :P – Breezer Dec 03 '10 at 11:10
-
Its going to be really difficult splitting that div up man, there has to be another way. – Sussagittikasusa Dec 03 '10 at 11:12
-
4Is it an option to create a GIF with a transparent area and use this as background-image of the div(background-color of the div has to be set to transparent)? – Dr.Molle Dec 03 '10 at 11:13
-
Yeah, then after that? How do we make it seethrough in a particular area? – Sussagittikasusa Dec 03 '10 at 11:16
-
nope trust me when i say it's not possible, you have to see a page as layers of boxes where you can do anything to the entire box but nothing with just a portion of it – Breezer Dec 03 '10 at 11:24
-
Hmmmm... maybe the background of this div element can be broken into smaller boxes... and I can achieve what I'm looking for. – Sussagittikasusa Dec 03 '10 at 11:27
-
could you possible show us your page and maybe tell us what you want to be able to see through the lens – Breezer Dec 03 '10 at 11:29
-
regarding to my comment above: the transparent area of the background-image will be the area you can see trough. – Dr.Molle Dec 03 '10 at 12:26
10 Answers
CSS box-shadow
is supported in almost all modern browsers, so you can do what you want (I hope, I understood you right) this way:
body {
margin: 0;
padding: 0;
}
.hole {
position: absolute;
left: 50px;
top: 50px;
width: 100px;
height: 100px;
box-shadow: 0 0 0 99999px rgba(0, 0, 0, .8);
}
<img src="http://upload.wikimedia.org/wikipedia/commons/5/51/Fox_Head.jpg" alt="" style="width: 100%;">
<div class="hole"></div>
So, the block will be transparent, and all around it will be highlighted with its shadow.

- 14,077
- 4
- 33
- 43

- 701
- 5
- 8
-
3
-
2
-
1@equinox outline-width appears to max out at 65534px on Chrome version 40.0, so "outline: 65534px solid rgba(0, 0, 0, .8)" is fine, but higher values of outline-width result in no outline. There's a similar, though higher, limit with FF, too. – Paul Pepper Feb 18 '15 at 22:19
-
Outline seems not to support border-radius, it is block. Beware of using accidentally big blur radius eg. 0rem 0rem 4000rem 4000rem hsla(0, 0%, 0%, 0.6). In Mac Chrome Version 41.0.2272.104 (64-bit) causes significant slowness if background has eg. a table with few tens of cells. Scrolling and responsiveness to mouse is slow. Also it causes random rendering errors. Using blur radius 0 or outline is fast. – Timo Kähkönen Apr 04 '15 at 19:50
-
Making a huge box-shadow spread doesn't work on ios - disappears altogether when it exceeds some limit. equinox's solution: `outline: 9999px solid rgba(0, 0, 0, .8);` works great on ios. Although, as Paul Pepper points out, `99999px` probably exceeds an outline limit... but why would anyone want an outline 100,000px??? – sterfry68 Jul 01 '17 at 17:47
-
On iOS Safari I see an upper limit of `box-shadow` combined with `border-radius: 50%` at `951px`. After that, it just disappears. The `outline` combined with `border-radius` does not work for me on iOS. – jkettmann Jul 08 '18 at 08:01
-
1Instead of setting an impossible high size like 99999px, for my use case, `calc(100vw + 100vh)` worked pretty well (also on iOS). – Jefrey Sobreira Santos Sep 02 '19 at 20:28
A new way to solve this, using blend modes, and supporting border-radius, multiple elements... but without support in IE
.back {
background-color: lightblue;
width: 400px;
height: 300px;
background-image: repeating-linear-gradient(45deg, white 0px,lightblue 40px);
}
.base {
position: relative;
left: 10px;
top: 10px;
width: 200px;
height: 200px;
border: solid 1px black;
background-color: white;
mix-blend-mode: hard-light;
}
.hole {
width: 80px;
height: 50px;
margin: 10px;
border: solid 1px red;
border-radius: 10px;
background-color: gray;
}
<div class="back">
<div class="base">
<div class="hole">ONE</div>
<div class="hole">TWO</div>
</div>
</div>

- 61,425
- 11
- 89
- 138
-
This is some great information to know - I had not heard of `mix-blend-mode` beforehand. This should be the accepted answer. – Gershom Maes Oct 07 '15 at 22:56
-
-
@vals, Why is this only working with "gray" color for the Hole (any other color will not create a hole)??? – Gil Epshtain Jun 26 '18 at 15:45
-
@GilEpshtain the **hard-light** blend-mode , when the channel intensity is 0.5 (or 128 in rgb scale), will reproduce the color of the background. gray is 0.5 in all chanels, so it reproduces fully the background – vals Jun 26 '18 at 17:18
-
4It should be noted though that this **significantly decreases font quality** on both Firefox and Chrome (at least on Manjaro Linux) and that any color **other than `white`, `black`, `red`, `blue`, `lime`, `cyan`, `magenta` and `yellow`** become (partly) transparent. This affects not only the background color, but also text, borders, etc. – Aloso Aug 09 '18 at 15:36
-
@vals what would be the solution if you wanted the **base** div to be of any other color, for example pink? also the children? – sima ghoreyshi Dec 04 '21 at 06:09
-
@simaghoreyshi You can not choose any color , only colors with RGB values of 0 or 255 are supported (so, red or green is ok, also yellow, but not pink) – vals Dec 04 '21 at 18:47
You can construct a set of frame divs in the following format:
So, one container div, with no/little style applied to it.
Then a set of 4 'border' divs with style applied to them, leavin the central area transparent.

- 61,249
- 84
- 283
- 456
-
Not what i was looking for, but i guess i can make your answer work. Thanks man. – Sussagittikasusa Dec 03 '10 at 11:44
-
No problem, I'm not sure if there is a way to take a generic div and punch holes in it, I think you have to do it this way I am afraid. – Tom Gullen Dec 03 '10 at 11:47
-
2Google has once created something like that... The hole followed your mouse as it moved over your site. Check http://googlecode.blogspot.com/2009/12/introducing-google-browser-size.html – xtofl Dec 03 '10 at 12:04
-
-
Making this work with round div, round hole (border-radius:50%) will be very hard to implement – Gil Epshtain Jun 26 '18 at 15:34
Found it!
- Parent div with a relative position, a transparent background and hidden overflow.
- Child div with absolute position, with colored, super big borders to fill the background of the parent, and a transparent background.
The hole will be composed of a transparent child, with borders so big they fill up the parent's background. The positioning of the child will depend of the size of the borders. Set a background to whatever is behind the parent, and it will show through!
In this example you can see the red through the yellow faux background (which is actually a huge border).
#parent{overflow:hidden; position:relative;}
#child {position:absolute; border:9000px yellow solid; top:0; left:0;}
http://jsfiddle.net/CarambaMoreno/UrbhS/
What do you think?

- 61
- 5
I designed something on code pen that I think you are/were looking for. I was looking for the same... couldn't find anything so this is what I made

- 39
- 2
You can use a png with alpha channel transparency as the background image of your div.
<div style="background-image:url(pngwithtransparentarea.png);width:100px;height:100px;">
</div>

- 26,427
- 12
- 52
- 69
There's one approach, albeit it can only do mostly rectangular borders, with the following mark-up as a demo:
html:
<div id="wrap">
<div id="frame">
</div>
<img src="http://farm3.static.flickr.com/2232/2299184911_ea1091968b_z.jpg?zz=1" />
</div>
css:
#wrap {
overflow: hidden;
position: relative;
}
#frame {
border: 60px solid #000;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(255,255,255,0.5);
}
While there's no way to truly 'cut' a hole in a div
, there is the possibility of using -webkit-mask-box-image
to apply masks directly to images. Albeit this only works in, so far as I'm aware, Webkit browsers (I know that it's a -webkit
vendor-prefixed property, but I don't believe that there's a -moz
or -o
equivalent, sadly).
Demo using the above, -webkit-mask-box-image
property, at JS Fiddle.

- 249,100
- 51
- 377
- 410
-
Hey David thanks though this is not what i wanted. Suppose your '#wrap', or any outside container had a background color. The code should've been able to penetrate through the image and show the background color of the outside container. – Sussagittikasusa Dec 03 '10 at 11:25
-
@Sussagittikasusa: ah, in which case I may have completely misunderstood your question. – David Thomas Dec 03 '10 at 11:28
The larger issue is not actually the background of the element you want to see through (which would just be background-color:transparent) but instead its ancestor element(s). For instance, a div with a background-color: transparent is still going to look as if it has a white background if its containing element has a white background. The best approach then is to define the background colors at lower levels in the page. For instance, if you want to see through div#see-through and it's a child of div#content which is in between div#header and div#footer, you could give #header and #footer background colors but define #content as transparent. Then assign background colors to the individual sibling elements of #see-through. One more thing: it might be helpful to remember when defining the transparent element that even a transparent element can have "colored" borders, meaning that you might be able to reach into in-between spots without adding extra elements.

- 34
- 1
-
Just asking, is it possible to cut a hole through an element with having the element a background color gradient? – Green Feb 20 '21 at 23:32
After really thinking this through best thing i could come up with is if you use an iframe it could be the "lens" that views whatever you desire but ofcourse it wont work like a real lens but close to

- 10,410
- 6
- 29
- 50
If it's acceptable to use an SVG element instead of a div, SVG provides a flexible mechanism for cutting holes using the fill-rule="evenodd"
attribute. You can create as many transparent regions of any shape as you'd like.
Here's an example that cuts two square holes into a gray square (also available as a JSFiddle):
<img
src="http://upload.wikimedia.org/wikipedia/commons/5/51/Fox_Head.jpg"
style="position: absolute; width: 300px;"
>
<svg style="position: absolute; width: 300px; height: 300px;">
<!--
This `path` element draws 3 squares:
1. A gray 300x300 square
2. A transparent 100x100 square
3. Another transparent 100x100 square
The key mechanism for creating transparent regions in the shape is
`fill-rule="evenodd"`. This attribute affects pixel colors in the following
way. Pick a pixel and draw an infinitely long line in any direction:
- If the line crosses an odd number of lines, the pixel receives the fill
color. In this fiddle, the infinite line extending from any gray pixel
crossed an odd number of lines -- for example, just the line that is the
perimeter of the gray rectangle.
- If the line crosses an even number of lines, the pixel is transparent.
In this fiddle, the infinite line extending from any transparent pixel
crossed an even number of lines -- for example, the perimeters of the
transparent square and the gray square.
-->
<path
fill="grey"
fill-rule="evenodd"
d="
M 0 0
h 300
v 300
h -300
Z
M 25 50
h 100
v 100
h -100
Z
M 175 50
h 100
v 100
h -100
Z
"
/>
</svg>

- 103
- 4