垂直居中, 在 CSS 中是一个老生常谈的问题, 面试的时候也会时常被提及. 所以, 今天我们就来聊聊 9 种不同的居中方法.
有常见的 flex,transform,absolute 等等. 也有 CSS3 的网格布局. 还有伪元素的方法, 是的, 你没有看错,::after 和 ::before 也可以实现居中.
1,flex
大家的第一反应, 可能就是 flex 了. 因为它的写法够简单直观, 兼容性也没什么问题. 是手机端居中方式的首选.
- <div class="wrapper flex-center">
- <p>horizontal and vertical</p>
- </div>
- .wrapper {
- width: 300px;
- height: 300px;
- border: 1px solid #ccc;
- }
- .flex-center {
- display: flex;
- justify-content: center;
- align-items: center;
- }
利用到了 2 个关键属性: justify-content 和 align-items, 都设置为 center, 即可实现居中.
需要注意的是, 一定要把这里的 flex-center 挂在父级元素, 才能使得其中 唯一的 子元素居中.
2,flex + margin
这是 flex 方法的变种. 父级元素设置 flex, 子元素设置 margin: auto;. 可以理解为子元素被四周的 margin "挤" 到了中间.
- <div class="wrapper">
- <p>horizontal and vertical</p>
- </div>
- .wrapper {
- width: 300px;
- height: 300px;
- border: 1px solid #ccc;
- display: flex;
- }
- .wrapper> p {
- margin: auto;
- }
- 3,transform + absolute
这个组合, 常用于图片的居中显示.
- <div class="wrapper">
- <img src="test.png">
- </div>
- .wrapper {
- width: 300px;
- height: 300px;
- border: 1px solid #ccc;
- position: relative;
- }
- .wrapper> img {
- position: absolute;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
- }
当然, 也可以将父元素 wrapper 的相对定位, 移入子元素 img 中, 替换掉绝对定位. 效果是一样的.
4,table-cell
利用 table 的单元格居中效果展示. 与 flex 一样, 需要写在父级元素上.
- <div class="wrapper">
- <p>horizontal and vertical</p>
- </div>
- .wrapper {
- width: 300px;
- height: 300px;
- border: 1px solid #ccc;
- display: table-cell;
- text-align: center;
- vertical-align: middle;
- }
5,absolute + 四个方向的值相等
使用绝对定位布局, 设置 margin:auto;, 并设置 top,left,right,bottom 的 值相等即可 (不一定要都是 0).
- <div class="wrapper">
- <p>horizontal and vertical</p>
- </div>
- .wrapper {
- width: 300px;
- height: 300px;
- border: 1px solid #ccc;
- position: relative;
- }
- .wrapper> p {
- width: 170px;
- height: 20px;
- margin: auto;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- }
这种方法一般用于弹出层, 需要设置弹出层的宽高.
6,writing-mode
这个方法可以改变文字的显示方向, 比如让文字的显示变为垂直方向.
- <div class="wrapper">
- <div class="wrapper-inner">
- <p>horizontal and vertical</p>
- </div>
- </div>
- .wrapper {
- width: 300px;
- height: 300px;
- border: 1px solid #ccc;
- writing-mode: vertical-lr;
- text-align: center;
- }
- .wrapper> .wrapper-inner {
- writing-mode: horizontal-tb;
- display: inline-block;
- text-align: center;
- width: 100%;
- }
- .wrapper> .wrapper-inner> p {
- display: inline-block;
- margin: auto;
- text-align: left;
- }
兼容性上还有些小瑕疵, 但大部分浏览器, 包括手机端已支持 writing-mode 的写法了.
7,grid
像表格一样, 网格布局让我们能够按行或列来对齐元素. 然而在布局上, 网格比表格更可能做到或更简单.
- <div class="wrapper">
- <p>horizontal and vertical</p>
- </div>
- .wrapper {
- width: 300px;
- height: 300px;
- border: 1px solid #ccc;
- display: grid;
- }
- .wrapper> p {
- align-self: center;
- justify-self: center;
- }
但它在兼容性上不如 flex, 特别是 IE 浏览器, 只支持 IE10 及以上.
8,::after
伪元素也能用来实现居中么? 感觉还是挺神奇的, 看下面这个例子:
- <div class="wrapper">
- <img src="test.png">
- </div>
- .wrapper {
- width: 300px;
- height: 300px;
- border: 1px solid #ccc;
- text-align: center;
- }
- .wrapper::after {
- content: '';
- display: inline-block;
- vertical-align: middle;
- height: 100%;
- }
- .wrapper> img {
- vertical-align: middle;
- }
水平方向很好理解. 垂直方向, 可以理解为 ::after 把 img 往下拉到了中间.
9,::before
另一种是配合 font-size: 0; 共同施展的魔法.
- <div class="wrapper">
- <img src="test.png">
- </div>
- .wrapper {
- width: 300px;
- height: 300px;
- border: 1px solid #ccc;
- text-align: center;
- font-size: 0;
- }
- .wrapper::before {
- display: inline-block;
- vertical-align: middle;
- font-size: 14px;
- content: '';
- height: 100%;
- }
- .wrapper> img {
- vertical-align: middle;
- font-size: 14px;
- }
font-size: 0; 的神秘之处在于, 可以消除标签之间的间隙. 另外, 因为伪元素搭配的, 都是最基础的 CSS 写法, 所以不存在兼容性的风险.
总结
今天共介绍了 9 种居中的方法. 像 flex,absolute,grid, 这些常用的方法往往可以在工作中, 帮我们解决布局的问题. 而像 writing-mode,::after,::before, 这些神奇的特性仿佛帮我们掀开了 CSS 魔法大陆的一角, 让人神往, 忍不住想去探索更多.
自己是一个 6 年的前端工程师, 希望本文对你有帮助!
这里推荐一下我的前端学习交流扣 qun:731771211 , 里面都是学习前端的, 如果你想制作酷炫的网页, 想学习编程. 自己整理了一份 2019 最全面前端学习资料, 从最基础的 html+CSS+JS[炫酷特效, 游戏, 插件封装, 设计模式] 到移动端 HTML5 的项目实战的学习资料都有整理, 送给每一位前端小伙伴, 每天分享技术
点击: 加入
来源: http://www.jianshu.com/p/5445b0a66166