CSS 如何在盒子内部及其边框上制作圆角?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4839613/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 23:35:32  来源:igfitidea点击:

How to make round corners to both inside of a box and its border?

cssrounded-corners

提问by linkyndy

I guess the title is kind of hard to understand, so I'll explain. I am trying to achieve this effect:

我想标题有点难以理解,所以我会解释一下。我试图达到这种效果:

enter image description here

在此处输入图片说明

(a box which has rounded corners and its border, which also has rounded borders).

(一个有圆角的盒子,它的边框也有圆角的边框)。

I've managed to do this, by using the background-clipproperty:

通过使用该background-clip属性,我设法做到了这一点:

enter image description here

在此处输入图片说明

(rounded corners for border but notfor inner box)

(边框的圆角,但不是内框)

The question is, how can I achieve rounded corners for the inner box?

问题是,如何实现内盒的圆角?

Thank you!

谢谢!

EDIT

编辑

The HTML I am using:

我正在使用的 HTML:

<header class="body template-bg template-border radius-all">
        <nav>
            <ul>
                <li><a href="#">Link 1</a></li>
                <li><a href="#">Link 2</a></li>
                <li><a href="#">Link 3</a></li>
                <li><a href="#">Link 4</a></li>
            </ul>
        </nav>
    </header>

And the CSS:

和 CSS:

.radius-all {
  border-radius: 10px;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
}

.template-bg {
  background: #FFF;
  -moz-background-clip: padding;
  -webkit-background-clip: padding;
  background-clip: padding-box;
}

.template-border {
  border: 5px solid rgba(255, 255, 255, 0.2);
}

采纳答案by Gio Borje

Inner border calculations

内边界计算

First, you'll need to remove -vendor-background-clip: padding-boxor set them to border-boxthe default in order to achieve the inner border radius.

首先,您需要删除-vendor-background-clip: padding-box它们或将它们设置为border-box默认值以实现内边框半径。

The inner border radius is calculated as the difference of the outer border radius (border-radius) and the border width (border-width) such that

内边界半径计算为外边界半径 ( border-radius) 和边界宽度 ( border-width)的差值,使得

inner border radius = outer border radius - border width

inner border radius = outer border radius - border width

Whenever the border-widthis greater than the border-radius, the inner border radius is negative and you get some awkward inverted corners. Currently, I don't believe there is a property for adjusting the inner-border-radius, so you'll need to calculate it manually.

border-width大于 时border-radius,内边界半径为负数,并且您会得到一些尴尬的倒角。目前,我认为没有用于调整 的属性inner-border-radius,因此您需要手动计算它。

In your case:

在你的情况下:

inner border radius = 6px - 5px = 1px

inner border radius = 6px - 5px = 1px

Your new CSS should be:

你的新 CSS 应该是:

.radius-all { border-radius: 6px; -moz-border-radius: 6px; -webkit-border-radius: 6px; }
.template-bg { background: #FFF; }
.template-border { border: 5px solid rgba(255, 255, 255, 0.2); }

Simply subtract the border-radius(6px) values from the border-widthvalue (5px) in order to achieve your desired inner-border-radius:

只需border-radiusborder-width值 (5px) 中减去(6px) 值即可获得所需的内边界半径:



Code that works for me

对我有用的代码

Tested on Firefox 3.x, Google Chrome, and Safari 5.0

在 Firefox 3.x、Google Chrome 和 Safari 5.0 上测试

 .radius-all { border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; }
.template-bg { background: #FFF; }
.template-border { border: 5px solid rgba(0, 0, 0, 0.2); } /* Note that white on white does not distinguish a border */


Adding color overlays in JavaScript

在 JavaScript 中添加颜色叠加

<script type="text/javascript">
    var bodyBgColor = document.getElementsByTagName('body')[0].style.backgroundColor;;

    // insert opacity decreasing code here for hexadecimal

    var header = document.getElementsByTagName('header')[0];
    header.style.backgroundColor = bodyBgColor;
</script>

I'm not entirely sure how to do hexadecimal arithmetic in JavaScript but I'm sure you can find an algorithm in Google.

我不完全确定如何在 JavaScript 中进行十六进制算术,但我相信您可以在 Google 中找到一种算法。



Applying General Borders

应用通用边框

Are you using a separate box <div>for your border through its backgroundproperty? If so, you'll need to apply border-radiusand its vendor specific properties on both the border box and the inner box:

您是否<div>通过其background属性为边界使用单独的框?如果是这样,您需要border-radius在边框框和内框上应用及其供应商特定属性:

<div id="border-box" style="border-radius: 5px;">
    <div id="inner-box" style="border-radius: 5px;">
    </div>
</div>

A much more efficient way would simply have the inner-box manage its own border:

一种更有效的方法是让内盒管理自己的边框:

<div id="inner-box" style="border: 4px solid blue; border-radius: 5px">
    <!-- Content -->
</div>

CSS-wise, you could just declare a .rounded-borderclass and apply it to every box that will have rounded borders:

在 CSS 方面,您可以声明一个.rounded-border类并将其应用于每个具有圆形边框的框:

.rounded-borders {
    border-radius: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    -khtml-border-radius: 5px;
}

And apply the class to any boxes that will have rounded borders:

并将该类应用于任何具有圆形边框的框:

<div id="border-box" class="rounded-borders">
    <div id="inner-box" class="rounded-borders">
    </div>
</div>

For a single box element, you'll still be required to declare the border size in order to be shown:

对于单个框元素,您仍然需要声明边框大小才能显示:

<style type="text/css">
    #inner-box { border: 4px solid blue; }
</style>

<div id="inner-box" class="rounded-borders">
</div>

回答by nickb

Another solution is to have matching inner and outer borders combined with border-radiusis to "fake" the border using the <spread-radius>value of the box-shadowproperty. This produces a solid shadow which can easily pass for a regular border.

另一种解决方案是将匹配的内边框和外边框相结合,border-radius并使用属性<spread-radius>值“伪造”边框box-shadow。这会产生一个实心阴影,可以很容易地通过常规边框。

For instance, to achieve a 4px border and a 4px white border radius, try this:

例如,要实现 4px 边框和 4px 白色边框半径,请尝试以下操作:

/* rounded corners */
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;

/* drop shadow */
-webkit-box-shadow: 0px 0px 0px 4px #fff;
-moz-box-shadow: 0px 0px 0px 4px #fff;
box-shadow: 0px 0px 0px 4px #fff;

If you want to add a "real" drop shadow to the entire container, you can simply chain your shadow statements like so:

如果你想给整个容器添加一个“真实”的阴影,你可以像这样简单地链接你的 shadow 语句:

/* drop shadow */
-webkit-box-shadow: 0px 0px 0px 4px rgba(255,255,255,1.0),
        1px 1px 8px 0 rgba(0,0,0,0.4);
-moz-box-shadow: 0px 0px 0px 4px rgba(255,255,255,1.0),
        1px 1px 8px 0 rgba(0,0,0,0.4);
box-shadow: 0px 0px 0px 4px rgba(255,255,255,1.0),
        1px 1px 8px 0 rgba(0,0,0,0.4);

Note:Keep in mind here that the order of the statements is the order in which it will be rendered.

注意:请记住,语句的顺序就是它的呈现顺序。

The only thing to beware of is that the initial "faux border" will overlap the first X pixels (where X is the width of the border) of any shadow you want beneath it (and combine, if you're using RGBa opacity on it below 100%.)

唯一需要注意的是,初始的“人造边框”将与您想要在其下方的任何阴影的第一个 X 像素(其中 X 是边框的宽度)重叠(如果您在其上使用 RGBa 不透明度,则合并)低于 100%。)

So it won't work in allsituations, but it'll get the majority. I use this pretty frequently when regular borders are not ideal.

所以它不会在所有情况下都有效,但它会得到大多数。当常规边框不理想时,我经常使用它。

回答by Leo Wu

Since there is no such thing as inner-border-radiusfor CSS, the browsers default it to border-radius - border-width. If you don't like that, the typical solution is to create two divs with borders to mimic the inner border radius but this solution brings in more design into the html. It is also a pain if it's a common border template used through out the site.

由于没有inner-border-radiusCSS这样的东西,浏览器默认它为border-radius - border-width. 如果您不喜欢那样,典型的解决方案是创建两个带边框的 div 以模仿内边框半径,但此解决方案为 html 带来了更多设计。如果它是整个站点使用的通用边框模板,那也是一种痛苦。

I managed to figure a way to keep it all in css by producing the inner div using :afterand content: "". So for your case it would be:

我设法找到了一种方法,通过使用:afterand生成内部 div 将其全部保存在 css 中content: ""。因此,对于您的情况,它将是:

.template-border {
    position: relative;
    border-radius: 5px;
    background-color: #000;
    border: 10px solid #000;
    z-index: -2;
}

.template-border:after {
    content: "";
    display: block;
    position: absolute;
    width: 100%;
    height: 100%;
    border-radius: 5px;
    background-color: #FFF;
    z-index: -1;
}

回答by Zsolti

Based on Leo Wu's idea, here it is my solution:

基于Leo Wu的想法,这是我的解决方案:

.my-div
{
  background-color: white;
  border: solid 20px black;
  border-radius: 10px;
  box-shadow: 0 0 10px black;
  height: 100px;
  left: 30px;
  position: relative;
  top: 20px;
  width: 200px;
}
.my-div:before
{
  background-color: white;
  border-radius: 5px;
  content: "";
  display: block;
  height: calc(100% + 20px);
  left: -10px;
  position: absolute;
  top: -10px;
  width: calc(100% + 20px);
  z-index: 1;
}
.some-content
{
  height: calc(100% + 20px);
  left: -10px;
  position: relative;
  top: -10px;
  width: calc(100% + 20px);
  z-index: 3;
}
.some-header
{
  background-color: green;
  border-radius: 5px 5px 0 0;
  height: 30px;
}
<html>
 <body>
  <div class="my-div">
   <div class="some-content">
    <div class="some-header">my title</div>
    <div>some other content</div>
   </div>
  </div>
 </body>
</html>

回答by Shaun McCran

You need to have two div elements, one inside the other, and use a cross browser rounded corner css, like this:

您需要有两个 div 元素,一个在另一个内,并使用跨浏览器圆角 css,如下所示:

.small-rounded {
    border: 1px solid ##000;
    -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px;
    -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px;
    -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px;
    -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px;
    border-radius: 5px;
}

回答by Daniel

The problem is not the coding of the CSS but the mathematics of a circle. Essentially your border-inner-radius(I know this property does not exist) is equal to the border-radius- border-width.

问题不在于 CSS 的编码,而是圆的数学。基本上你的border-inner-radius(我知道这个属性不存在)等于border-radius- border-width

Quite simply work out what you want your inner radius to be and then add the width of the border to achieve the desired effect.

很简单地计算出您想要的内半径,然后添加边框的宽度以达到所需的效果。

border-inner-radius+ border-width= border-radius

border-inner-radius+ border-width=border-radius

回答by Nick Steele

Most of the solutions on this page are from the web stone ages (before 2013 - i.e. even before IE11).

此页面上的大多数解决方案来自网络石器时代(2013 年之前 - 即甚至在 IE11 之前)。

Since IE11, the way to do this is easy...

从 IE11 开始,这样做的方法很简单......

Just in case someone is Googling for this answer after 2013 (it's almost 2020 today) and got sent here, here is the most simple, compatible, and easy way to do this, even if you need to support IE11...

以防万一有人在 2013 年之后(今天快 2020 年)在谷歌上搜索这个答案并被发送到这里,这里是最简单、兼容和最简单的方法,即使您需要支持 IE11...

(Feel free to change the px values for the look you want, or better yet, use variables and transpile with Stylus or SASS)

(随意更改 px 值以获得您想要的外观,或者更好的是,使用变量并使用 Stylus 或 SASS 进行转换)

Example HTML...

示例 HTML...

<div class="wrapper">
    <div class="content">
        your content goes here
    </div>
</div>

Example CSS...

示例 CSS...

.wrapper {
    border-radius: 25px;
    border: solid 25px blue;
    background-color: blue;
}
.content {
    border-radius: 10px;
    background-color: white;
}

...Presto. enter image description here

......快。 在此处输入图片说明

回答by Temani Afif

Another idea is to consider multiple radial-gradientto simulate the inner radius and you can control the outer and inner radius like you want without the need of any extra element:

另一个想法是考虑多个radial-gradient来模拟内半径,您可以随意控制外半径和内半径,而无需任何额外元素:

.box {
  width:150px;
  height:150px;
  margin:10px;
  border:10px solid red;
  border-radius:10px; /* Outer Radius*/
  background:
   radial-gradient(farthest-side at bottom right,transparent 98%,red 100%) top left,
   radial-gradient(farthest-side at top    right,transparent 98%,red 100%) bottom left,
   radial-gradient(farthest-side at bottom left ,transparent 98%,red 100%) top right,
   radial-gradient(farthest-side at top    left ,transparent 98%,red 100%) bottom right,
   blue;
  background-size:25px 25px; /* inner Radius*/
  background-repeat:no-repeat;
  background-origin:padding-box;
}
<div class="box">

</div>

You can also have different values for each side:

您还可以为每一侧设置不同的值:

.box {
  width:150px;
  height:150px;
  margin:10px;
  border:10px solid red;
  border-radius:10px; /* Outer Radius*/
  background:
   radial-gradient(farthest-side at bottom right,transparent 98%,red 100%) top left / 30px 30px,
   radial-gradient(farthest-side at top    right,transparent 98%,red 100%) bottom left / 20px 20px,
   radial-gradient(farthest-side at bottom left ,transparent 98%,red 100%) top right / 50px 50px,
   radial-gradient(farthest-side at top    left ,transparent 98%,red 100%) bottom right/ 10px 10px,
   blue;
  background-repeat:no-repeat;
  background-origin:padding-box;
}
<div class="box">

</div>

回答by Machine Pereere

The best and fastest way is to do this

最好和最快的方法是这样做

.curve {
  width : 300px;
  height: 100px;
  border: 4px solid black;
  border-bottom-left-radius: 20px;
  border-bottom-right-radius: 20px;
  border-top-right-radius: 20px;
  border-top-left-radius: 20px;
} 
<div class='curve'></div>

回答by Volomike

You need to make the border-radius to a value greater than the border-width until you start to see a curve. It's not a set formula to set the border-radius of +1px greater than border-width. However, it's going to be a positive value, definitely. You need to experiment in the different browsers where you need this until you see the smallest possible border-radius value that works good enough for you in most browsers. (Some browsers may not support this.) For instance, in Google Chrome, I set a border-width to 10px, but had to set the border-radius to 13px before I started to see a semblance of an inner border curve, while 15px worked even better.

您需要将 border-radius 设置为大于 border-width 的值,直到您开始看到曲线。设置+1px的border-radius大于border-width并不是一个固定公式。然而,它肯定会是一个正值。您需要在需要它的不同浏览器中进行试验,直到您看到在大多数浏览器中都对您足够好用的最小可能的 border-radius 值。(有些浏览器可能不支持。)例如,在谷歌浏览器中,我将边框宽度设置为 10px,但必须将边框半径设置为 13px,然后我才开始看到内边框曲线的外观,而 15px效果更好。