事件起因

最初是网友的一个提问,来自于我的知识星球社区:

有关CSS的overflow和border-radius的那些事,你的圆角被覆盖了吗?-LMLPHP

说实话,不得不佩服这个网友的眼力,这么小的细节都能发现。不过这也正是 FineUI 一直前进的动力,来自社区的监督和促进。

从截图上看,貌似圆角部分被内部节点覆盖了。换句话说:外部的圆角没有截断内部的元素!

由于这位网友测试的是 Cupertino 主题,圆角只有 6px,不大明显:

有关CSS的overflow和border-radius的那些事,你的圆角被覆盖了吗?-LMLPHP

换成 Le Frog 主题,这个问题就更加突出了:

有关CSS的overflow和border-radius的那些事,你的圆角被覆盖了吗?-LMLPHP

分析问题

对于这个问题,有几种可选的解决办法:

1. 去除窗体控件的圆角边框,毕竟操作系统的窗体都是直角的,这个应该也无可厚非(只不过这个改动和之前不一致,肯定会勾起部分用户的不满情绪)

2. 给内部节点元素也加上圆角边框,防止内部节点的覆盖父节点的圆角边框

第二个方式倒是可行的方案,在浏览器调试工具中尝试如下:

有关CSS的overflow和border-radius的那些事,你的圆角被覆盖了吗?-LMLPHP

由于外层节点 .f-panel 拥有 CSS 样式类 f-corner-all:

.f-corner-all {
border-radius: 6px;
}

这里给内部的 .f-panel-header 增加一个样式类 f-corner-top:

.f-corner-top {
border-top-right-radius: 6px;
border-top-left-radius: 6px;
}

似乎已经完美解决这个问题了。

其实不然,由于窗体内部的结构比较复杂,比如存在底部工具栏的情况(底部工具栏又可能有多个):

有关CSS的overflow和border-radius的那些事,你的圆角被覆盖了吗?-LMLPHP

因此,判断哪个元素位于最下面,是正文元素,还是某个工具栏控件,就是一个麻烦事。

并且还存在用户动态显示隐藏工具栏的情况,这就更增加了复杂度。

所以这个问题我迟迟没有动手修改。

直到有一天,我突然发现,同是 Cupertino 主题,下拉菜单的圆角边框是正常的,不信你来看(单田芳说):

有关CSS的overflow和border-radius的那些事,你的圆角被覆盖了吗?-LMLPHP

解决问题

我似乎看到了问题解决的希望,同一个主题,有个地方正常,有的地方不正常,是是否比较两者的差异了!

经过仔细对比,问题逐步浮出水面,却原来下拉菜单有这么个CSS属性:

有关CSS的overflow和border-radius的那些事,你的圆角被覆盖了吗?-LMLPHP

.f-menu {
overflow: auto;
}

而窗体控件没有定义 overflow 属性,我们看下浏览器缺省的 overflow 属性:

有关CSS的overflow和border-radius的那些事,你的圆角被覆盖了吗?-LMLPHP

原来,如果未定义 overflow 属性,那么节点的这个属性默认值是 visible(有点出乎意料,我还以为是 auto 呢)。

现在好了,既然比较出差异,应用这个改变即可(为了便于观察,我们把 border-radius 改为 12px):

有关CSS的overflow和border-radius的那些事,你的圆角被覆盖了吗?-LMLPHP

问题解决!

小结

所有BUG都是如此,未解决之前看似洪水猛兽,找到根源之后却是纸老虎。不过关键在于解决问题的方法和途径,中间所历经的过程才是最宝贵的。

You are not along

这篇文章似乎已经解决,但是到底为什么会这么呢?

为什么 border-radius 和 overflow: auto(或者hidden)配合起来才好使呢?

我相信大部分我能遇到的问题,别人已经遇到过并给出解决方案,很多时候我们不能通过正确的检索找到之前那个遇到相同问题的人。

不过这次我很幸运,找到了完全相同的一篇文章:https://stackoverflow.com/questions/8582176/should-border-radius-clip-the-content

分享在此:

<div class="progressbar">
<div class="buffer"></div>
</div>
.progressbar { height: 5px; width: 100px; border-radius: 5px; }
.buffer { width: 25px; height: 5px; background: #999999; }

作者遇到相同的问题:容器定义了border-radius,但是内容还是超出了容器的圆角定义。

最后,作者抛出了这个疑惑:这不是关于如何修正它,而是关于它是否应该像这样工作的问题?

回答更精彩:

最终给出的结论:

为了让子节点不超出容器圆角边框,容器的overflow属性必须是除visible之外的其他值(比如 auto, hidden, scroll...)

04-22 10:31