Here's how I would do it. I'll provide step-by-step instructions so it's easier to follow the "magic". :)
The idea is to use a simple square SVG with a viewBox
width and height of 100x100. Then we can position the circle that will be our future hole in the bottom right of the viewBox.
body {
width: 100%;
height: 100vh;
padding: 0; margin: 0;
display: flex;}
#box {
margin: auto;
position: relative;
width: 33%;
height: 200px;
background: url(https://lorempixel.com/400/400/) center/cover;
overflow: hidden;
}
<div id="box">
<svg width="100%" height="100%" viewBox="0 0 100 100">
<rect x="0" y="0" width="100" height="100" fill="#015668"/>
<circle cx="70" cy="70" r="20" fill="black"/><!-- the hole -->
</svg>
</div>
Then we use preserveAspectRatio="xMaxYMax meet"
to tell the renderer that we want the SVG contents in the bottom right corner.
body {
width: 100%;
height: 100vh;
padding: 0; margin: 0;
display: flex;}
#box {
margin: auto;
position: relative;
width: 33%;
height: 200px;
background: url(https://lorempixel.com/400/400/) center/cover;
overflow: hidden;
}
<div id="box">
<svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMaxYMax meet">
<rect x="0" y="0" width="100" height="100" fill="#015668"/>
<circle cx="70" cy="70" r="20" fill="black"/><!-- the hole -->
</svg>
</div>
The next step is make the rectangle wider and start off the left of the viewBox
so that it fills the area of the viewport that is to the left of the SVG. We'll do that by making it start at x="-900"
and be width="1000"
. That means it extends to the left 9X more than the (100 wide) viewBox. That should make it more than wide enough to cater for even the most humongous monitors around.
We will also do the same thing in the vertical direction. Just in case the viewport ever gets tall and skinny. That can happen if you resize the window so that it has narrow width.
body {
width: 100%;
height: 100vh;
padding: 0; margin: 0;
display: flex;}
#box {
margin: auto;
position: relative;
width: 33%;
height: 200px;
background: url(https://lorempixel.com/400/400/) center/cover;
overflow: hidden;
}
<div id="box">
<svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMaxYMax meet">
<rect x="-900" y="-900" width="1000" height="1000" fill="#015668"/>
<circle cx="70" cy="70" r="20" fill="black"/><!-- the hole -->
</svg>
</div>
Finally, we convert this to a mask and apply it to a rectangle that fills the viewport the same way.
body {
width: 100%;
height: 100vh;
padding: 0; margin: 0;
display: flex;}
#box {
margin: auto;
position: relative;
width: 33%;
height: 200px;
background: url(https://lorempixel.com/400/400/) center/cover;
overflow: hidden;
}
<div id="box">
<svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMaxYMax meet">
<defs>
<mask id="mymask">
<rect x="-900" y="-900" width="1000" height="1000" fill="white" fill-opacity="0.9"/>
<circle cx="70" cy="70" r="20" fill="black"/><!-- the hole -->
</mask>
</defs>
<rect x="-900" y="-900" width="1000" height="1000" fill="#015668" mask="url(#mymask)"/>
</svg>
</div>
For a final test. Let's make the "box" bigger to check it is properly responsive. We'll make it 400px high this time. Try resizing the browser windo to check the responsiveness.
body {
width: 100%;
height: 100vh;
padding: 0; margin: 0;
display: flex;}
#box {
margin: auto;
position: relative;
width: 33%;
height: 400px;
background: url(https://lorempixel.com/400/400/) center/cover;
overflow: hidden;
}
<div id="box">
<svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMaxYMax meet">
<defs>
<mask id="mymask">
<rect x="-900" y="-900" width="1000" height="1000" fill="white" fill-opacity="0.9"/>
<circle cx="70" cy="70" r="20" fill="black"/><!-- the hole -->
</mask>
</defs>
<rect x="-900" y="-900" width="1000" height="1000" fill="#015668" mask="url(#mymask)"/>
</svg>
</div>