移动端适配,展开讲讲?
移动设备的种类繁多,屏幕尺寸、分辨率、设备能力等都有可能不同。
因此,我们需要采取一些策略来确保我们的网页在不同的设备上都能正确、优雅地展示。
先说一些常用的方案吧:
- 响应式布局
- REM布局
- Viewport Meta Tag
- Flex 布局
- 使用适配库 如amfe-flexible,postcss-pxtorem等
- 设备检测 Modernizr
响应式布局
通常我们会使用CSS3的媒体查询(media query)来根据设备的视口宽度来改变布局。
例如将多列布局变为单列布局,或者改变字体大小和间距等。
REM布局
REM 是 CSS3 中的一个相对单位,它相对于根元素(html)的字体大小进行计算。
我们可以通过改变根元素的字体大小,来改变其他元素的尺寸,以此来实现布局的自适应。一般我们会结合JavaScript来动态计算根元素的字体大小。
<html>
<head>
<style>
html {
font-size: calc(100vw / 10); /* 假设设计稿宽度为750px, 1rem = 75px */
}
div {
width: 1rem; /* div的宽度为75px */
}
</style>
</head>
<body>
<div></div>
</body>
</html>
如何动态改变根元素的字体大小呢?
其实是搭配媒体查询来达到动态效果:
html {
font-size: 16px; /* 默认字体大小 */
}
/* 当视口宽度小于600px时,改变字体大小 */
@media (max-width: 600px) {
html {
font-size: 14px;
}
}
/* 当视口宽度小于400px时,再次改变字体大小 */
@media (max-width: 400px) {
html {
font-size: 12px;
}
}
由于rem
是相对于<html>
元素的字体大小,所以当我们改变<html>
元素的字体大小时,所有使用rem
单位的元素的大小也会随之改变。这使得我们可以根据视口的大小来调整页面的布局和元素的大小。
rem 和 em 的区别 ?
em
是相对于其父元素的字体大小。假设父元素的字体大小为16px,那么1em就等于16px。如果一个元素的字体大小设置为2em,那么该元素的字体大小就是其父元素字体大小的两倍。
那我们为什么不用 em 来当做方案呢?
使用em
,元素的大小是相对于其父元素的字体大小,这意味着如果你在一个深层次的元素上设置大小,你需要考虑所有祖先元素的字体大小。这可能导致复杂和难以预料的结果,尤其是在大型和复杂的项目中。
如果你希望元素的字体大小和其内部元素的大小保持一致,或者如果你希望元素的大小能够响应其父元素的字体大小变化,那么 em
可能是一个好的选择。
那 rpx 单位呢 ?
rpx
被设计为可以根据屏幕宽度进行自适应。规定屏幕宽度为750rpx。因此在 iPhone6 上,1rpx 对应 0.5物理像素。小程序会根据手机屏幕的宽度自动进行转换,这样在不同宽度的屏幕上,元素的视觉大小会保持相对一致。
所以,如果你正在开发小程序,或者使用 uni-app 这种框架,通常就无需再使用 rem
进行布局了。
而在开发通用网页时,我们还是需要使用到像 rem
这样的响应式设计工具的。
Viewport Meta Tag
viewport meta 标签是移动端开发中非常重要的一个标签,它用于设置视口的大小和比例。
例如,以下的 meta 标签会使得布局视口宽度等于设备的物理视口宽度,并禁止用户手动缩放:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
Flex 布局
通过使用flex
属性,我们可以很容易地定义元素在不同屏幕大小下的比例。
设备检测
有些时候,我们可能需要根据设备的类型或者能力来改变布局或者提供不同的功能。这时,我们可以通过一些库如Modernizr来检测设备的能力,或者使用媒体查询来检测设备的物理特性。
在架构层面,我们需要考虑的是如何设计一个灵活、可扩展、易维护的适配方案。我们可能需要选择适合我们项目的适配方法,可能是REM,可能是媒体查询,也可能是一个混合方案。
此外,我们也需要考虑如何将适配方案整合到我们的构建系统中,例如,如何自动将px转化为rem,如何自动生成适当的媒体查询等。我们还需要考虑如何测试我们的适配方案,确保在各种设备上都能正确工作。
什么是 Modernizr?
Modernizr是一个JavaScript库,它可以帮助你检测用户的浏览器是否支持你需要的HTML5和CSS3特性。
这样你就可以根据这些检测结果来决定你的代码是否要使用某个特性,或者提供一个备选方案。
例如,你可能希望使用HTML5的Canvas特性来画图,但是有些旧的浏览器可能不支持Canvas。
这时你可以使用Modernizr来检测用户的浏览器是否支持Canvas,如果支持,就使用Canvas,如果不支持,就提供一个基于图片或Flash的备选方案。
if (Modernizr.canvas) {
// 浏览器支持canvas
// 在canvas上画图
} else {
// 浏览器不支持canvas
// 提供一个备选方案
}
适配库 amfe-flexible,postcss-pxtorem
这是两个常用的库,用于帮助开发者更方便地实现基于rem
的响应式设计。
amfe-flexible
是阿里移动前端团队开发的一个库,用于动态设置<html>
元素的font-size
值。
使用amfe-flexible
后,你就不需要自己编写媒体查询来改变font-size
了,amfe-flexible
会自动根据设备的屏幕宽度来调整font-size
。具体的使用方法如下:
首先,安装amfe-flexible
:
npm install amfe-flexible --save
然后,在你的主入口文件(例如main.js
)中引入并使用它:
import 'amfe-flexible'
amfe-flexible 工作原理
- 首先获取到视口(viewport)的宽度。通常,这个宽度等于设备的屏幕宽度。
- 根据设计稿的尺寸和视口的宽度计算出一个合适的
font-size
值。例如,如果设计稿的宽度是 750px,视口的宽度是 375px,那么font-size
的值就会被设置为375/10 = 37.5px
。 - 设置
<html>
元素的font-size
属性为计算出来的值。
如果我们使用媒体查询设置 <html>
的 font-size
,就需要为每一种可能的屏幕宽度编写一个设置 <html>
的 font-size
。
如果有一种屏幕宽度没有考虑到,就可能导致布局的错误。
相比之下,amfe-flexible
的方式更为自动化,只需要引入库并简单配置即可,不需要编写大量的媒体查询,也不需要考虑各种可能的屏幕宽度,因此在实践中更为常用。
那amfe-flexible
到底是如何自动设置 font-size 的值呢?
"自动设置 font-size 的值",其实就是根据屏幕的宽度(视口宽度)自动调整根元素<html>
的font-size
。
举个例子,假设设计稿的宽度是750px,我们可以设定1rem等于设计稿宽度的1/10,也就是75px。那么,在一个375px宽度的设备(比如iPhone6)上,amfe-flexible
会将<html>
的font-size
设置为37.5px(375px/10),而在一个414px宽度的设备(比如iPhone 8 Plus)上,font-size
会被设置为41.4px(414px/10)。
这样我们只需要按照设计稿上的尺寸直接写px,就可以做到自适应了。
postcss-pxtorem
postcss-pxtorem
是一个PostCSS插件,它可以将你的CSS中的px
单位自动转换为rem
单位。
这样,你可以继续使用你习惯的px
单位来编写CSS,然后让postcss-pxtorem
在编译阶段自动转换它们。具体的使用方法如下:
安装:
npm install postcss-pxtorem --save-dev
然后,在你的postcss.config.js
配置文件中添加postcss-pxtorem
:
module.exports = {
plugins: {
'postcss-pxtorem': {
rootValue: 16, // 基准值,通常设置为设计稿宽度/10
propList: ['*'], // 应用于所有属性
minPixelValue: 2 // 最小的转换值,如果设置为2,那么小于2px的值就不会被转换
},
},
};
现在,postcss-pxtorem
会在编译阶段自动将你的CSS中的px
单位转换为rem
单位。
postcss-pxtorem
的工作原理
在你的CSS文件被编译时,它会找出所有以px为单位的值,并自动将其转换为rem单位。
例如,如果你在CSS文件中写了width: 750px
,那么postcss-pxtorem
会在编译阶段自动将其转换为width: 10rem
(假设rootValue
为75)。
总结
这两个工具结合使用,可以让你在开发过程中只需要关心px单位,而无需手动进行px到rem的转换,也无需关心视口宽度的变化,从而大大提升开发效率。
这也是为什么amfe-flexible
和postcss-pxtorem
常常会一起使用的原因。
amfe-flexible
负责自动调整<html>
的font-size
,postcss-pxtorem
负责将px单位自动转换为rem单位。
使用这两个工具,可以让你在写CSS时仍然可以像平时一样使用px单位,但最终的结果却是响应式的,可以自动适应各种屏幕大小。
假如我们在项目中写了这么一段css:
.container {
width: 750px;
padding: 20px;
font-size: 28px;
}
然后,在项目的编译过程中,postcss-pxtorem
会自动将这些 px
单位转换为 rem
单位。假设我们设置了 rootValue: 75
,那么转换后的样式将会是:
.container {
width: 10rem;
padding: 0.26667rem;
font-size: 0.37333rem;
}
而amfe-flexible
会自动调整 <html>
的 font-size
。
比如在一个宽度为 375px 的设备上,它会将 <html>
的 font-size
设置为 37.5px
。因此,1rem
就等于 37.5px
。在这种情况下,上述的 .container
元素,它的宽度将会是 375px
,padding
将会是 10px
,font-size
将会是 14px
。
这样一来,无论设备的宽度如何变化,.container
的视觉尺寸都会保持相对一致。
这就是 amfe-flexible
和 postcss-pxtorem
结合使用的工作方式。在编写样式时,你只需要按照设计稿的尺寸,用 px
单位来编写。然后,这两个工具会自动将其转换为能够适应不同屏幕大小的样式。
转载自:https://juejin.cn/post/7237052860512813113