【问题标题】:How to make round corners to both inside of a box and its border?如何在盒子内部及其边框上制作圆角?
【发布时间】:2011-06-17 21:33:54
【问题描述】:

我想标题有点难以理解,所以我会解释一下。 我正在努力实现这种效果:

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

我已经通过使用background-clip 属性成功地做到了这一点:

(边框圆角,内框

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

谢谢!

编辑

我正在使用的 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>

还有 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);
}

【问题讨论】:

    标签: css rounded-corners


    【解决方案1】:

    内边框计算

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

    内边框半径计算为外边框半径 (border-radius) 和边框宽度 (border-width) 之差,这样

    inner border radius = outer border radius - border width

    border-width 大于border-radius 时,内边框半径为负数,您会得到一些尴尬的倒角。目前,我不相信有一个属性可以调整inner-border-radius,所以你需要手动计算。

    在你的情况下:

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

    你的新 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); }
    

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


    适合我的代码

    在 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 */
    

    在 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>
    

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


    应用一般边框

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

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

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

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

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

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

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

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

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

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

    【讨论】:

    • 感谢您的回答。我目前的解决方案与您建议的解决方案非常相似,但它不起作用。我还应该尝试什么?
    • @linkyndy,感谢您发布标记,您面临的问题是内部边界计算。
    • 非常感谢您的澄清。我设法实现了“内部”边框,但仅适用于 Firefox 和 IE9。在 Chrome、Safari 和 Opera 中,“内”框没有任何圆角,锐边几乎穿过边框的圆角。有什么“补救措施”吗?值得一提的是,我需要背景剪辑,因为我的边框与背景颜色相同,只是不透明度较低。如果我将背景剪辑设置为边框框,则将不再看到边框。再次感谢您。
    • 在 Chromium 和 Safari 上测试,它们运行良好,您是否更改了 -webkit-border-radius 并删除了 -webkit-background-clip?我不认为外边界​​半径、内边界半径和颜色可以在没有一些黑客(或 JavaScript)的情况下同时控制。如果你真的想要在边界半径上灵活地重叠颜色,我会选择 Shaun McCran 的答案,只需使用两个 &lt;div&gt; 元素,否则需要使用 JavaScript 来控制复杂的行为。您可以随时向 w3 和 CSS 工作组施压,要求他们添加更多 CSS 属性。
    • 我改变了半径,正如我所说,我需要背景剪辑。所以,你说除了两个&lt;div&gt;s,没有别的办法了吗?我本来想要更干净的东西。但我想知道为什么 FF 和 IE 正确显示这些边框而其他三个不正确...这些黑客是什么?也许他们会在我的情况下工作。
    【解决方案2】:

    另一种解决方案是将匹配的内部和外部边框与border-radius 结合使用,即使用box-shadow 属性的&lt;spread-radius&gt; 值“伪造”边框。这会产生一个实心阴影,可以轻松通过常规边框。

    例如,要实现 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;
    

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

    /* 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);
    

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

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

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

    【讨论】:

    • 感谢您的回复! :)
    • 这实际上是完美的答案!谢谢!
    【解决方案3】:

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

    我设法通过使用 :aftercontent: "" 生成内部 div 来将其全部保存在 css 中。因此,对于您的情况,它将是:

    .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;
    }
    

    【讨论】:

    • 吴先生的绝妙答案
    • 很好的答案。但我必须添加“顶部:0;左侧:0;”到:之后。此外,使用现代 CSS,您可以使用诸如 --arb-border-color 之类的变量来自定义任何类型的边框。
    【解决方案4】:

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

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

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

    【讨论】:

      【解决方案5】:

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

      从IE11开始,这个方法就很简单了……

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

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

      示例 HTML...

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

      示例 CSS...

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

      ...转眼间。

      【讨论】:

      • 就是这个。
      【解决方案6】:

      基于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>

      【讨论】:

        【解决方案7】:

        你需要有两个 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;
        }
        

        【讨论】:

        • 感谢您的回答,但我想通过使用单个元素来实现。
        • 记录在案,-moz-border-radius-webkit-border-radius 工作。
        • 现在都可以了,只是边框宽度和半径的比例问题。
        【解决方案8】:

        另一个想法是考虑多个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>

        你也可以为每一边设置不同的值:

        .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>

        【讨论】:

          【解决方案9】:

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

          .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;
          } 
          &lt;div class='curve'&gt;&lt;/div&gt;

          【讨论】:

            【解决方案10】:

            今天我遇到了这个“问题”。我的解决方案使用两个 div 并将内部 div 重叠在外部 div 上。

            我的解决方案的一个好处是它不会改变背景颜色(它可以是透明的)。

            可以通过修改outer-border类来控制外边框半径,用inner-border类修改内边框。

            .outer-border {
              border: 10px solid #20b2aa;
              border-radius: 5px;
              display: flex;
              flex-direction: column;
              min-height: 100px;
            }
            
            .inner-border, .inner-border-evidence {
              flex: 1;
              border: 10px solid #20b2aa;
              border-radius: 30px;
              margin: -9px;
            }
            
            .inner-border-evidence {
              border-color: #0a3b8a;
            }
            <div class="outer-border">
              <div class="inner-border">
              </div>
            </div>
            <br />
            <p>Here you can see how the inner div overlaps the outer div.</p>
            <div class="outer-border">
              <div class="inner-border-evidence">
              </div>
            </div>

            【讨论】:

              【解决方案11】:

              您需要将边框半径设置为大于边框宽度的值,直到您开始看到曲线。将 +1px 的边框半径设置为大于边框宽度不是固定公式。但是,这绝对是一个积极的价值。您需要在需要此功能的不同浏览器中进行试验,直到您看到在大多数浏览器中对您来说足够好的最小边框半径值。 (某些浏览器可能不支持。)例如,在 Google Chrome 中,我将边框宽度设置为 10 像素,但必须将边框半径设置为 13 像素,然后才开始看到内部边框曲线的外观,而 15 像素效果更好。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2022-12-03
                • 2010-09-24
                • 1970-01-01
                • 1970-01-01
                • 2021-02-15
                • 1970-01-01
                • 2017-12-30
                • 2015-07-05
                相关资源
                最近更新 更多