CSS主流布局总结与比较(一)水平居中对齐

作为一个前端开发,常年关注的重点都在JS上,对于CSS没有形成一个系统的知识脉络,趁这个机会总结一下几种主流布局中水平居中对齐的不同实现方案以及方案之间的比较。

父text-align + 子inline-block

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#parent {
width: 100%;
height: 200px;
background-color: aliceblue;
text-align: center;
}

#child {
width: 200px;
height: 200px;
background-color: red;
display: inline-block;
}
</style>
</head>
<body>
<div id="parent">
<div id="child"></div>
</div>
</body>
</html>

原理

text-align

text-align CSS属性定义行内内容(例如文字)如何相对它的块父元素对齐。text-align 并不控制块元素自己的对齐,只控制它的行内内容的对齐。具体的取值范围可参考MDN

display

display 属性可以设置元素的内部和外部显示类型 display types。元素的外部显示类型 outer display types 将决定该元素在流式布局中的表现(块级或内联元素);元素的内部显示类型 inner display types 可以控制其子元素的布局(例如:flow layoutgridflex)。

display 属性使用关键字取值来指定,关键字取值被分为六类:

1
2
3
.container {
display: [ <display-outside> | <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy> ;
}

具体不展开介绍,有兴趣也可以去MDN一个个翻看

简单介绍其中三类:

display-outside

这些关键字指定了元素的外部显示类型,实际上就是其在流式布局中的角色(即在流式布局中的表现)。

这个就是我们常见的并且是这次使用的inline,block之类的

display-inside (en-US)

这些关键字指定了元素的内部显示类型,它们定义了该元素内部内容的布局方式(假定该元素为非替换元素 non-replaced element)。

常见的有flow,flex,table,grid等

display-legacy

CSS 2 对于 display 属性使用单关键字语法,对于相同布局模式的 block 级和 inline 级变体需要使用单独的关键字。常见的就是inline-block,inline-flex

总结

所以综上,为什么这个方案可以生效,首先就是child的display的值为inline-block,是display-outside类型,定义的是它的外部显示类型,也就是针对parent的类型为行内块级元素,这里最主要的是行内,块级元素只是为了让width和height生效,然后parent的text-align的作用就是定义内部元素的对齐方式。

优点

  • 浏览器兼容好,ie6也可以支持,因为text-align和inline-block都是CSS2的内容

缺点

  • text-align具有继承性,也就是子级元素的文本也是居中的,如果你不想子级元素的文本居中,你需要在子集元素中重新设置text-align属性

子table + 子margin

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#parent {
width: 100%;
height: 200px;
background-color: aliceblue;
}

#child {
width: 200px;
height: 200px;
background-color: red;
display: table; // 或者block
margin: 0 auto;
}
</style>
</head>
<body>
<div id="parent">
<div id="child"></div>
</div>
</body>
</html>

原理

display

这里用到的还是上面讲的display,类型是display-inside的table

margin

margin 属性接受 1~4 个值。每个值可以是 ](https://developer.mozilla.org/zh-CN/docs/Web/CSS/length),[,或 auto。取值为负时元素会比原来更接近临近元素。

  • 当只指定一个值时,该值会统一应用到全部四个边的外边距上。
  • 指定两个值时,第一个值会应用于上边和下边的外边距,第二个值应用于左边和右边
  • 指定三个值时,第一个值应用于上边,第二个值应用于右边和左边,第三个则应用于下边的外边距。
  • 指定四个值时,依次(顺时针方向)作为上边右边下边,和左边的外边距。

可取值:

length

以固定值为外边距。

percentage

相对于包含块宽度,以百分比值为外边距。

auto

让浏览器自己选择一个合适的外边距。有时,在一些特殊情况下,该值可以使元素居中。

优点

只需要对子级元素进行设置

缺点

如果子级元素脱离文档流,导致margin属性无效

脱离文档流的方式

  • 浮动
  • 绝对定位
  • 固定定位

子position:absolute + 子transform

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#parent {
width: 100%;
height: 200px;
background-color: aliceblue;
/* 只要不是默认的static就可以 */
position:relative;
}

#child {
width: 200px;
height: 200px;
background-color: red;
position:absolute;
left: 50%;
transform: translateX(-50%);
}
</style>
</head>
<body>
<div id="parent">
<div id="child"></div>
</div>
</body>
</html>

原理

position

CSS **position**属性用于指定一个元素在文档中的定位方式。toprightbottomleft 属性则决定了该元素的最终位置。

  • **定位元素(positioned element)**是其计算后位置属性为 relative, absolute, fixedsticky 的一个元素(换句话说,除static以外的任何东西)。
  • **相对定位元素(relatively positioned element)**是计算后位置属性为 relative 的元素。
  • **绝对定位元素(absolutely positioned element)**是计算后位置属性为 absolutefixed 的元素。
  • 粘性定位元素**(stickily positioned element)**是计算后位置属性为 sticky 的元素。

大多数情况下,heightwidth 被设定为auto的绝对定位元素,按其内容大小调整尺寸。但是,被绝对定位的元素可以通过指定topbottom ,保留height未指定(即auto),来填充可用的垂直空间。它们同样可以通过指定leftright并将width 指定为auto来填充可用的水平空间。

除了刚刚描述的情况(绝对定位元素填充可用空间):

  • 如果 topbottom 都被指定(严格来说,这里指定的值不能为 auto ),top 优先。
  • 如果指定了 leftright ,当 direction设置为 ltr(水平书写的中文、英语)时 left 优先, 当direction设置为 rtl(阿拉伯语、希伯来语、波斯语由右向左书写)时 right 优先。

相对定位的元素并未脱离文档流,而绝对定位的元素则脱离了文档流。在布置文档流中其它元素时,绝对定位元素不占据空间。

绝对定位元素相对于最近的非 static 祖先元素定位。当这样的祖先元素不存在时,则

transform

CSS**transform**属性允许你旋转,缩放,倾斜或平移给定元素。这是通过修改CSS视觉格式化模型的坐标空间来实现的,具体可以看一下MDN

优点

父级元素是否脱离文档流,不影响子级元素居中

缺点

transform是CSS3新特性,需要考虑兼容性