水平居中
行内元素
-
如果父级元素是块级元素则直接给父级元素设置 text-align: center;
- This shorthand property sets the text-align-all and text-align-last properties and describes how the inline-level content of a block is aligned along the inline axis if the content does not completely fill the line box. Values other than justify-all or match-parent are assigned to text-align-all and reset text-align-last to auto.
- 此 简写性设置 text-align-all 和 text-align-last 属性,并描述如果内容未完全填满行框,块的行内级内容如何沿行内轴对齐。将 justify-all 或 match-parent 以外的值分配给 text-align-all,并将 text-align-last 重置为 auto。
- 也就是说,这个属性实际上是一个简写属性,他会同时设置 text-align-all 和 text-align-last属性.规范中对可取值的描述中还提到特殊值如
justify-all或match-parent会同时影响这两个子属性,但是如果不是这两个特殊值,那么它将设置text-align-all 属性,并将 text-align-last 重置为 auto. - 但是实际上text-align-all属性并没有被实现,因为在规范中提到了
Authors should use the text-align shorthand instead of this property.作者应使用 text-align 简写属性,而不是此属性。
- 所以使用前提是想要居中的元素的父级元素是块级元素,而元素本身是行内级元素,并且本身没有填满父元素.
<style>
.container {
width: 200px;
height: 200px;
background-color: aquamarine;
}
.item {
width: 50px;
height: 50px;
background-color: bisque;
}
.container {
text-align: center;
}
</style>
<div class="container">
<span class="item">行内元素<span />
</div>
- 基于一,如果父级元素不是块级元素,那么可以先把父级元素设置为块级元素然后父级元素设置 text-align: center;
块级元素
方案一
-
定宽度: 需要谁居中,就给谁设置 margin: 0 auto;
- 没什么好说的,当**
margin: 0 auto;** 应用于块级元素时,margin-left和margin-right会自动计算为相等的值,从而使元素在包含块中水平居中.
- 没什么好说的,当**
<style>
.container {
width: 200px;
height: 200px;
background-color: aquamarine;
}
.item {
width: 50px;
height: 50px;
background-color: bisque;
}
.item {
margin: 0 auto;
}
</style>
<div class="container">
<div class="item">
块级元素
</div>
</div>
- 不定宽度: 默认子元素的宽度和父元素一样,这时需要设置子元素为*display: inline-block; *或 *display: inline; *即将其转换成行内块级/行内元素,给父元素设置 text-align: center;
方案二
使用定位属性,首先设置父元素为相对定位,再设置子元素为绝对定位,设置子元素的left:50% ,即让子元素的左上角水平居中;(子绝父相,以下是子绝父相成立的基础)
-
The box is laid out as for static, then offset from the resulting position. This offsetting is a purely visual effect, and, unless otherwise specified, does not affect the size or position of any other non-descendant box except insofar as it increases the scrollable overflow area of its ancestors. This positioning scheme is called relative positioning.
-
盒子的布局与 static 一样,然后从结果位置偏移。这种偏移是一种纯粹的视觉效果,除非另有说明,否则不会影响任何其他非后代框的大小或位置,除非它增加了其上级的可滚动溢出区域。这种定位方案称为相对定位。
-
The box is taken out of flow such that it has no impact on the size or position of its siblings and ancestors, and does not participate in its parent’s formatting context. Instead, the box is positioned and sized solely in reference to its absolute positioning containing block, as modified by the box’s inset properties, see § 4 Absolute Positioning Layout Model. It can overlap in-flow content or other absolutely positioned elements, and is included in the scrollable overflow area of the box that generates is containing block. This positioning scheme is called absolute positioning.
-
该框已从 flow 中取出,因此它对其同级和上级的大小或位置没有影响,并且不参与其父级的格式设置上下文。 相反,盒子的定位和大小仅参考其绝对定位包含块,由盒子的 inset 属性修改,参见 § 4 绝对定位布局模型。它可以与流中内容或其他绝对定位的元素重叠,并包含在生成 is containing 块的框的可滚动溢出区域中。这种定位方案称为绝对定位。(注,在规范中提到:Box Insets: the top, right, bottom, left, inset-block-start, inset-inline-start, inset-block-end, and inset-inline-end properties)
-
包含块:
For other elements, if the element's position is 'relative' or 'static', the containing block is formed by the content edge of the nearest block container ancestor box.
If the element has 'position: absolute', the containing block is established by the nearest ancestor with a 'position' of 'absolute', 'relative' or 'fixed', in the following way:
- In the case that the ancestor is an inline element, the containing block is the bounding box around the padding boxes of the first and the last inline boxes generated for that element. In CSS 2.1, if the inline element is split across multiple lines, the containing block is undefined.
- Otherwise, the containing block is formed by the padding edge of the ancestor.
- If there is no such ancestor, the containing block is the initial containing block.
对于其他元素,如果元素的位置是 'relative' 或 'static',则包含块由最近的块容器祖先框的内容边缘形成。
如果元素具有 'position: absolute',则包含块由最近的祖先建立,其 'position' 为 'absolute'、'relative' 或 'fixed',方式如下:
- 如果祖先是内联元素,则包含块是为该元素生成的第一个和最后一个内联框的填充框周围的边界框。在 CSS 2.1 中,如果内联元素被拆分为多行,则包含块是 undefined。
- 否则,包含块由祖先的 padding edge 形成。
- 如果没有这样的祖先,则包含块是初始包含块。
-
定宽度: 设置绝对子元素的 *margin-left: 负 元素宽度的一半px; *或者设置transform: translateX(-50%);
<style> .container { width: 200px; height: 200px; background-color: aquamarine; } .item { width: 50px; height: 50px; background-color: bisque; } .container { position: relative; } .item { position: absolute; left: 50%; transform: translateX(-50%); margin-left: -25px; } </style> <div class="container"> <div class="item"> 块级元素 </div> </div> -
不定宽度: 利用css3新增属性transform: translateX(-50%);
方案三:
使用flexbox布局实现(宽度定不定都可以 ,再实现水平垂直居中的部分会介绍)
垂直居中
单行的行内元素
- 只需要设置单行行内元素的"行高等于盒子的高"即可;
多行的行内元素
使用给父元素设置display:table-cell; 和vertical-align: middle; 属性即可;
-
实现的基础:
For table cells, the behavior of align-content: normal depends on the computed value of vertical-align: top makes it behave as start and bottom makes it behave as end; otherwise middle makes it behave as center, and all other values make it behave as baseline. [CSS2] 对于表格单元格,align-content: normal 的行为取决于 vertical-align: top 使其表现为 start,bottom 使其表现为 end;否则,Middle 将使其表现为 Center,所有其他值将使其表现为 Baseline。[CSS2]
注:如果要使用vertical-align对齐,那么必须要设置display:table-cell;因为vertical-align属性只对行内元素和表格单元格元素生效(MDN上还说会对行内块元素生效其实是错的,因为在规范中提到: This shorthand property specifies how an inline-level box is aligned within the line by specifying its alignment baseline type (alignment-baseline), baseline alignment preference (baseline-source), and post-alignment shift (baseline-shift) in a single declaration. 此速记属性通过在单个声明中指定行内级框的对齐基线类型 (alignment-baseline)、基线对齐首选项 (baseline-source) 和对齐后偏移 (baseline- shift) 来指定行内级框在行内的对齐方式。 所以 vertical-align只对行内元素和表格单元格元素生效(上文提到过对于表格单元格,align-content:normal 的行为取决于 vertical-align)
那么严格意义上来说还应该设置 align-content: normal;才能保证这个方案是有效的
块级元素
方案一 使用定位
首先设置父元素为相对定位,再设置子元素为绝对定位,设置子元素的top: 50% ,即让子元素的左上角垂直居中;
定高度: 设置绝对子元素的 *margin-top: -元素高度的一半px; *或者设置transform: translateY(-50%);
不定高度: 利用css3新增属性transform: translateY(-50%);
方案二:使用flexbox布局实现(高度定不定都可以)
使用flexbox布局,只需要给待处理的块状元素的父元素添加属性 display: flex; align-items: center;
水平垂直居中
已知高度和宽度的元素
方案一: 设置父元素为相对定位,给子元素设置绝对定位,top: 0; right: 0; bottom: 0; left: 0; margin: auto;
方案二: 设置父元素为相对定位,给子元素设置绝对定位,left: 50%; top: 50%; margin-left: -元素宽度的一半px; margin-top: -元素高度的一半px;
未知高度和宽度的元素
方案一: 使用定位属性
设置父元素为相对定位,给子元素设置绝对定位,left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%);
方案二: 使用flex实现居中
实现:在容器上加入以下css类.
原理:在flex布局的前提下,
-
justify-content
- 规范中是这样说的:The justify-content property aligns flex items along the main axis of the current line of the flex container. This is done after any flexible lengths and any auto margins have been resolved. Typically it helps distribute extra free space leftover when either all the flex items on a line are inflexible, or are flexible but have reached their maximum size. It also exerts some control over the alignment of items when they overflow the line.
- justify-content 属性沿 flex 容器当前行的主轴对齐 flex 项。这是在解决任何 flexible length 和任何 auto margins 之后完成的。通常,当一行上的所有 flex 项都是不灵活的,或者是灵活的但已达到其最大大小时,它有助于分配剩余的额外可用空间。它还对 items 溢出行时的对齐方式施加一些控制。
- center属性:Flex items are packed toward the center of the line. The flex items on the line are placed flush with each other and aligned in the center of the line, with equal amounts of space between the main-start edge of the line and the first item on the line and between the main-end edge of the line and the last item on the line. (If the leftover free-space is negative, the flex items will overflow equally in both directions.)
- Flex 项将向行的中心打包。该行上的 flex 项彼此齐平放置,并对齐于行的中心,在该行的主起始边缘与该行的第一项之间以及该行的主端边缘与该行的最后一项之间具有相等的间距。(如果剩余的 free-space 为负数,则 flex 项将在两个方向上均匀溢出。
-
align-items
- 规范中是这样说的:
- Flex items can be aligned in the cross axis of the current line of the flex container, similar to justify-content but in the perpendicular direction. align-items sets the default alignment for all of the flex container’s items, including anonymous flex items.
- Flex 内容可以在 Flex 容器当前行的交叉轴上对齐,类似于 justify-content,但方向是垂直的。align-items 设置所有 Flex 容器的项(包括匿名 Flex 项)的默认对齐方式。
- centent属性:The flex item’s margin box is centered in the cross axis within the line. (If the cross size of the flex line is less than that of the flex item, it will overflow equally in both directions.)
- Flex 项的边距框位于线条内的交叉轴中心。(如果 flex 行的交叉大小小于 flex 项的交叉大小,它将在两个方向上均匀溢出。
所以flex可以实现居中是因为规范中规定了在flex布局下justify-content定义主轴对齐方式,而align-items定义了交叉轴的对齐方式,而center值对应中心对齐方法.
.container {
display: flex;
justify-content: center;
align-items: center;
}