7

前端知识 | CSS小技巧-自适应椭圆

 4 years ago
source link: https://my.oschina.net/u/4271269/blog/4814987
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
前端知识 | CSS小技巧-自适应椭圆 - osc_wip0vvls的个人空间 - OSCHINA - 中文开源技术交流社区

背景知识:

border-radius 属性的基本用法。

你可能注意到过,给任何正方形元素设置一个足够大的 border-radius,就可以把它变成一个圆形。所用到的 CSS 代码如下所示:   

9477865-09e72fa1417d1459.png

9477865-9b460c82c0806bac.png

图1.1给元素设置固定宽高以及一半长度的 border-radius,可以得到一个圆形

你可能还注意到了,如果指定任何大于 100px 的半径,仍然可以得到一个圆形。规范特别指出了这其中的原因:

“当任意两个相邻圆角的半径之和超过 borderbox 的尺寸时,用户代理必须按比例减小各个边框半径所使用的值,直到它们不会相互重叠为止。”——CSS 背景与边框(第三版)(http://w3.org/TR/css3-background/#corner-overlap)

不过,我们往往不愿意对一个元素指定固定的宽度和高度,因为我们希望它能根据其内容自动调整并适应,而内容的长短不可能在事先就知道。即使是在设计一个静态网站的时候(元素的内容可以预先确定),我们也可能需要在某个时刻改变其内容;或者我们为它准备了一款尺寸略有差异的回退字体,而不同字体对相同内容的渲染结果很可能是不同的。在这个案例中,我们通常期望达到这个效果:如果它的宽高相等,就显示为一个圆;如果宽高不等,就显示为一个椭圆。可是,我们前面的代码并不能满足这个期望。当宽度大于高度时,我们得到的形状如图1.2所示。那我们到底能不能用 border-radius 来产生一个椭圆,甚至是一个自适应的椭圆呢?

9477865-97ee14f39803aede.png

图1.2在前面的圆形示例中,当高度小于宽度时发生的情况;border-radius 所产生的圆形用虚线标示。

解决方案:

说到 border-radius,有一个鲜为人知的真相:它可以单独指定水平和垂直半径,只要用一个斜杠(/)分隔这两个值即可。这个特性允许我们在拐角处创建椭圆圆角(参见图1.3)。因此,如果我们有一个尺寸为 200px×150px 的元素,就可以把它圆角的两个半径值分别指定为元素宽高的一半,从而得到一个精确的椭圆:

9477865-e19698ceee9d861a.png

9477865-e949345e26c12df2.png

图1.3一个容器设置了不相等的水平和垂直 border-radius;拐角处的弧线现在呈现出椭圆的形状,这个椭圆的水平和垂直半径就是我们为 border-radius 指定的值,在图中用虚线标示。

9477865-99c79c688bb1afa5.png

图1.4通过非对称的 border-radius 曲线来创建一个椭圆。

我们可以在图1.4中看到结果。但是,这段代码存在一个很大的缺陷:只要元素的尺寸发生变化,border-radius 的值就得跟着改。我们在图3-5中可以看到,当元素的尺寸变为 200px×300px 时,如果 border-radius 没有跟着改变,会发生什么后果。因此,如果我们的元素尺寸会随着它的内容变化而变化,这就是一个问题了。难道我们真的走投无路了吗?其实,border-radius 这个属性还有另外一个鲜为人知的真相,它不仅可以接受长度值,还可以接受百分比值。这个百分比值会基于元素的尺寸进行解析,即宽度用于水平半径的解析,而高度用于垂直半径的解析。这意味着相同的百分比可能会计算出不同的水平和垂直半径。因此,如果要创建一个自适应的椭圆,我们可以把这两个半径值都设置为50%:

a.png

由于斜杠前后的两个值现在是一致的(即使它们最终可能会被计算为不同的值),我们可以把这行代码进一步简化为:

a.png

最终,只需要这一行代码,我们就可以得到一个自适应的椭圆了。

扩展:border-radius 的简写方式

a.png

延伸一句代码半椭圆:border-radius: 100% 0 0 100%/50%;即可形成如图1.5所示的半椭圆

a.png

延伸一句代码实现1/4椭圆:border-radius: 100% 0 0 0; 即可形成如图1.6所示的1/4椭圆

a.png图1.6

为什么叫 border-radius?可能有人会奇怪,border-radius 到底由何得名。这个属性并不需要边框来参与工作,似乎把它叫作 corner-radius 更贴切一些。这个名字乍听起来确实让人摸不着头脑,其实原因在于 border-radius 是对元素 borderbox 进行切圆角处理的。当元素没有边框时,可能还看不出差异;当它有边框时,则以边框外侧的拐角作为切圆角的基准。边框内侧的圆角会稍小一些(严格来说内角半径将是 max(0,border-radius-border-width))。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK