水平垂直居中在页面的布局中还是会经常用到的,比如讲一个图片水平居中显示?
我们都知道水平居中的时候我们可以使用margin: 0 auto;,但是在垂直方向上使用margin: auto 0;确是无效的。这是为什么呢?
说到这里就设计到宽度计算和高度计算了:
宽度计算
默认的宽度规则是“适应于父级”规则。(是默认,那当然就是所有啦)
W3 CSS 2.1 第十章里为常规流替换和非替换块级元素定义了这个算式:
margin-left + border-left-width + padding-left + width + padding-right + border-right-width + margin-right = width of containing block
这里需要一张盒子模型,借助于盒模型的图片我们可以很清楚的理解宽度的计算方法。
同时为几项auto设置了额外的算法:
- If there is exactly one value specified as ‘auto’, its used value follows from the equality.
- If ‘width’ is set to ‘auto’, any other ‘auto’ values become ‘0’ and ‘width’ follows from the resulting equality.
- If both ‘margin-left’ and ‘margin-right’ are ‘auto’, their used values are equal. This horizontally centers the element with respect to the edges of the containing block.
大致意思就是
- 如果有一个值指定为“自动”,则它的使用值是从等式中提取的。
- 如果“宽度”设置为“自动”,则任何其他“自动”值都将从结果相等中变为“0”和“宽度”。
- 如果“左边的”和“右边的”是“自动的”,它们的使用值相等。这个水平将元素集中在包含块的边上。这就是auto可以水平居中的原因。
对于绝对定位元素,计算公式如下:
left + margin-left + border-left-width + padding-left + width + padding-right + border-right-width + margin-right + right = width of containing block
加入了left和right两个值,依然可以使用margin: 0 auto;来实现水平居中。代码如下:
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
width: 200px; //如果未设置宽度,则宽度默认为父元素的宽度
高度计算
This section also applies to block-level non-replaced elements in normal flow when ‘overflow’ does not compute to ‘visible’ but has been propagated to the viewport.
If ‘margin-top’, or ‘margin-bottom’ are ‘auto’, their used value is 0. If ‘height’ is ‘auto’, the height depends on whether the element has any block-level children and whether it has padding or borders:
The element’s height is the distance from its top content edge to the first applicable of the following:
- the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
- the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child’s bottom margin does not collapse with the element’s bottom margin
- the bottom border edge of the last in-flow child whose top margin doesn’t collapse with the element’s bottom margin
- zero, otherwise
大致意思就是:
本节也适用于在“溢出”未计算为“可见”但已传播到视空间的正常流中的块级未替换元素。
如果“边距顶部”或“边距底部”是“自动”,它们的使用值是0。如果“高度”是“自动”,则高度取决于元素是否有任何块级别的子元素,以及是否有填充或边框:
元素的高度是从它的顶部内容边缘到第一个适用的距离:
- 如果框具有一行或多行的内联格式化上下文,则最后一行框的底部边缘
- 如果子底边距不在元素的底部边缘折叠,那么最后一个子元素的底部(可能是折叠的)边缘的底部边缘。
- 最后一个子元素的底部边界边缘,其顶部边距不会因元素的底部边距而折叠。
- 否则为0
对于绝对定位元素,计算公式如下:
top + margin-top + border-top-width + padding-top + height + padding-bottom + border-bottom-width + margin-bottom + bottom = height of containing block
因此margin-top: auto; margin-bottom: auto;top: 0;bottom: 0;,可以让绝对定位元素垂直居中,代码如下:
position: absolute;
top: 0;
bottom: 0;
margin-top: auto;
margin-bottom: auto;
height: 200px; //如果未设置高度,则宽度默认为父元素的高度
既然使用绝对定位可以实现水平居中和垂直居中,那自然而然就可以实现水平垂直居中,代码如下:
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
width: 200px; //如果未设置宽度,则宽度默认为父元素的宽度
height: 200px; //如果未设置高度,则宽度默认为父元素的高度;如果宽度和高度都未设置,则充满整个父元素。
另外使用该方法也可以实现当子元素的高度的大于父元素,并且仅希望显示父元素垂直方向中间一块的内容(图片多适用)。
下面展示一个例子,如图,我们金希望显示中间的汽车:
html结构:
<div class="container">
<img src="timg.jpg">
</div>
css布局:
* {
margin: 0;
padding: 0;
}
.container {
position: relative;
width: 500px;
height: 135px;
overflow: hidden;
}
img {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
width: 100%;
}
显示结果如图所示: