h5基础
1. 介绍
1.1 IPhone6的参数
设备像素 750 * 1334
设备独立像素 375 * 667
屏幕分辨率 750 * 1334
ppi 326
一般设置的移动端最大和最小宽度
min-width:320px;
max-width:640px;
1.2 980 布局视口
980 像素就是浏览器厂商设置的布局视口的初始宽度
1.3 数据共享的方法
- 提高变量的作用域.
- 将数据保存在一个对象中
1.4 addEventListener 第三个参数
document.documentElement.addEventListener('touchstart', function(e){
//阻止默认行为
e.preventDefault();
},{
passive:false // 被动 被动模式 true false 控制 e.preventDefault 是否失效
});
2. 屏幕相关
2.1 屏幕大小
屏幕大小指屏幕的对角线的长度,单位一般是英寸。常见的手机屏幕大小 3.5、4、4.7、5.0、5.5、6.0等。常见手机屏幕查看网址 http://screensiz.es/
注意:
-
英寸的英文为 inch , 英尺的英文是 foot 4.7inch
-
1foot = 12inch 1inch=2.54cm
2.2 屏幕分辨率
屏幕分辨率是指屏幕横纵向上的像素点数。一般表示形式 x * y 或者 y * x 表示。例如 IPhone 6 的屏幕分辨率为 750 * 1334,华为 P30 的分辨率为 2340 * 1080。
注意:
- 屏幕分辨率是一个固定值,生产出来就固定了,无论手机屏幕还是电脑屏幕。
- 屏幕分辨率与显示分辨率不同。计算机可以修改显示分辨率,信号传递给屏幕,屏幕会进行计算,在屏幕上显示。
- 1080P 的分辨率是1920x1080 720P 1280 * 720
- 2K 屏幕是单一方向分辨率具有约 2000 像素的显示设备。最标准的 2K 分辨率为 2048×1024
几款手机的分辨率
型号 | 分辨率 |
---|---|
IPhone 3GS | 320 * 480 |
IPhone 4 / 4s | 640 * 960 |
IPhone 5 / 5s | 640 * 1136 |
IPhone 6 / 7 / 8 | 750 * 1334 |
华为 P30 | 1080 * 2340 |
IPhone X | 1125 * 2436 |
4. 视口viewport
4.1 PC 端
在 PC 端,视口指的是浏览器的可视区域。其宽度和浏览器窗口的宽度保持一致。在 CSS 标准文档中,视口也被称为初始包含块,它是所有 CSS 百分比宽度推算的根源。
// 获取可视区域的宽度 不包含滚动条
document.documentElement.clientWidth
// 获取浏览器窗口的宽度 包含滚动条
window.innerWidth
// 获取浏览器总宽 包含外侧的阴影
window.outerWidth
// 获取屏幕的宽度 screen 屏幕的总宽
screen.width
4.2 移动端
移动端的视口与 PC 端不同,有三个视口
- 布局视口
- 视觉视口
- 理想视口
4.2.1 布局视口:放置网页内容的区域
布局视口是用来放置网页内容的区域。
一般移动设备的浏览器都默认定义一个虚拟的布局视口(layout viewport),用于解决早期的页面在手机上显示的问题。 视口大小由浏览器厂商决定,如果不设置viewport,大多数设备的布局视口大小为 980px。
获取方式:
document.documentElement.clientWidth // 布局视口的宽度
document.documentElement.clientHeight
4.2.2 视觉视口: 用户可见的区域
视觉视口就是 用户可见的区域:window.innerWidth
获取方式
window.innerWidth // 视觉视口的宽度
window.innerHeight
注:不缩放的情况下,视觉视口宽度 == 布局视口宽度。
4.2.3 理想视口
宽度与屏幕同宽的布局视口称为理想视口。 理想视口的好处
- 用户不需要缩放和滚动条就能看到网站的全部内容。
- 针对移动端的设计稿更容易开发。
注意:理想视口不是真实存在的视口
设置理想视口的方法
<meta name="viewport" content="width=device-width" />
<--或者-->
<meta name="viewport" content="initial-scale=1.0" />
<--合体(推荐)-->
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
4.2.4 常用参数
// 获取 布局视口 的宽度
console.log(document.documentElement.clientWidth);
// 获取 视觉视口 的宽度
console.log(window.innerWidth);
5. 缩放
5.1 PC 端
放大时
- 布局视口变小
- 视觉视口变小
- 元素的像素大小不变
缩小时
- 布局视口变大
- 视觉视口变大
- 元素的像素大小不变
5.2 移动端
放大时
- 布局视口不变
- 视觉视口变小
缩小时
- 布局视口不变
- 视觉视口变大
注意:移动端缩放不会影响页面布局
6. 真机测试流程
真机测试是项目测试必需的一个流程,一定要掌握!!!
-
关闭防火墙
-
webstorm -> ctrl + alt + s -> 搜索 debugger -> 修改端口并选中两个多选框 端口要大于 1024 建议用 8000 8888
-
使 PC 与手机处于同一个网络。手机连接电脑 wifi,或者电脑连接手机热点,两者在同一个 wifi 下最方便。
-
cmd 查看电脑无线网卡的 IP(ipconfig)
-
webstorm 在浏览器中预览文件,将 localhost 更改为 IP
-
打开草料网址 https://cli.im/ 将 URL 转化为二维码,手机扫描即可 😎
7. viewport 控制
viewport 标签是苹果公司在 2007 年引进的,用于移动端布局视口的控制。
使用示例
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scaleable=no,maximum-scale=1.0, minimum-scale=1.0">
viewport 相关选项
- width 布局视口宽度
- initial-scale 初始化缩放比例
- minimum-scale 最小缩放比例
- maximum-scale 最大缩放比例
- user-scalable 设置是否允许用户缩放
- viewport-fit auto/contain/cover
width
width 值可以是数字,也可以是设备宽度表示 device-width,这样可以得到完美视口
initial-scale
initial-scale 为页面初始化时的显示比例。
scale = 屏幕宽度独立像素 / 布局视口宽度。 // iphone6 0.5
注意:
- chrome 测试该参数会有偏差,真机测试
- initial-scale = 1.0 也可以得到完美视口
- initial-scale 会影响布局视口和视觉视口的大小
- width 与 initial-scale 同时设置时,会选择尺寸较大的那个
minimum-scale
设置允许用户最小缩放比例。
minimum-scale = 屏幕独立像素宽度 / 视觉视口 //iphone 6 0.5
maximum-scale
设置允许用户最大缩放比例,苹果浏览器 safari 不认识该属性
maximum-scale = 屏幕独立像素宽度 / 视觉视口 // 2
user-scalable
是否允许用户通过手指缩放页面。苹果浏览器 safari 不认识该属性。
viewport-fit
设置为 cover 可以解决『刘海屏』的留白问题
8. 移动端事件
8.1 事件类型
移动端事件列表
- touchstart 元素上触摸开始时触发
- touchmove 元素上触摸移动时触发
- touchend 手指从元素上离开时触发
- touchcancel 触摸被打断时触发
这几个事件最早出现于IOS safari中,为了向开发人员转达一些特殊的信息
其他常见事件:
键盘:
onkeydown onkeypress onkeyup
滚轮:
onmousewheel
文档:
onload onbeforeunload
<script type="text/javascript">
// 判断 用户是否离开您的网页
window.onbeforeunload=function () {
return '您确定要离开吗?';
}
</script>
表单:
onfocus onblur onsubmit onreset
鼠标:
onclick onmouseenter onmouseleave onmouseover onmouseout onmousedown onmousemove onmouseup
8.7 IOS 多指事件
事件类型
- gesturestart : 手指触碰当前元素,屏幕上有两个或者两个以上的手指
- gesturechange : 手指触碰当前元素,屏幕上有两个或者两个以上的手指位置在发生移动
- gestureend : 在gesturestart后, 屏幕上只剩下两根以下(不包括两根)的手指
多指事件属性
- rotation : 表示手指变化引起的旋转角度,负值表示逆时针旋转,正值表示顺时针旋转。
- scale : 表示两个手指间距离的变化情况(例如向内收缩会缩短距离);这个值从 1 开始,并随距离拉大而 增长,随距离缩短而减小。根据我们的生理极限,不允许出现负值
8.2 应用场景
touchstart 事件可用于元素触摸的交互,比如页面跳转,标签页切换
touchmove 事件可用于页面的滑动特效,网页游戏,画板
touchend 事件主要跟 touchmove 事件结合使用
touchcancel 使用率不高
注意:
- touchmove 事件触发后,即使手指离开了元素,touchmove 事件也会持续触发
- 触发 touchmove 与 touchend 事件,一定要先触发 touchstart
- 事件的作用在于实现移动端的界面交互
8.3 事件绑定
方式一:
box.ontouchstart = function(){
console.log('touch start')
}
方式二(推荐):
box.addEventListener('touchstart', function(){
console.log('touch start')
})
8.4 点击穿透
touch 事件结束后会默认触发元素的 click 事件,如没有设置完美视口,则事件触发的时间间隔为 350ms 左右,如设置完美视口则时间间隔为 5ms 左右。
如果 touch 事件隐藏了元素,则 click 动作将作用到新的元素上,触发新元素的 click 事件或页面跳转,此现象称为点击穿透
var t1 = 0;
var box = document.getElementById('box');
box.addEventListener('touchstart', function () {
console.log('触发了 touchstart 事件');
t1 = Date.now(); // 获取当前时间的时间戳
});
box.addEventListener('click', function () {
console.log('触发了 click 事件');
var t2 =Date.now();
console.log('时间间隔:', t2 - t1);
})
解决方法
方法1:阻止当前元素事件的默认行为。
cls.addEventListener('touchstart', function(e){ e.preventDefault();})
// 鼠标右键 不弹出自定义的菜单
window.oncontextmenu=function (e) {
e.preventDefault();
}
方法2:阻止顶级元素事件的默认行为,可以增加一个包裹元素绑定,也可以给 document 和 window 绑定,不过需要关闭被动模式
document.addEventListener('touchstart', function (e) {
e.preventDefault();
}, {passive: false});
方法3:使用非链接的元素代替 a 标签,设置链接地址属性,并绑定 touchstart 事件
<div class="item">
<div data-href="http://m.atguigu.com">
<img src="holder.js/60x60?bg=#a76">
</div>
<div data-href="http://m.atguigu.com">
<img src="holder.js/60x60?bg=#a76">
</div>
<div data-href="http://m.atguigu.com">
<img src="holder.js/60x60?bg=#a76">
</div>
</div>
通过touchstart 事件,获取data-href属性,并调整链接 location.href=XXX;
方法4:延时隐藏 遮罩层元素
setTimeout(function () {
el.style.display = 'none';
}, 400);
8.5 页面跳转的选择
移动端页面跳转可以使用 a 链接,也可以使用 touchstart 事件来触发 JS 代码完成跳转
- 效率上,touchstart 速度更快
- SEO 优化上, a 链接效果更好
8.6 浏览器默认行为(一般是不需要阻止的)
这里指的浏览器默认行为主要有3个
- 向下滑动会露出空白
- 长按会弹出复制、拷贝等菜单行为
- 页面缩放
8.6.1 为什么要阻止这些默认行为
这样可以让网页在不同的浏览器都有一样的表现。
8.6.2 如何阻止默认行为
可以给 document 绑定 touchstart 事件,并阻止默认行为,不过需要关闭被动模式。这里推荐创建一个包裹元素,绑定 touchstart 事件并阻止默认行为。
CSS 代码
html, body, #app {
width: 100%;
height:100%;
overflow: hidden;
}
HTML 代码
<body>
<div id="app">
XXXXXX
</div>
</body>
JS 代码
var app=document.documentGetElementById('app')// 阻止事件的默认行文app.addEventListener('touchstart', function (e) { e.preventDefault();})
8.6.3 后遗症
最外层元素阻止了 touchstart 默认行为之后,会产生一些意外现象😭
- 链接失效
- 内容无法选择
- form 元素无法获得焦点
8.6.4 最终解决方案:阻止冒泡e.stopPropagation()
产生『后遗症』的原因在于 touchstart 阻止了默认行为,后续所有的操作都已经失效。
解决问题:只需要给目标元素绑定 touchstart 事件并阻止事件冒泡,这样当前操作的默认行为仍然可用。
var link = document.getElementsByTagName('a')[0]; // 目标元素
link.addEventListener('touchstart', function (e) {
e.stopPropagation(); // 阻止事件冒泡
})
注: 不是非要阻止浏览器的默认行为,这是一种极端要求的应对方法,正常只需要设置完美视口即可。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
#box {
width: 100%;
height: 2000px;
background: linear-gradient(to bottom, #98a, #aef);
}
</style>
</head>
<body>
<div id="app">
<div id="box">
<h2><a href="http://www.baidu.com/s?wd=方便面">兰亭集序</a></h2>
<div>作者: <input type="text"></div>
<p>
永和九年,岁在癸丑,暮春之初,会于会稽山阴之兰亭,修禊事也。群贤毕至,少长咸集。此地有崇山峻岭,茂林修竹,又有清流激湍,映带左右,引以为流觞曲水,列坐其次。虽无丝竹管弦之盛,一觞一咏,亦足以畅叙幽情。
是日也,天朗气清,惠风和畅。仰观宇宙之大,俯察品类之盛,所以游目骋怀,足以极视听之娱,信可乐也。
夫人之相与,俯仰一世。或取诸怀抱,悟言一室之内;或因寄所托,放浪形骸之外。虽趣舍万殊,静躁不同,当其欣于所遇,暂得于己,快然自足,不知老之将至;及其所之既倦,情随事迁,感慨系之矣。向之所欣,俯仰之间,已为陈迹,犹不能不以之兴怀,况修短随化,终期于尽!古人云:“死生亦大矣。”岂不痛哉!
每览昔人兴感之由,若合一契,未尝不临文嗟悼,不能喻之于怀。固知一死生为虚诞,齐彭殇为妄作。后之视今,亦犹今之视昔,悲夫!故列叙时人,录其所述,虽世殊事异,所以兴怀,其致一也。后之览者,亦将有感于斯文。
</p>
</div>
</div>
<script>
var app = document.querySelector('#app');
var p = document.querySelector('p');
var input = document.querySelector('input');
//阻止浏览器的默认行为
app.addEventListener('touchstart', function (e) {
e.preventDefault();
});
//获取a链接
var a = document.querySelector('a');
a.addEventListener('touchstart', function (e) {
//阻止冒泡
e.stopPropagation();
});
// 阻止m冒泡,长按文字就可以复制了
p.addEventListener('touchstart', function(e){
e.stopPropagation();
});
// input获取焦点
input.addEventListener('touchstart', function(e){
this.focus();
e.stopPropagation();
});
// input 丧失焦点
app.addEventListener('touchstart', function(){
input.blur();
});
</script>
</body>
</html>
9. 事件对象属性
touch 事件对象中有 3 个非常重要的属性
- changedTouches
- targetTouches
- touches
- 获取手指离开元素时的位置:只可以使用changedTouches
9.1 touchstart 事件
在 touchstart 事件中,
changedTouches 为当前在元素上同时按下的触点对象数组。
targetTouches 为按下后,当前元素上的触点对象数组
touches 为按下后,当前屏幕上所有的触点对象数组
9.2 touchmove 事件
在 touchmove 事件中
changedTouches 为当前在元素上同时滑动的触点对象数组。
targetTouches 为滑动时,当前元素上的触点对象数组
touches 为滑动时,当前屏幕上所有的触点对象数组
9.3 touchend 事件
在 touchend 事件中
changedTouches 为当前在元素上同时抬起的触点对象数组。
targetTouches 为结束时时,当前元素上的触点对象数组
touches 为结束时时,当前屏幕上所有的触点对象数组
9.4 触点对象
每一个触点对象都包含一些位置信息,其中包括
- clientX 相对可视区域左侧的偏移
- clientY 相对可视区域顶侧的偏移
- pageX 相对文档左侧的偏移
- pageY 相对文档顶部的偏移
案例一:获取当前鼠标点击时的坐标
var box = document.querySelector('#box');
// 获取当前鼠标点击的坐标
box.onclick = function(e){
var x = e.clientX;
var y = e.clientY;
var a = e.pageX;
var b = e.pageY;
console.log(x,y, a, b);
}
案例二: 获取当前按键的信息
// 获取当前按键的信息 ctrl + c
window.onkeydown = function(e){
console.log(e.keyCode); // 67 c
console.log(e);
if(e.keyCode == 67 && e.ctrlKey){
// alert('你按下了 ctrl + c')
// 防止用户复制页面内容
e.preventDefault();
}
}
案例三: 阻止 右键 的弹出菜单
window.oncontextmenu = function(e){
e.preventDefault();
}
案例四:点击单独的位置,获取触的位置信息;移动鼠标,也可以获取触点的位置信息
// 点击单独的位置,获取触的位置信息;移动鼠标,也可以获取触点的位置信息
var box = document.querySelector('#box');
box.addEventListener('touchstart', function(e) {
// 获取触点的信息
var x = e.changedTouches[0].clientX;
var y = e.changedTouches[0].clientY;
box.innerHTML = 'X:' + x + ' <br> Y:' + y;
});
box.addEventListener('touchmove', function(e) {
// 获取触点的信息
var x = e.changedTouches[0].clientX;
var y = e.changedTouches[0].clientY;
box.innerHTML = 'X:' + x + ' <br> Y:' + y;
});
// 阻止默认行为
document.documentElement.addEventListener('touchstart', function(e) {
e.preventDefault();
}, {
passive: false
})
案例五:拖拽:4的位置=3-(1-2)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
#box {
width: 100px;
height: 100px;
background: darkred;
color: white;
position: absolute;
left: 0;
top: 0;
/*background:rgb(200,241,200);*/
}
</style>
</head>
<body>
<div id="box">
</div>
<script>
// 拖拽box的位置
var box = document.querySelector('#box');
box.addEventListener('touchstart', function(e) {
// 获取按下时触点的位置
this.size_client_x1 = e.touches[0].clientX;
this.size_client_y1 = e.touches[0].clientY;
// 获取按下时 元素距离左侧的偏移量
this.size_offset_left1 = box.offsetLeft;
this.size_offset_top1 = box.offsetTop;
});
box.addEventListener('touchmove', function(e) {
// 获取按下时触点的位置
this.size_client_x2 = e.touches[0].clientX;
this.size_client_y2 = e.touches[0].clientY;
// 获取按下时 元素距离左侧的偏移量
this.size_offset_left2 = box.offsetLeft;
this.size_offset_top2 = box.offsetTop;
var left_val = this.size_client_x2 - (this.size_client_x1 - this.size_offset_left1);
var top_val = this.size_client_y2 - (this.size_client_y1 - this.size_offset_top1);
// 获取最大的left 的值
var maxLeft = document.documentElement.clientWidth - box.offsetWidth;
// 检测水平方向的位置
if (left_val <= 0) {
left_val = 0;
}
if (left_val >= maxLeft) {
left_val = maxLeft;
}
if (top_val <= 0) {
top_val = 0;
}
// 设置box的 left top 的值
box.style.left = left_val + 'px';
box.style.top = top_val + 'px';
});
document.body.addEventListener('touchstart', function(e) {
e.preventDefault();
}, {
passive: false
});
</script>
</body>
</html>
10. 适配
移动端设备的屏幕尺寸繁多,要想让页面的呈现统一,需要对不同尺寸的设备进行适配。适配的方式主要有两种
- viewport 适配
- rem 适配
10.1 viewport 适配
拿到设计稿之后,设置布局视口宽度为设计稿宽度,然后量尺寸进行布局即可。
- 设置 viewport width 等于设计稿的宽度即可
- 量取元素的尺寸, 量出来是多少, 就写多少。比如元素宽度 100 像素, 则css 样式为 width : 100px
10.2 rem适配
https://www.bilibili.com/video/BV1nV411q7ch?p=22 参考视频
em 和 rem 都是 CSS 中的长度单位。而且两个都是相对长度单位,不过两个有点区别
-
em 相对的是父级元素的字体大小
<div id="outer"> <div id="inner"> 内容区域 </div> </div> <style> #outer{ font-size:40px; } #inner{ // 1em=40px 因为是相对于 父级元素的字体大小 font-size: 1em; } </style>
-
rem 相对的是根元素(html)的字体大小
<div id="outer"> <div id="inner"> 内容区域 </div> </div> <style> html{ font-size:80px; } #outer{ font-size:40px; } #inner{ // 1rem=80px 因为是相对于 根元素的字体大小 font-size: 1rem; } </style>
-
核心是等比缩放
rem 适配的策略有以下几种
方法一 :
先按照 IPhone 6 进行页面布局,再进行适配
- 完美视口设置
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
-
设计稿总宽 375 布局
设计稿一般都是750*1334的比例,所以真实的css元素尺寸=量取的宽度/2
-
设置 IPhone 6 根元素font-size = 100px
-
增加 JS 代码进行自动的html的font-size设置
// 以IPhone 6 根元素 font-size=100px 大小为参考,计算任何设备下的根元素的font-size值
document.documentElement.style.fontSize = document.documentElement.clientWidth*100/375+'px';
window.onresize = function () {
document.documentElement.style.fontSize = document.documentElement.clientWidth*100/375+'px';
}
-
计算rem
如果html的font-size为100px,那么1rem=100px,1px=0.01rem,所以,如果设计稿给出的宽度是300px,那么最后转换为rem为:300/2*0.01=1.5rem
完整代码案例:
<!doctype html>
<html lang="en" style="font-size: 100px;">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>适配</title>
<style>
#box {
width: 2rem;
height:1rem;
background: #886;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
// // 获取布局视口的宽度
// var width = document.documentElement.clientWidth;
//
// //计算新的font-size 以iphone6 font-size=100px为依据
// var x = width * 100 / 375;
//
// //设置新的font-size
// document.documentElement.style.fontSize = x + 'px';
document.documentElement.style.fontSize = document.documentElement.clientWidth * 100 / 375 + 'px';
window.onresize = function() {
document.documentElement.style.fontSize = document.documentElement.clientWidth * 100 / 375 + 'px';
}
</script>
</body>
</html>
方法二(推荐):根据设计稿宽度的比例尺寸作为根元素的字体大小
选择一个设计稿宽度的比例尺寸作为根元素的字体大小,如果设计稿宽度是750px,那么html的font-size=75px(方便计算);如果设计稿宽度是375px,那么html的font-size=37.5px(方便计算);
-
完美视口设置
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
-
通过 JS 设置页面的根元素字体大小(这里为了方便计算,设置布局视口的宽度/10)
document.documentElement.style.fontSize = document.documentElement.clientWidth / 10+ 'px'; window.onresize = function() { document.documentElement.style.fontSize = document.documentElement.clientWidth / 10+ 'px'; }
-
根据设计稿使用 rem 设置元素大小
如果html的font-size为75px,那么1rem=75px,1px=1/75rem,所以,如果设计稿给出的宽度是300px,那么最后转换为rem为:300/75=4rem
完整代码案例:
<!doctype html> <html lang="en" style="font-size: 37.5px;"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>rem适配</title> <style> #box { width: 400/37.5rem; height: 200/37.5rem; background: #886; } </style> </head> <body> <div id="box"></div> <script> document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px'; window.onresize = function() { document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px'; } </script> </body> </html>
结合scss后会更加方便:
// 因为是参考设计稿750px;如果设计稿是375px,那么此处的base-font-size应该是387.5px @function px2rem($px, $base-font-size:75px) { @if (unitless($px)) { @warn "Assuming #{$px} to be in pixels, attempting to convert it into pixels for you"; @return px2rem($px + 0px); } @else if (unit($px)==rem) { @return $px; } @return ($px / $base-font-size) * 1rem; } #box { width: px2rem(400); // 400是在750px设计稿下量取的尺寸 height: px2rem(200); background: #886; }
11. 1px 边框问题
高清屏幕下 1px 对应更多的物理像素,所以 1 像素边框看起来比较粗,解决方法如下
方法一
- 边框使用伪类选择器,或者单独的元素实现。例如底部边框
.box2::after { content: ''; height: 1px; width: 100%; position: absolute; left: 0; bottom: 0; background: #000;}
- 在高清屏幕下设置
@media screen and (-webkit-min-device-pixel-ratio: 3) { .box2 { transform: scaleY(0.33333); }}
方法二
- rem 页面布局
var fontSize = 50;document.documentElement.style.fontSize = '50'+px;
-
元素的边框设置为 1px
-
通过 viewport 中的 initial-scale 将页面整体缩小
var dpr = window.devicePixelRatio;viewport.setAttribute('content', 'user-scalable=no, initial-scale='+1/dpr + ',user-scalable=no');
- 重新设置根元素字体
document.documentElement.style.fontSize = fontSize * dpr + 'px';