css 实现移动端居中布局常见方式(面试题)
布局可不仅仅只是把数据整齐的罗列在页面上这么简单,一个合适的布局可以令用户的操作非常顺畅。同时在不同的场景下也应选择不同的布局,如果选错布局的话很可能会导致用户对页面的操作不那么的丝滑,哪怕最初呈现出来的数据都是一样的。
由于移动端的屏幕并不像电脑屏幕那么大,而且长宽比也有很大的区别,所以造就了移动端布局与 PC 端布局有着很大的不同,那么接下来我们就来看一下各式各样的常见布局。
居中布局
绝对定位实现
居中布局通常分为两种,一种是固定宽高,另一种是非固定宽高。
固定宽高很好理解,顾名思义就是宽高都写死。 而非固定宽高通常都是靠里面的内容来撑起盒子的高度,内容时多时少。
这两种方式也造就了不一样的技术实现,绝对定位法适合固定宽高:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> /* 清除默认样式 */ * { padding: 0; margin: 0; } /* 令 html 和 body 全屏显示, 并有一个灰色背景 */ html, body { height: 100%; background: gray; } /* 先在父元素上设置相对定位 */ body { position: relative } .center { /* 绝对定位 */ position: absolute; /* 上下左右全部为 0 */ top: 0; right: 0; bottom: 0; left: 0; /* 给定宽高 */ width: 70%; height: 25%; /* 令外边距自动填充 */ margin: auto; /* 白色背景 */ background: white; } </style> </head> <body> <div class="center"></div> </body> </html>
效果如下:
- 如果不给定宽高,盒子将会和父元素一样大,因为绝对定位上下左右都是
0
,意为紧贴着父元素的边。 - 给了固定宽高,但没写
margin
的话盒子会固定在左上角,因为top
和left
的优先级更高。 - 给了
margin: auto;
的话,浏览器会自动填充边距,令其居中。 - 此种实现方式优点是兼容性很好,几乎没用到任何
CSS
的新特性,全部都是经典属性。
绝对定位 + 负边距
此种方法也是适用于固定宽高:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> /* 清除默认样式 */ * { padding: 0; margin: 0; } /* 令 html 和 body 全屏显示, 并有一个灰色背景 */ html, body { height: 100%; background: gray; } /* 先在父元素上设置相对定位 */ body { position: relative } .center { /* 绝对定位 */ position: absolute; /* 上方和左方为 50% */ top: 50%; left: 50%; /* 给定宽高 */ width: 300px; height: 200px; /* 上外边距为负的给定高度的一半 */ margin-top: -100px; /* 左外边距为负的给定宽度的一半 */ margin-left: -150px; /* 白色背景 */ background: white; } </style> </head> <body> <div class="center"></div> </body> </html>
效果如下:
⚠️ 注意,”绝对定位+负边距”这种方法不适合那种宽百分之多少、高百分之多少这种相对单位,取而代之的是具体的数值。
因为边距的百分比和宽高的百分比相对的不是同一参考物,它是相对于父元素的宽来计算的,这点要注意。
绝对定位 + 平移
有时中间盒子的内容是要靠后台传过来的数据决定的,如果写死的话,当数据较多时就会发生溢出,数据较少时又会空出一大片,所以我们需要一种更加智能的方式来实现居中布局。
绝对定位 + 平移是绝对定位 + 负边距的改进版,那么具体都改进了哪些方面呢?
负边距的百分比并不是相对于自身,而是相对于父元素,所以只能写具体的像素值,显得不够智能。
而平移相对于自身,只需要无脑写-50%
就可以了:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> /* 清除默认样式 */ * { padding: 0; margin: 0; } /* 令 html 和 body 全屏显示, 并有一个灰色背景 */ html, body { height: 100%; background: gray; } /* 先在父元素上设置相对定位 */ body { position: relative } .center { /* 绝对定位 */ position: absolute; /* 上方和左方为 50% */ top: 50%; left: 50%; /* 不用给宽高,但是可以给个内边距防止内容与盒子过于贴合 */ padding: 10px; /* 这个 50%是相对于自身宽高而言的 */ transform: translate(-50%, -50%); /* 白色背景 */ background: white; } </style> </head> <body> <div class="center"> 用内容撑开盒子 </div> </body> </html>
效果如下:
- margin 的百分比是相对于父元素的宽;
- 而
translate
函数的百分比是相对于自身; - 不仅适用于未知宽高,也同样适用于固定宽高的居中布局。
网格 Grid 实现
大家可能或多或少听过一些Grid
的大名,深入了解过的人会觉得它很强大,但没深入了解过的人对它的印象可能就是:兼容性不好
但随着时间的推移,在移动端只要不考虑特别低版本的手机的话基本上都可以用了。
即使你对Grid
没什么兴趣,觉得在移动端用Flex
就已经足够了的。把它最简单的用法记住了也不会费太大劲。因为毕竟如果你能给面试官写出一个最新的技术,面试官也会对你刮目相看的:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> /* 清除默认样式 */ * { padding: 0; margin: 0; } /* 令 html 和 body 全屏显示, 并有一个灰色背景 */ html, body { height: 100%; background: gray; } /* 中央盒子的直接父元素 */ body { /* 令其变成网格布局 */ display: grid; /* 令其子元素居中 */ place-items: center; } .center { /* 不用给宽高,但是可以给个内边距防止内容与盒子过于贴合 */ padding: 10px; /* 白色背景 */ background: white; } </style> </head> <body> <div class="center">用内容撑开盒子</div> </body> </html>
运行结果如下:
其实关键代码异常的简单,几乎没什么特别大的学习成本,就这么两行:
/* 令其变成网格布局 */ display: grid; /* 令其子元素居中 */ place-items: center;
Flex 弹性盒子
移动端布局王者 Flex:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> /* 清除默认样式 */ * { padding: 0; margin: 0; } /* 令 html 和 body 全屏显示, 并有一个灰色背景 */ html, body { height: 100%; background: gray; } /* 找到中央盒子的直接父元素 */ body { /* 令其变成弹性布局 */ display: flex; } .center { /* 自动外边距 */ margin: auto; /* 白色背景 */ background: white; /* 不用给宽高,但是可以给个内边距防止内容与盒子过于贴合 */ padding: 10px; } </style> </head> <body> <div class="center">用内容撑开盒子</div> </body> </html>
运行结果如下:
Flex 几乎没有不会的吧?超级好用,简单实惠又便捷,如果这个都不会的话可以去看看我之前写的 flex 教程,里面有着很详细的入门教程:
表格布局
在居中布局这种场景下,表格布局也很适用:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> /* 清除默认样式 */ * { padding: 0; margin: 0; } body { /* 令 body 全屏显示 */ width: 100vw; height: 100vh; /* 显示为表格的格子 */ display: table-cell; /* 水平居中 */ text-align: center; /* 垂直居中 */ vertical-align: middle; /* 灰色背景 */ background: gray; } .center { /* 显示为行内块元素 */ display: inline-block; /* 不用给宽高,但是可以给个内边距防止内容与盒子过于贴合 */ padding: 10px; /* 白色背景 */ background: white; } </style> </head> <body> <div class="center">用内容撑开盒子</div> </body> </html>
运行结果如下:
此布局的关键点在于:
- 父元素上 3 个样式设置:
display: table-cell;
text-align: center;
vertical-align: center;
- 子元素上设置:
display: inline-block;
结语
看完这些有没有很郁闷,一个小小的居中布局都这么多种实现方式,而且这还不是全部的实现方式,我只挑了几款市面上常见的,可能大家会觉得有这个必要记这么多嘛!
其实这个问题就显得仁者见仁智者见智了,一方面面试造火箭,工作拧螺丝的现状让大家很苦恼。明明觉得自己技术还不错,至少公司要的都能给实现出来,但面试的时候面对面试官的刁难自己却无能为力。
以上就是今天码云笔记为大家整理的关于移动端居中布局的多种实现方式,希望对大家有帮助,也许下一次面试时并不会遇到一个面试官让你以各种方式实现居中布局,但开拓一下眼界总是好的,因为变换一下思路有助于大家在遇见复杂布局的时候可以快速选型。
码云笔记 » css 实现移动端居中布局常见方式(面试题)