响应式网站的实现方式很多,例如rem+vw、rem+flexible、媒体查询等等,之前公司要求开发一套官网能够同时适配三端(PC、IPAD、移动端),下面记录我遇到的问题以及解决方法。
1.实现
一开始,只有一套设计图(我们是PC端为基础,一般是移动端设计稿为基础多),使用flexiblejs+rem方式足够适配多端且不用像媒体查询那样需要写多套样式,后来需求有所变化,移动端设计稿与PC端相比改变很大,这种情况下只能考虑写两套样式,即flexible+rem用于适配PC+IPAD端,利用媒体查询针对移动端用户另外设计一套样式,思路上可以使用postcss将像素转换成rem,同时vs安装px-to-rem插件,在移动端样式使用rem单位,这样既可以享受到flexiblejs动态设置根元素font-size同时不需要担心postcss会将px单位自动转换成rem。
1.1 安装插件
npm i postcss postcss-pxtorem
1.2 配置 px-to-rem插件
vscode搜索cssrem可以看到配置选项,在设置里面可以配置屏幕宽度、设计稿宽度、基准fontszie(建议设计稿宽度 / 10)等等
1.3 配置post-css
在项目根目录下新建postcss.config.cjs文件并配置
module.exports = {
plugins: {
"postcss-pxtorem": {
rootValue(res) {
return 192
},// 设计稿宽度的1/10,代表 1rem=192
"propList": ["*"], // 需要做转化处理的css属性 * 就是所有属性都要转换,如`hight`、`width`、`margin`等,`*`表示全部
"exclude": /node_modules|pages\/login.vue/i, // 这里表示不处理node_modules文件下的css
}
}
}
1.4 引入flexible.js文件
(function flexible(window, document) {
var docEl = document.documentElement;
var dpr = window.devicePixelRatio || 1;
// adjust body font size
function setBodyFontSize() {
if (document.body) {
document.body.style.fontSize = 12 * dpr + "px";
} else {
document.addEventListener("DOMContentLoaded", setBodyFontSize);
}
}
setBodyFontSize();
// set 1rem = viewWidth / 10
function setRemUnit() {
;
var rem = docEl.clientWidth / 10;
docEl.style.fontSize = rem + "px";
}
setRemUnit();
// reset rem unit on page resize
window.addEventListener("resize", setRemUnit);
window.addEventListener("pageshow", function (e) {
if (e.persisted) {
setRemUnit();
}
});
// detect 0.5px supports
if (dpr >= 2) {
var fakeBody = document.createElement("body");
var testElement = document.createElement("div");
testElement.style.border = ".5px solid transparent";
fakeBody.appendChild(testElement);
docEl.appendChild(fakeBody);
if (testElement.offsetHeight === 1) {
docEl.classList.add("hairlines");
}
docEl.removeChild(fakeBody);
}
})(window, document);
1.5 使用px-to-rem适配移动端
//此处写普通样式PC+IPAD
@media (max-width:750px) {
// 可以先写px单位,写完样式后alt+z统一转换
// 此处写移动端样式
.swiper-wrapper {
// width: 100%;
height: 6rem;
background-color: #dcebff;
img {
// background-color: #dcebff;
object-fit: contain;
width: 100%;
height: 6rem;
padding: 0;
}
}
}
2. 总结
总结一下,在有两套UI的情况下实现响应式适配,可以使用flexiblejs+rem+媒体查询的方式,针对PC与IPAD端,使用flexiblejs+rem方式正常编写,同时需要引入postcss将px单位自动换成rem单位;针对移动端,写媒体查询,需要避免postcss的自动转换,同时引入px-to-rem自动将px换成rem避免postcss自动转换的同时,也可以针对性的写移动端样式。