codecamp

内凹圆角

原文出处:http://www.w3cplus.com/css3/css-secrets/inner-rounding.html

问题

有些时候,我们只希望容器的内部边框是圆角的,但是外部轮廓线要是矩形的,如下图所示:

内凹圆角

图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;

你能猜到这段代码的效果吗?它所表现的效果:

内凹圆角

图2注:为一个圆角元素添加轮廓线

在这里我们将会充分利用 outline 不受元素的圆角影响,而元素的阴影受圆角影响的特性来完成这一效果。因此,如果我们将outline 置于图层顶部,那么 box-shadow 就会弥补 outline 在角落上的空隙:

内凹圆角

图3注:使用 box-shadow 属性包围圆角,并且不设置任何偏移和模糊效果

所以组合使用它们就可以实现最终的效果。下图中的阴影和 outline 被设置成了不同的颜色,这是为了让大家看的更明白。

内凹圆角

图4注:这里的轮廓线之所以使用黑色,阴影之所以使用洋红色,是为了让大家看清其中的原理;值得注意的是轮廓线在所有图层的最上方

注意,我们无需让阴影的范围等于 outline 的宽度,只需让阴影足以覆盖间隙即可。实际上,如果让 outline 的宽度和阴影的范围相同,在某些浏览器中会发生一些渲染问题,所以我建议使用比 outline 稍小一些的阴影。这也提出了新的问题:弥补间隙的最小阴影应该是多少?

为了回答这个问题,我们需要使用学校里学到的勾股定理来计算直角三角形的各边变长。勾股定理指出,最长边等于其他两边的平方和,由此可知,如果这两条边都等于 a,那么最长边就等于

你可能会惊讶中学学到的理论竟然和我们的内部圆角效果相关,那么你可以查看一下图:

内凹圆角

图5注:如果边框半径是r,那么圆心到罗廓线边角的最长距离就是

它很好地解释了勾股定理是如何应用到这里的。在我们的这个示例中,border-radius 是 .8em,所以最小的阴影范围是

请注意,这种计算方法并不是没有限制的:对于这里要实现的效果,我们阴影半径必须比 outline 的宽度要小,同时还要大于那么我们就无法实现实现这种效果了。

灵活的背景定位
条纹背景
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }