理解CSS Shapes的引用框
本文由大漠根据Razvan Caliman的《Understanding Reference Boxes for CSS Shapes》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明原作者相关信息http://razvancaliman.com/writing/css-shapes-reference-boxes/。
——作者:Razvan Caliman
——译者:大漠
CSS Shapes是用来定义内容环绕的路径,这些路径都是通过形状函数来定义,比如:circle()
、 ellipse()
、 inset()
或 polygon()
,他们都被定位在一个虚拟盒子(virtual box)中,也就是引用框(reference box)。
引用框定义了形状的坐标系统,因此它影响了形状如何绘制和定位。他有四种引用框可供选择:margin-box
, padding-box
, border-box
和 content-box
。每种引用框都会产生不同的结果。请继续往下阅读,了解他们是如何工作。
我们以内容围绕在一个圆形形状周围为例。我们将使用百分比来定义圆形形状的半径,来观察引用框对形状产生的影响。
.shape{
shape-outside: circle(50%);
float: left;
width: 100px;
height: 100px;
}
特别声明:本文中所有示例,参考与教程制作,如果您希望浏览DEMO的效果,请使用Webkit Nightly和Chrome Canary浏览器。如无特别说明,下面所有示例都只能在这两种浏览器下浏览。
margin-box
如里未显式的声明,CSS Shapes的引用框默认为margin-box
。上面的形状声明相当于:
shape-outside: circle(50%) margin-box;
得出的效果:
margin-box
引用框的意思,形状的虚拟框定位在元素margin
的外边缘。坐标系统的原点在这个框的左上角,X轴从左向右,Y轴从上向下。
在我们的示例中并没有设置margin
,所以margin-box
引用框并没有超出元素内容区域。形状的坐标系统原点还是在元素的左上角。
在这一点上,圆的半径为50%,实际就是50px(宽和高的一半)。
当给形状指定margin
时变化:
.shape{
margin: 50px;
shape-outside: circle(50%);
float: left;
width: 100px;
height: 100px;
}
设置margin:50px
后,margin-box
引用框在元素的四周向外扩展了50px
。基于该元素的尺寸,引用框的尺寸变成200px * 200px
。
圆的半径50%实际长度应该是100px,原点也在内容区域之外,在margin
生成的盒子的左上角处。
示例对应的变化如下图所示:
使用margin-box
引用框时,内容围绕形状会超出元素的实际尺寸区域。
margin和Shapes
它是了解所有引用框定义形状坐标系统,但实际上只有形状使用margin-box
引用框非常重要。这意味着使用margin-box
引用框剪切的形状会大于其他引用框的形状。因此,使用margin
可用以增加绘制图形的区域。
border-box
正如其名所暗示,border-box
引用框限制形状的坐标系统定义在元素边框的外边缘。在这种情况之下,形状可能会与元素边框重叠,如果元素设置了margin
,形状可以超越元素的边框。
.shape{
border: 25px solid pink;
shape-outside: circle(50%) border-box;
float: left;
width: 100px;
height: 100px;
}
添加了25px的实线边框后,默认情况下,元素所有方向都变大了,引用框将变成150px * 150px
,(宽度 + 25px * 2)、(高度 + 25px * 2),而圆的半径50%,实际就相当于75px。
对应的引用盒子示意图:
然而,如果设置box-sizing:border-box;
(注:不同的属性)。不同的盒模型计算方法,盒子的大小不会改变,只是元素内容区域宽度变小。在这种情况之下,引用框的大小始终是100px * 100px
,而圆半径50%实际上就是50px。
.shape {
border: 25px solid pink;
box-sizing: border-box;
shape-outside: circle(50%) border-box;
float: left;
width: 100px;
height: 100px;
border-radius: 50%;
}
类似padding-box
,如果使用了margin
,可以帮助border-box
引用框的形状与元素保持一定的间距。
如果有必要让形状与元素边框重叠在一起或者形状跟着元素边框变化一起变化,我们就可以使用border-box
引用框。
padding-box
padding-box
引用框约束形状坐标系统在元素内距的外边缘。
来看一个简单的示例,将形状的引用框指定为padding-box
:
.shape{
padding: 25px;
shape-outside: circle(50%) padding-box;
float: left;
width: 100px;
height: 100px;
}
设置了padding:25px;
之后,如果你不修改box-sizing
的值,使用浏览器默认值content-box
,那么元素在所有方向都会增加25px
的宽度。
在这个示例中,引用框变成了150px * 150px
(width + 25px * 2),(height + 25px * 2)。圆形半径50%,实际就是75px。形状的坐标原点也在元素内盒(padding-box
)左上角。
对应的引用盒子示意图:
如果设置box-sizing:border-box;
,浏览器将会改变元素的CSS盒模型模式,浏览器会从整体宽度中减去内距,从而使元素的内容区域的实际宽度变小。在这个示例中,引用框大小始终会保持在100px * 100px
,而圆的半径50%,实际长度就是50px。
在这两个方案中都可以通过maring
来调整形状和元素之间的位置。
当你有必要让内容与主元素有部分重叠时,就可以使用box-sizing:border-box
。
box-sizing是CSS3的一个新属性,可以通过这个属性来修改CSS的盒模型模式,其主要包括:
content-box
和border-box
。详细的介绍请猛击这里。
content-box
content-box
引用框限制了形状坐标系统在元素的内容区域内。
这是一个非常少见的,显式设置元素宽度,而高度由自己的内容来控制。这种引用框生成的形状直接受到元素的内容影响。
来看看有关于content-box
引用框的两个示例:
.shape{
shape-outside: circle(50%) content-box;
float: left;
width: 100px;
height: 100px;
}
显式设置引用框两个维度的值:同时设置了引用框的宽度和高度。就算添加了padding
和border
,改变了元素尺寸大小,但引用框仍然使用的是初始定义的尺寸。
.shape {
padding: 25px;
border:25px solid rgba(22,222,22,.5);
shape-outside: circle(50%) content-box;
float: left;
width: 100px;
height: 100px;
border-radius: 50%;
}
对应的引用盒子示意图:
当使用box-sizing:border-box;
,减去padding
和border
的值,引用框剩下的可用表示是完全相同的。如果该运算导致引用框剩余的面为零或负值,将不会显示形状,因为没有地方绘制形状。
.shape {
box-sizing:border-box;
padding: 25px;
border:25px solid rgba(22,222,22,.5);
shape-outside: circle(50%) content-box;
float: left;
width: 100px;
height: 100px;
border-radius: 50%;
}
可能还有一种情况,只定义一个方向的维度,引用框只受其中一方面的限制。
.shape{
shape-outside: circle(50%) content-box;
float: left;
width: 100px;
/* height: 100px; */
}
请注意,现在显式的注释掉了height
的设置。现在content-box
引用框取决于元素内容。不同的字体大小值和相对单位都会影响引用框。
尺寸大小可变的引用框
为了能更好的说明问题,到目前为止,示例中使用的都是一个正方形元素。这样一来,圆的半径刚好上正方形元素宽度一半。
然而,给circle()
和ellipse()
的半径使用百分比作单位,相对来说要复杂一些。可以使用这样的一个公式:
sqrt(width的二次方 +height的二次方)/sqrt(2)
这是一种特殊的情况,对于circle()
和ellipse()
的半径,而其他形状,比如polygon()
是不受影响的。
对于content-box
引用框只影响一个或两个维度时,这个公式变得有点弱智。值得注意的是,这是一种可变化的引用框,而不仅是content-box
引用框。
从上图可以看出,图形圆不会触及到content-box
的顶部和底部边缘,而是扩展出左边和右边的边缘。出现这种现像有两个原因:
- 根据上面的公式,算出元素的尺寸
- 没有显式定义圆的圆心在哪个位置,所以是默认的坐标系统的坐标中心(本例中是该元素对角线的交点)
乍一看,使用content-box
引用框麻烦蛮多的。然而,这确实是一个有效的用例,逐渐剖析了形状。这意味着可以创建一个形状,他是可见的所需的形状,并且会随着内容的增加而改变。
想象一下,使用polygon()
创建一个侧面有锯齿的形状,而且元素内容在这个形状侧面。CSS Shapes是没有repeat
的属性。使用content-box
引用框,可以让形状根据内容实现形状重复的效果。
记住,margin-box
引用框实际上是剪切出超大的形状。如果元素周围设置margin
,只要设置了margin-box
引用框,形状有可能会超出content-box
引用框。
从引用框创建形状
它可能跳过形状函数,从元素的引用框创建形状。当使用边界做为border-radius
时,这非常有用,因为该属性会根据引用框影响形状。
.shape{
border-radius: 50px;
shape-outside: margin-box;
float: left;
width: 100px;
height: 100px;
}
border-radius
自身就对元素进行了剪切,但它并影响围绕他的浮动——它仍然是矩形。添加shape-outside: margin-box;
(请注意,没有形状函数)。浮动的元素仍然接触元素的border-radius
。
很大程度上,所有引用框工作正如前面定义的边界的半径,但是结合也要考虑特殊情况。
跳过形状函数和当元素根据border-radius
剪切的元素根据引用框推断出形状是非常有用的。
使用border-radius
创建形状看起来并不是复杂的事情,甚至是微不足道。但Lea Verou在她的演讲中,出色的解释了这个属性。
参考
下面的表格提供如何计算引用框的参考
reference box | box-sizing: cotnent-box | box-sizing: border-box |
---|---|---|
content-box |
width + height | width + height |
padding-box |
width + height + padding | width + height - padding |
border-box |
width + height + padding + border | width + height - padding - border |
margin-box |
width + height + padding + border + margin | width + height - padding - border + margin |
结论
引用框可以帮助我们控制CSS Shapes的位置和大小。
他们抽出了一些复杂的坐标系统,不需要手动的定义每个元素的尺寸,变得没那么抽像。这有助于在多设备上实现适合终端的形状。
非常感谢Alan Stearns和Sara Soueidan审核这篇文章。
译者手语:整个翻译依照原文线路进行,并在翻译过程略加了个人对技术的理解。如果翻译有不对之处,还烦请同行朋友指点。谢谢!
如需转载烦请注明出处:
英文原文:http://razvancaliman.com/writing/css-shapes-reference-boxes/
中文译文:https://www.fedev.cn/css3/css-shapes-reference-boxes.html
jordans for sale epic