移动端适配
移动端适配是使应用在各种设备(不同设备的屏幕尺寸和分辨率差异较大)上都能良好地显示。
viewport
viewport即视窗、视口,用于显示网页部分的区域,在PC端视口即是浏览器窗口区域,在移动端,为了让页面展示更多的内容,视窗的宽度默认不为设备的宽度,在移动端视窗有三个概念:布局视窗、视觉视窗、理想视窗。
- 布局视窗:移动设备上的浏览器会把自己默认的viewport设为980px或其他值,一般都比移动端浏览器可视区域大很多,会有横向滚动条。
- 视觉视窗:终端设备显示网页的区域。
- 理想视窗:终端屏幕的宽度,页面刚好全部展现在视窗内,不会出现横向滚动条。
通过设置 viewport 可以设置页面大小,在 meta 标签可以设置 viewport 信息:
1 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-sacle=1, maximum-scale=1" > |
| 属性 | 含义 | 取值 |
|---|---|---|
| width | 定义视口的宽度,单位为像素 | 正整数或设备宽度device-width |
| height | 定义视口的高度,单位为像素 | 正整数或device-height |
| initial-scale | 定义网页初始缩放值 | 整数或小数,小数为缩小,反之放大 |
| maximum-scale | 定义缩放最大值 | 整数或小数 |
| minimum-scale | 定义缩放最小值 | 整数或小数 |
| user-scalable | 定义用户是否可以缩放 | yes/no |
适配方案
rem 布局
- rem单位是相对于字体大小的html元素,也称为根元素。 默认情况下,html元素的font-size为16px。所以此时1rem = 16px。
- 如果通过rem来实现响应式的布局,只需要根据视图容器的大小,动态的改变font-size即可(而em是相对于父元素的)。
rem响应式的布局思想:
- 一般不要给元素设置具体的宽度,但是对于一些小图标可以设定具体宽度值
- 高度值可以设置固定值,设计稿有多大,我们就严格有多大
- 所有设置的固定值都用rem做单位(首先在HTML总设置一个基准值:px和rem的对应比例,然后在效果图上获取px值,布局的时候转化为rem值)
- js获取真实屏幕的宽度,让其除以设计稿的宽度,算出比例,把之前的基准值按照比例进行重新的设定,这样项目就可以在移动端自适应了
rem布局的缺点:在响应式布局中,必须通过js来动态控制根元素font-size的大小,也就是说css样式和js代码有一定的耦合性,且必须将改变font-size的代码放在css样式之前。
1 | /*上述代码中将视图容器分为10份,font-size用十分之一的宽度来表示,最后在header标签中执行这段代码,就可以动态定义font-size的大小,从而1rem在不同的视觉容器中表示不同的大小,用rem固定单位可以实现不同容器内布局的自适应。*/ |
rem布局也是目前多屏幕适配的最佳方式。默认情况下我们html标签的font-size为16px,利用媒体查询,设置在不同设备下的字体大小。
1 | /* pc width > 1100px */ |
1 | //动态为根元素设置字体大小 |
媒体查询
CSS 媒体查询(media query)是响应式设计的关键组成部分,你可以根据各种设备特征和参数是否存在以及对应的值来应用 CSS 样式。
1 | @media media-type and (media-feature-rule) { |
它由以下部分组成:
一个媒体类型,告诉浏览器这段代码是用在什么类型的媒体上的(例如印刷品或者屏幕)。可以指定的媒体类型为:
- all
- screen
- speech
一个媒体表达式,是一个被包含的 CSS 生效所需的规则或者测试。
一组 CSS 规则,会在测试通过且媒体类型正确的时候应用。
媒体特征规则
在指定了类型以后,你可以用一条规则指向一种媒体特征。
宽和高
使用最小值和最大值对响应式设计有很多的用处,所以你会很少见到width或height 单独使用的情况。
1 | @media screen and (min-width: 800px) { |
朝向
一个受到良好支持的媒体特征是orientation,我们可以用它测得竖放(portrait mode)和横放(landscape mode)模式。要在设备处于横向的时候改变 body 文本颜色的话,可使用下面的媒体查询。对朝向的测试可以帮你建立一个为竖放设备优化的布局。
1 | @media (orientation: landscape) { |
使用指点设备
作为四级规范的一部分,hover****媒体特征被引入了进来。这种特征意味着你可以测试用户是否能在一个元素上悬浮,这也基本就是说他们正在使用某种指点设备,因为触摸屏和键盘导航是没法实现悬浮的。
1 | @media (hover: hover) { |
如果我们知道用户不能悬浮的话,我们可以默认显示一些交互功能。对于能够悬浮的用户,我们可以选择在悬浮在链接上的时候,让这些功能可用。
还是在四级规范中,出现了pointer媒体特征。它可取三个值:none、fine和coarse。fine指针是类似于鼠标或者触控板的东西,它让用户可以精确指向一片小区域。coarse指针是你在触摸屏上的手指。none值意味着,用户没有指点设备,也许是他们正只使用键盘导航,或者是语音命令。
使用pointer可以在用户使用屏幕时进行交互时,帮你更好地设计响应这种交互的界面。例如,如果你知道用户正在用触摸屏设备交互的时候,你可以建立更大的响应区域。
更复杂的媒体查询
有了所有不同的可用的媒体查询,你可能想要把它们混合起来,或者建立查询列表——其中的任何一个都可以匹配生效。
媒体查询中的“与”逻辑
为了混合媒体特征,你可以以与在上面使用and很相同的方式,用and来混合媒体类型和特征。
例如,我们可能会想要测得min-width和orientation,而 body 的文字只会在视口至少为 400 像素宽,且设备横放时变为蓝色。
1 | @media screen and (min-width: 400px) and (orientation: landscape) { |
媒体查询中的“或”逻辑
如果你有一组查询,且要其中的任何一个都可以匹配的话,那么你可以使用逗号分开这些查询。
在下面的示例中,文本会在视口至少为 400 像素宽的时候或者设备处于横放状态的时候变为蓝色。如果其中的任何一项成立,那么查询就匹配上了。
1 | @media screen and (min-width: 400px), screen and (orientation: landscape) { |
媒体查询中的“非”逻辑
你可以用not操作符让整个媒体查询失效。这就直接反转了整个媒体查询的含义。因而在下面的例子中,文本只会在朝向为竖着的时候变成蓝色。
1 | @media not all and (orientation: landscape) { |
怎么选择断点
可以在一张样式表上加入多条媒体查询,调整整个页面或者部分页面以达到适应各式屏幕尺寸的最佳效果。引入媒体查询,以及样式改变时的点,被叫做***断点***(breakpoints)。
开发者工具中的响应式设计模式能很好地帮助弄清楚断点应该设置在哪里。你能容易就能让视口变大和变小,然后看下可以在哪里加入媒体查询、调整设计,从而改善内容。
移动优先的响应式设计
- 使用媒体查询时的一种通用方式是,为窄屏设备(例如移动设备)创建一个简单的单栏布局,然后检查是否是大些的屏幕,在你知道你有足够容纳的屏幕宽度的时候,开始采用一种多栏的布局。这经常被描述为移动优先设计。
- 媒体查询的缺点也很明显,如果在浏览器大小改变时,需要改变的样式太多,那么多套样式代码会很繁琐。
vw/vh 布局
vw表示相对于视图窗口的宽度,vh表示相对于视图窗口高度。 任意层级元素,在使用vw单位的情况下,1vw都等于视图宽度的百分之一。使用 vw 和 vh 单位来定义页面元素的尺寸,从而实现响应式布局。与百分比布局很相似,但更好用。
1 | .box { |
百分比布局
使用百分比来实现布局,但是需要特定宽度时,元素百分比参考的对象为父元素,元素嵌套较深时会有问题。不建议用%来做响应式布局。
1 | <div class="parent"> |
响应式布局
现代布局方式,例如多栏布局、伸缩盒和网格默认是响应式的。
多个列
1 | .container { |
伸缩盒
1 | .container { |
CSS 网格
1 | .container { |
使用第三方框架
除了手动进行移动端适配外,还可以使用一些专门的移动端开发框架,如 Bootstrap、Ant Design、Element Ui等。这些框架提供了丰富的移动端组件和样式,可以大大简化移动应用的开发过程,并帮助开发者快速实现移动端适配。


