前端大屏适配方案汇总
【摘要】 前端大屏适配方案汇总
方案一:rem 单位+动态设置 html 的 font-size
动态设置 html 根字体的大小和 body 字体大小(使用 lib_flexible.js插件)
- 将设计稿的宽(1920)平均分成 24 等份,每一份 80px;
- html 根字体大小就设置为 80px,即 1rem = 80px,24rem = 1920px(移动端推荐分为 10 份);
- 将 body 字体大小设置为 16px;
- 最后需要使用插件或者其他方式将 px 转为 rem 单位:手动、less/scss 函数、cssrem 插件、webpack 插件、Vite 插件等。
lib_flexible.js 代码参考
(function flexible(window, document) {
var docEl = document.documentElement;
var dpr = window.devicePixelRatio || 1;
// adjust body font size
function setBodyFontSize() {
if (document.body) {
// body 字体大小默认为 16px
document.body.style.fontSize = 16 * dpr + 'px';
} else {
document.addEventListener('DOMContentLoaded', setBodyFontSize);
}
}
setBodyFontSize();
// 这里默认平均分成 10 等分(适用移动端)
// set 1rem = viewWidth / 24 ;(使用pc端)
function setRemUnit() {
var rem = docEl.clientWidth / 24; // 1920 / 24 = 80
docEl.style.fontSize = rem + 'px'; // 设置 html字体的大小 80px
}
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);
方案二:vw 单位
- 直接使用 vw 单位,屏幕的宽默认为 100vw,那么100vw = 1920px, 1vw = 19.2px 。
- 安装 cssrem 插件, body 的宽高(1920px * 1080px)直接把 px 单位转 vw 单位
- 其他 px 转 vw 方式:手动、less/scss 函数、cssrem 插件、webpack 插件、Vite 插件
方案三:scale 等比例缩放(推荐)
CSS 函数 scale() 用于修改元素的大小。可以通过向量形式定义的缩放值来放大或缩小元素,同时可以在不同的方向设置不同的缩放值。
使用 CSS3 中的 scale 函数来缩放网页,我们可以使用两种方案来实现:
方案一:直接根据宽度的比率进行缩放。(宽度比率 = 网页当前宽 / 设计稿宽)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body,
ul {
margin: 0;
padding: 0;
}
body {
width: 1920px;
height: 1080px;
box-sizing: border-box;
border: 3px solid red;
/* 指定缩放的原点在左上角 */
transform-origin: left top;
}
ul {
width: 100%;
height: 100%;
list-style: none;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
li {
width: 33.333%;
height: 50%;
box-sizing: border-box;
border: 2px solid green;
font-size: 30px;
}
</style>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<script>
// 设计稿: 1920 * 1080
// 目标适配: 1920 * 1080 3840 * 2160 ( 2 * 2 ) ; 7680 * 2160( 4 * 2)
// 1.设计稿的尺寸
let targetX = 1920;
// let targetY = 1080
// let targetRatio = 16 / 9 // 宽高比率
// 2.拿到当前设备(浏览器)的宽度
let currentX = document.documentElement.clientWidth || document.body.clientWidth;
// 1920 * 1080 -> 3840 * 2160
// 3.计算缩放比例 (当前设备的宽度 / 设计稿的宽度)
let scaleRatio = currentX / targetX; // 参照宽度进行缩放
// 4.开始缩放网页 (缩放的原点在左上角)
document.body.style = `transform: scale(${scaleRatio})`;
</script>
</body>
</html>
方案二:动态计算网页宽高比,决定是是否按照宽度的比率进行缩放。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body,
ul {
margin: 0;
padding: 0;
}
body {
position: relative;
width: 1920px;
height: 1080px;
box-sizing: border-box;
border: 3px solid red;
/* 指定缩放的原点在左上角 */
transform-origin: left top;
}
ul {
width: 100%;
height: 100%;
list-style: none;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
li {
width: 33.333%;
height: 50%;
box-sizing: border-box;
border: 2px solid green;
font-size: 30px;
}
</style>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<script>
// 设计稿: 1920 * 1080
// 目标适配: 1920 * 1080 3840 * 2160 ( 2 * 2 ) ; 7680 * 2160( 4 * 2)
// 1.设计稿的尺寸
let targetX = 1920;
let targetY = 1080;
let targetRatio = 16 / 9; // 宽高比率
// 2.拿到当前设备(浏览器)的宽度
let currentX = document.documentElement.clientWidth || document.body.clientWidth;
let currentY = document.documentElement.clientHeight || document.body.clientHeight;
// 1920 * 1080 -> 3840 * 2160
// 3.计算缩放比例
let scaleRatio = currentX / targetX; // 参照宽度进行缩放 ( 默认情况 )
let currentRatio = currentX / currentY; // 宽高比率
// 超宽屏
if (currentRatio > targetRatio) {
// 如果当前设备的宽高比率大于设计稿的宽高比率,那么就以高度为参照进行缩放,并且居中显示
scaleRatio = currentY / targetY;
document.body.style = `width:${targetX}px; height:${targetY}px;transform: scale(${scaleRatio}) translateX(-50%); left: 50%`;
} else {
// 4.开始缩放网页
document.body.style = `width:${targetX}px; height:${targetY}px; transform: scale(${scaleRatio})`;
}
</script>
</body>
</html>
三种适配方案对比
vw 相比 rem 的优势
优势一:不需要去计算html的font-size大小,不需要给html设置font-size,也不需要设置body的font-size,防止继承;
优势二:因为不依赖font-size的尺寸,所以不用担心某些原因html的font-size尺寸被篡改,页面尺寸混乱;
优势三:vw相比rem更加语义化。1vw是1/100的viewport大小(即将屏幕分成100份);并且具备rem之前所有的优点。
vw 和 rem 存在的问题
- 如果使用rem或vw单位时,在 js 中添加样式时,单位需要手动设置rem或vw。
- 第三方库(Element、Echarts等)的字体一般默认都是px单位,因此通常需要层叠第三方库的样式。
- 当大屏比例更大时,有些字体还需要相应的调整字号。
scale相比vw和rem的优势
- 优势一:相比于vw和rem,使用起来更简单,不需要对单位进行换算
- 优势二:因为不需要对单位进行换算,在使用第三方库时,不需要考虑单位转换问题
- 优势三:由于浏览器的字体默认最小是不能超过12px,导致rem或vw无法设置小于12px的字体,scale缩放没有这个问题。
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)