Inverted' Border-Radius Possible

Inverted' border-radius possible?

Not using the native border-radius. As mentioned on MDN "Negative values are invalid". You could definitely look for a library out there which does this for you automatically (though I find the approach taken in Philip's suggested library to be particularly outdated).

Using pure CSS I have come up with an approach. The idea is to add 4 extra elements inside your container, set their background to the same color as your page background (so this will not let page content underneath filter through – for that, you’d need SVG masking or similar), and to position them in such a way that they lie just outside of the element itself. We then apply a border-radius which gives the affect:

#main {    margin: 40px;    height: 100px;    background-color: #004C80;    position: relative;    overflow: hidden;}
#main div { position: absolute; width: 20px; height: 20px; border-radius: 100%; background-color: #FFF;}
.top { top: -10px; }.bottom { bottom: -10px; }.left { left: -10px; }.right { right: -10px; }
<div id="main">    <div class="top left"></div>    <div class="top right"></div>    <div class="bottom left"></div>    <div class="bottom right"></div></div>

How to use inverted border-radius?

Just use before and add an element to style

div {
position: relative;
display: inline-block;
background-color: blue;
width: 10em;
height: 10em;
}

div::before{
display: block;
position: relative;
content: '';
width: 10%;
top: 15%;
height: 70%;
background-color: white;
border-top-right-radius: 1em;
border-bottom-right-radius: 1em;
}
<div></div>

CSS - How to make inverted border-bottom with curved edges?

You need to make use of border-top instead of border-bottom

.border-curve {
width: 20em;
height: 10em;
background: transparent;
border-top: 1px solid hsl(180deg 100% 52%);
border-radius: 0.35em;
}

body {
background: gray;
}
<div class="border-curve"></div>

CSS inverse border-radius outside element's bounding box to create a mobile phone notch design

There are four ways to do that, from simple to more complex:

  • Adding 2 pseudoelements with radial-gradient.

    Simplest and well-supported solution. Probably the one I would use.

  • Adding 2 pseudoelements with mask-image (same as above, but with worse support).

    Quite similar, code-wise, to the previews one, but with really bad support (needs browser prefixes for those that support it).

  • Adding 2 pseudoelements with a border-radius, box-shadow and background: transparent.

    Needs a bit more code, but it looks a bit smoother, at least on Chrome Version 78.0.3904.108, so maybe it's worth it for you, although the difference is minimal. In any case, the shapes you can do can't be as complex as with the previous alternatives, especially if you want to work with ellipses rather than circles, like in this other question: https://stackoverflow.com/a/59278227/3723993.

  • Using an SVG.

    I think the SVG solution is not worth it here, but it would be a good alternative for more complex shapes or animated/transitioning shapes.

Here you can check the first 3 solutions:

const notch = document.getElementById('notch');const button = document.getElementById('button');const xrayCheckbox = document.getElementById('xrayCheckbox');const xrayLabel = document.getElementById('xrayLabel');const label = document.getElementById('label');
const solutions = [{ name: 'pseudoelements + radial-gradient', classes: 'notch notch-gradient'}, { name: 'pseudoelements + box-shadow', classes: 'notch notch-shadow'}, { name: 'pseudoelements + mask-image', classes: 'notch notch-mask'}];
let currentSolutionIndex = 0;let currentSolution = solutions[currentSolutionIndex];let xRayEnabled = false;
button.onclick = () => { currentSolutionIndex = (currentSolutionIndex + 1) % solutions.length; currentSolution = solutions[currentSolutionIndex]; updateLabels();};
xrayCheckbox.onchange = () => { xRayEnabled = xrayCheckbox.checked; updateLabels();};
function updateLabels() { if (xRayEnabled) { notch.className = `${ currentSolution.classes }-xray`; label.innerText = `${ currentSolution.name } (X-Ray)`; xrayLabel.innerText = 'Disable X-Ray'; } else { notch.className = currentSolution.classes; label.innerText = currentSolution.name; xrayLabel.innerText = 'Enable X-Ray'; }}
body {  position: relative;  overflow: hidden;  height: 100vh;  margin: 0;}
.phone { width: 420px; height: 800px; padding: 12px 12px 24px; position: absolute; top: 32px; left: 50%; transform: translate(-50%, 0); background: #000; box-shadow: 0 8px 32px 0 rgba(0, 0, 0, .5); border-radius: 16px;}
.screen { height: 100%; overflow: hidden; position: relative; background: #FFF; border-radius: 8px;}
.viewport { height: 100%; position: relative; overflow-x: hidden; overflow-y: scroll;}
.notch { top: 12px; left: 50%; width: 24px; height: 12px; z-index: 10; position: absolute; transform: translate(-50%, 0); background: #000; border-bottom-left-radius: 1024px; border-bottom-right-radius: 1024px;}
.notch::before,.notch::after { top: 0; width: 8px; height: 8px; content: ""; position: absolute;}
.notch-gradient-xray,.notch-shadow-xray,.notch-mask-xray { background: red;}
/* RADIAL GRADIENT SOLUTION */
.notch-gradient::before { left: -6px; background: radial-gradient(circle at bottom left, transparent 0, transparent 70%, black 70%, black 100%);}
.notch-gradient::after { right: -6px; background: radial-gradient(circle at bottom right, transparent 0, transparent 70%, black 70%, black 100%);}
.notch-gradient-xray::before { left: -6px; background: green radial-gradient(circle at bottom left, transparent 0, transparent 70%, cyan 70%, cyan 100%);}
.notch-gradient-xray::after { right: -6px; background: green radial-gradient(circle at bottom right, transparent 0, transparent 70%, cyan 70%, cyan 100%);}
/* BOX-SHADOW SOLUTION */
.notch-shadow::before { left: -6px; background: transparent; border-radius: 0 8px 0 0; box-shadow: 0 -4px 0 0 #000;}
.notch-shadow::after { right: -6px; background: transparent; border-radius: 8px 0 0 0; box-shadow: 0 -4px 0 0 #000;}
.notch-shadow-xray::before { left: -6px; background: green; border-radius: 0 8px 0 0; box-shadow: 0 -4px 0 0 cyan;}
.notch-shadow-xray::after { right: -6px; background: green; border-radius: 8px 0 0 0; box-shadow: 0 -4px 0 0 cyan;}
/* MASK SOLUTION */
.notch-mask::before { left: -6px; background: #000; -webkit-mask-image: radial-gradient(circle at bottom left, transparent 0, transparent 70%, black 70%, black 100%);}
.notch-mask::after { right: -6px; background: #000; -webkit-mask-image: radial-gradient(circle at bottom right, transparent 0, transparent 70%, black 70%, black 100%);}
.notch-mask-xray::before { left: -6px; background: cyan; -webkit-mask-image: radial-gradient(circle at bottom left, transparent 0, transparent 70%, black 70%, black 100%);}
.notch-mask-xray::after { right: -6px; background: cyan; -webkit-mask-image: radial-gradient(circle at bottom right, transparent 0, transparent 70%, black 70%, black 100%);}
.camera { top: 0; left: 50%; width: 12px; border: 4px solid #33244A; height: 12px; position: absolute; transform: translate(-50%, -50%); background: #304A58; border-radius: 1024px; box-sizing: border-box;}
#button { font-family: monospace; font-size: 16px; padding: 8px 16px; margin: 32px auto 16px; background: transparent; border: 2px solid black; display: block; border-radius: 2px;}
#xray { font-family: monospace; font-size: 16px; padding: 0 16px; text-align: center; display: block; margin: 0 0 16px; display: flex; align-items: center; justify-content: center;}
#xrayCheckbox { margin: 0 8px 0 0;}
#label { font-family: monospace; font-size: 16px; padding: 0 16px; text-align: center;}
<div class="phone">  <div id="notch" class="notch notch-gradient">    <div class="camera"></div>  </div>
<div class="screen"> <div class="viewport"> <button id="button">Change Solution</button> <label id="xray"> <input id="xrayCheckbox" type="checkbox" /> <span id="xrayLabel">Enable X-Ray</span> </label> <div id="label">pseudoelements + radial-gradient</div> </div> </div></div>

Inverted border-radius?

You can add a gray square with the length of the radius you want there, and then put a white rounded div (circle) on top of it, the div having the width twice the length of the gray square.

See here: http://plnkr.co/edit/RxMMvqS74aMq018P5Jsq?p=preview (I reused your corner div, and added a circle div on top)

Experiment with the width/height of the corner and circle divs and the circle div's radius to get different rounding effects.

Here is a more rounded version: http://plnkr.co/edit/uwRZHCzAxEcQSQ2Elu6u?p=preview

Creating inverted border radius and box-shadow together

You can use a reduced code considering gradient coloration: