通过css的@media媒体查询设置不同的样式,实现不同屏幕的适配。
link元素中的css媒体查询,不同屏幕加载不同的样式文件:
<link rel="stylesheet" media="(max-width:576px)" href="moblie.css">
<link rel="stylesheet" media="(min-width:768px)" href="pc.css">
css样式表中的媒体查询
@media only screen and (max-width: 414px){
html{
font-size: 64px;
}
}
@media only screen and (max-width: 375px){
html{
font-size: 58px;
}
}
@media only screen and (max-width: 360px){
html{
font-size: 56px;
}
}
@media only screen and (max-width: 320px){
html{
font-size: 50px;
}
}
根据视口大小动态设置根元素html的font-size值进行适配
单个静态页面布局,需要手动将px单位换成rem单位,有些不需要动态缩放的元素依旧使用px.
只需要在页面引入下面这段原生代码,就能实现html根元素值动态改变。
/**
* designWidth 设计稿的实际宽度值 根据实际设置
* maxWidth 制作稿的最大宽度值 根据实际设置
*/
;(function(designWidth, maxWidth) {
let doc = document,
win = window,
docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window? 'orientationchange' : 'resize';
function refreshRem() {
let width = docEl.getBoundingClientRect().width;
maxWidth = maxWidth || 640;
width >maxWidth && (width = maxWidth);
let rem = width * 100 / designWidth;
docEl.style.fontSize = rem + 'px';
}
if(!doc.addEventListener) return ;
win.addEventListener(resizeEvt, refreshRem, false);
doc.addEventListener('DOMContentLoaded', refreshRem, false);
if (doc.readyState === "complete") {
doc.body.style.fontSize = "16px";
} else {
doc.addEventListener("DOMContentLoaded", function(e) {
doc.body.style.fontSize = "16px";
}, false);
}
})(750, 750);
1,meta标签设置viewport宽度为屏幕宽度;
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
2,px自动转换成vw
2.1 安装插件postcss-px-to-viewport
npm install postcss-px-to-viewport --save-dev
2.2 vue3中使用postcss-px-to-viewport 适配屏幕
在项目根目录创建postcss.config.js 文件,并填入以下内容,重新运行
module.exports = {
plugins: {
// ...
'postcss-px-to-viewport': {
// options
unitToConvert: 'px', // 需要转换的单位,默认为"px"
viewportWidth: 750, // 设计稿的视窗宽度
unitPrecision: 5, // 单位转换后保留的精度
propList: ['*', '!font-size'], // 能转化为 vw 的属性列表,font-size不进行vw转换
viewportUnit: 'vw', // 希望使用的视窗单位
fontViewportUnit: 'vw', // 字体使用的视窗单位
selectorBlackList: [], // 需要忽略的 CSS 选择器,不会转为视窗单位,使用原有的 px 等单位
minPixelValue: 1, // 设置最小的转换数值,如果为 1 的话,只有大于 1 的值会被转换
mediaQuery: false, // 媒体查询里的单位是否需要转换单位
replace: true, // 是否直接更换属性值,而不添加备用属性
exclude: undefined, // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
include: /\/src\//, // 如果设置了include,那将只有匹配到的文件才会被转换
landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件
landscapeUnit: 'vw', // 横屏时使用的单位
landscapeWidth: 1125, // 横屏时使用的视窗宽度
},
},
};
可以在代码中设置是否转换
/* px-to-viewport-ignore-next / —> 下一行不进行转换.
/ px-to-viewport-ignore */ —> 当前行不进行转换
.title{
/* px-to-viewport-ignore-next */
width:10px;
font-size:16px;/* px-to-viewport-ignore */
}
Android 4.4 之下和 iOS 8 以下的版本有一定的兼容性问题
1,安装viewport-units-buggyfill
npm install viewport-units-buggyfill --save-dev
2,初始化
const hacks = require('viewport-units-buggyfill/viewport-units-buggyfill.hacks');
require('viewport-units-buggyfill').init({
hacks: hacks
});
3,在css中使用,手动添加content代码
.my-viewport-units-using-thingie {
width: 50vmin;
height: 50vmax;
top: calc(50vh - 100px);
left: calc(50vw - 100px);
/* hack to engage viewport-units-buggyfill */
content: 'viewport-units-buggyfill; width: 50vmin; height: 50vmax; top: calc(50vh - 100px); left: calc(50vw - 100px);';
}