查看: 2799|回复: 0

[HTML代码] 前端知识 | CSS小技巧-自适应椭圆

发表于 2018-1-22 08:00:06

背景知识:

border-radius 属性的基本用法。

难题:

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




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

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

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

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



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

解决方案:

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




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



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

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



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



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

扩展:border-radius 的简写方式



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



图1.5

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



图1.6


小花絮:

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


海说软件会持续推出前端教学课程、技术干货。


-END-





上一篇:小程序第一天
下一篇:小程序第二天
回复

使用道具 举报