Invert rounded corner in CSS?

我与影子孤独终老i 提交于 2019-11-26 04:54:33
Chris Burton

Just to update this, it seems you can in multiple ways.

Lea Verou posted a solution

Here is mine using border-image

Using border image

html

<div><img src="https://s3.amazonaws.com/resized-images-new/23292454-E6CD-4F0F-B7DA-0EB46BC2E548" /></div>

css

div {
    width: 200px;           
    border-width: 55px;
    -moz-border-image: url(http://i47.tinypic.com/2qxba03.png) 55 repeat;
    -webkit-border-image: url(http://i47.tinypic.com/2qxba03.png) 55 repeat;
    -o-border-image: url(http://i47.tinypic.com/2qxba03.png) 55 repeat;
    border-image: url(http://i47.tinypic.com/2qxba03.png) 55 repeat;
    margin: 50px auto;   
}

Using radial gradient

Lea Verou's solution

html

<div class="inner-round"></div>

css

.inner-round {
    background-image:
        radial-gradient(circle at 0 0, rgba(204,0,0,0) 14px, #c00 15px),
        radial-gradient(circle at 100% 0, rgba(204,0,0,0) 14px, #c00 15px),
        radial-gradient(circle at 100% 100%, rgba(204,0,0,0) 14px, #c00 15px),
        radial-gradient(circle at 0 100%, rgba(204,0,0,0) 14px, #c00 15px);
}
Gajus

In modern browsers, you can use mask-image:

#aux-container {
  width: 100px;
  height: 100px;
  background: #f00;
  -webkit-mask-image: radial-gradient(circle 10px at 0 0, transparent 0, transparent 20px, black 21px);
}
<div id="aux-container"></div>

http://jsbin.com/eViJexO/1/

Additionally, take a look at http://www.html5rocks.com/en/tutorials/masking/adobe/, which describes how to achieve similar result using mask-box-image.

You can also use and inline svg with a path element:

body{background:url('http://i.imgur.com/RECDV24.jpg');background-size:cover;}
svg{width:30%;}
<svg viewbox="0 0 10 10">
  <path d="M9 1 V9 H1 V3 Q3 3 3 1" fill="#fff"/>
</svg>

In this example, I use a cubic bezier curve for the inverted round edge.

With this approach, you can also fill the shape with an image or gradient:

body{background:url('http://i.imgur.com/RECDV24.jpg');background-size:cover;}
svg{width:30%;}
<svg viewbox="0 0 10 6.7">
  <defs>
    <clipPath id="clip">
      <path d="M9 1 V6.7 H1 V3 Q3 3 3 1" fill="#fff"/>
    </clipPath>
  </defs>
  <image xlink:href="http://i.imgur.com/qi5FGET.jpg" x="0" y="0" height="6.7" width="10" clip-path="url(#clip)"/>
</svg>

Unfortunately, there is currently not a solution based on official or implemented CSS Specs :(

However, as other people have added, there are possible solutions (or cheats?) you can do to achieve the same effect using JS libraries or complex HTML/CSS implementations. I came across this issue whilst looking for a way to make even more complex corners than the OP without using images.

I have filed a bug (Feature Request) over at the webkit site - as there does not appear to be one filed already.

Bug 62458 - Feature Request: Inverse rounded corners

For a plain background-color, you actually can, using pseudo element and box shadow to draw background-color instead, and it will not hide backgrounds of parent's container, you will actually see them through.

What you need is a browser that understands :before/:after and box-shadow :) ...

For IE8 , you can draw hudge borders instead shadows. http://codepen.io/anon/pen/fFgDo

box-shadow approach : http://codepen.io/anon/pen/FwLnd

div {
  margin:2em; /* keep it away from sides to see result */
  padding:2em;/* for test to size it when empty */
  position:relative; /* reference to set pseudo element where you wish */
  overflow:hidden;/* you do not want the box-shadow all over the page */
}
div:before {
  content:'';
  position:absolute;
  width:80px;
  height:80px;
  top:-40px;
  left:-40px;
  border-radius:100%;
  box-shadow:0 0 0 2000px #1D005D;/* here draw the shadow inside its parent , maybe z-index will be required for content */
}


pseudo element can take any shape, and transform via css and set any where in its element to draw kind of holes through : examples : http://codepen.io/gc-nomade/pen/nKAka

This can be done with a radial gradient.

div {
  width: 20vw;
  height: 20vw;
  background: radial-gradient(circle at top left,transparent 4vw, darkblue 4.1vw);
}
<div></div>

Just for fun, additional inverted corners can be added by defining multiple backgrounds - one for each corner:

div {
  width: 40vw;
  height: 40vw;
  position: relative;
  background-color: darkblue;
  --circle: radial-gradient(circle,white 8vw, darkblue 8.1vw);
}
div:before {
  content: '';
  position: absolute;
  width: 100%;
  height: 100%;
  background-image: var(--circle), var(--circle), var(--circle), var(--circle);
  background-size: 18vw 18vw;
  background-position: -40% -40%, 140% -40%, -40% 140%, 140% 140%;
  background-repeat: no-repeat;
}
<div></div>

There are ways you could solve this issue by using just CSS - however it would depend on the colour of your background (if solid its easier) if you have a pattern for background it might be slightly more complex.

I cover a basic example here of how to make an Inverse Border Radius in CSS (here). This uses a trick with the size of Border to use the inside, you might have to do some positioning to get it to work properly however as you can see its possible. Especially if you specify a background-color for each span.

If you want all 4 corners you would have to add a separate class for each span inside your div, and each class would simulate a corner, top left, top right etc.

No. If you have solid background you can probably use css to create the bite.
Otherwise, there isn't anything special you can do beyong using PNGs, much like you'd create round corners before border-radius.

actually there's one way, like this:

<div style="background-color: red;height: 12px; width: 12px;">
    <div style="margin-top: 40px; height: 12px; width: 12px; moz-border-radius-topright: 12px;
        -webkit-border-top-right-radius: 12px; border-top-right-radius: 12px; background-color:#fff">
    </div>
</div>

but as @Domenic says you'll need a solid background, otherwise you'll get this:

<div style=" background-color:#666">
  <div style="background-color: red;height: 12px; width: 12px;">
    <div style="margin-top: 40px; height: 12px; width: 12px; moz-border-radius-topright: 12px;
        -webkit-border-top-right-radius: 12px; border-top-right-radius: 12px; background-color:#fff">
    </div>
</div>

It can be done using after element. check this jsfiddle linkenter code here

No, there is not.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!