ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
> 原文出处:http://www.w3cplus.com/css3/css-secrets/inner-rounding.html ## 问题 有些时候,我们只希望容器的内部边框是圆角的,但是外部轮廓线要是矩形的,如下图所示: ![内凹圆角](https://box.kancloud.cn/2015-10-01_560cdc0d7e385.png "内凹圆角") *图1注:一个具有轮廓线的容器,而它的圆角只在容器的内部* 目前,这个有趣的设计用得还不是很多。使用两个元素实现这种效果就太平庸了: ~~~ <div class="something-meaningful"><div> I have a nice subtle inner rounding, don’t I look pretty? </div></div> .something-meaningful { background: #655; padding: .8em; } .something-meaningful > div { background: tan; border-radius: .8em; padding: 1em; } ~~~ 这么做的效果还不错,但会强迫我们使用两层标签,而实际上我们只需要一层。那么是否有方法只使用一层就实现这种效果呢? ## 解决方案 之前使用两层标签的解决方案很灵活,可以让我们充分利用 `background` 的特性。比如,我们希望边框不只是纯色的,也有可能是带有噪点的纹理,那么使用上面的方法很简单就可以做到。不过,当我们的边框只是纯色时,有一种方法可以只使用一层元素实现相同的效果,下面就是代码: ~~~ background: tan; border-radius: .8em; padding: 1em; box-shadow: 0 0 0 .6em #655; outline: .6em solid #655; ~~~ 你能猜到这段代码的效果吗?它所表现的效果: ![内凹圆角](https://box.kancloud.cn/2015-10-01_560cdc0dbd545.png "内凹圆角") *图2注:为一个圆角元素添加轮廓线* 在这里我们将会充分利用 `outline` 不受元素的圆角影响,而元素的阴影受圆角影响的特性来完成这一效果。因此,如果我们将`outline` 置于图层顶部,那么 `box-shadow` 就会弥补 `outline` 在角落上的空隙: ![内凹圆角](https://box.kancloud.cn/2015-10-01_560cdc0de8d12.png "内凹圆角") *图3注:使用 `box-shadow` 属性包围圆角,并且不设置任何偏移和模糊效果* 所以组合使用它们就可以实现最终的效果。下图中的阴影和 `outline` 被设置成了不同的颜色,这是为了让大家看的更明白。 ![内凹圆角](https://box.kancloud.cn/2015-10-01_560cdc0e2f4ad.png "内凹圆角") *图4注:这里的轮廓线之所以使用黑色,阴影之所以使用洋红色,是为了让大家看清其中的原理;值得注意的是轮廓线在所有图层的最上方* 注意,我们无需让阴影的范围等于 `outline` 的宽度,只需让阴影足以覆盖间隙即可。实际上,如果让 `outline` 的宽度和阴影的范围相同,在某些浏览器中会发生一些渲染问题,所以我建议使用比 `outline` 稍小一些的阴影。这也提出了新的问题:弥补间隙的最小阴影应该是多少? 为了回答这个问题,我们需要使用学校里学到的勾股定理来计算直角三角形的各边变长。勾股定理指出,最长边等于其他两边的平方和,由此可知,如果这两条边都等于 `a`,那么最长边就等于![](https://box.kancloud.cn/2015-10-01_560cdc136b7d0.png)。 你可能会惊讶中学学到的理论竟然和我们的内部圆角效果相关,那么你可以查看一下图: ![内凹圆角](https://box.kancloud.cn/2015-10-01_560cdc13ac456.png "内凹圆角") *图5注:如果边框半径是`r`,那么圆心到罗廓线边角的最长距离就是![](https://box.kancloud.cn/2015-10-01_560cdc13e7476.png),这意味着阴影最小的扩散范围应该是![](https://box.kancloud.cn/2015-10-01_560cdc142b063.png)。* 它很好地解释了勾股定理是如何应用到这里的。在我们的这个示例中,`border-radius` 是 `.8em`,所以最小的阴影范围是![](https://box.kancloud.cn/2015-10-01_560cdc149ee8f.png)。在这里我们只需要将它约取为 `.34em` 的阴影范围。为了避免重复计算,你可以直接取圆角半径的一半,这样就已经足够用了![](https://box.kancloud.cn/2015-10-01_560cdc14bb5ba.png)。 请注意,这种计算方法并不是没有限制的:对于这里要实现的效果,我们阴影半径必须比 `outline` 的宽度要小,同时还要大于![](https://box.kancloud.cn/2015-10-01_560cdc14e3e84.png)(这里的 `r` 表示 `border-radius`)。这意味着如果 `outline` 的宽度小于![](https://box.kancloud.cn/2015-10-01_560cdc14e3e84.png)那么我们就无法实现实现这种效果了。