我们在编写样式的时候会遇到这样问题移动端动态计算字体的大小:
这个时候我们首先会想到使用rem,响应式布局的单位我们第一时间会想到通过rem单位来实现适配,但是它还需要内嵌一段脚本去动态计算跟元素大小。
比如:
使用脚本(方法一)
(function (doc, win) {
let docEl = doc.documentElement
let resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'
let recalc = function () {
var clientWidth = docEl.clientWidth
if (!clientWidth) return
docEl.style.fontSize = 14 * (clientWidth / 320) + 'px'
}
if (!doc.addEventListener) return
win.addEventListener(resizeEvt, recalc, false)
doc.addEventListener('DOMContentLoaded', recalc, false)
})(document, window)
使用脚本(方法二)
!function (e, t) {
function i() {
var t = n.getBoundingClientRect().width / 10; n.style.fontSize = t + "px", p.rem = e.rem = t
}
var a, r = e.document, n = r.documentElement, o = r.querySelector('meta[name="viewport"]'), l = r.querySelector('meta[name="flexible"]'), m = r.querySelector('meta[name="flexible-in-x5"]'), s = !0, d = 0, c = 0, p = t.flexible || (t.flexible = {});
if (o) { console.warn("将根据已有的meta标签来设置缩放比例"); var u = o.getAttribute("content").match(/initial\-scale=([\d\.]+)/); u && (c = parseFloat(u[1]), d = parseInt(1 / c))
} else if (l) { var f = l.getAttribute("content"); if (f) { var h = f.match(/initial\-dpr=([\d\.]+)/), v = f.match(/maximum\-dpr=([\d\.]+)/); h && (d = parseFloat(h[1]), c = parseFloat((1 / d).toFixed(2))), v && (d = parseFloat(v[1]), c = parseFloat((1 / d).toFixed(2))) } }
if (m && (s = "false" !== m.getAttribute("content")), !d && !c) {
var x = (e.navigator.appVersion.match(/android/gi), e.chrome), g = e.navigator.appVersion.match(/iphone/gi), b = e.devicePixelRatio, w = /TBS\/\d+/.test(e.navigator.userAgent), y = !1; try { y = "true" === localStorage.getItem("IN_FLEXIBLE_WHITE_LIST") } catch (e) { y = !1 } c = 1 / (d = g || x || w && s && y ? b >= 3 && (!d || d >= 3) ? 3 : b >= 2 && (!d || d >= 2) ? 2 : 1 : 1)
} if (n.setAttribute("data-dpr", d), !o)
if ((o = r.createElement("meta")).setAttribute("name", "viewport"), o.setAttribute("content", "initial-scale=" + c + ", maximum-scale=" + c + ", minimum-scale=" + c + ", user-scalable=no"), n.firstElementChild) n.firstElementChild.appendChild(o); else { var E = r.createElement("div"); E.appendChild(o), r.write(E.innerHTML) } e.addEventListener("resize", function () { clearTimeout(a), a = setTimeout(i, 300) }, !1), e.addEventListener("pageshow", function (e) { e.persisted && (clearTimeout(a), a = setTimeout(i, 300)) }, !1), "complete" === r.readyState ? r.body.style.fontSize = 12 * d + "px" : r.addEventListener("DOMContentLoaded", function (e) { r.body.style.fontSize = 12 * d + "px" }, !1), i(), p.dpr = e.dpr = d, p.refreshRem = i, p.rem2px = function (e) { var t = parseFloat(e) * this.rem; return "string" == typeof e && e.match(/rem$/) && (t += "px"), t }, p.px2rem = function (e)
{ var t = parseFloat(e) / this.rem; return "string" == typeof e && e.match(/px$/) && (t += "rem"), t }
}(window, window.lib || (window.lib = {}))
那有没有一个单位不需要JS和CSS耦合在一起的单位?答案是有的,就是vw/vh。
vw = view width
vh = view height
这两个单位是CSS3引入的,以上称为视口单位允许我们更接近浏览器窗口定义大小。
(1)vw、vh、vmin、vmax 是一种视窗单位,也是相对单位。它相对的不是父节点或者页面的根节点。而是由视窗(Viewport)大小来决定的,单位 1,代表类似于 1%。
视窗(Viewport)是你的浏览器实际显示内容的区域—,换句话说是你的不包括工具栏和按钮的网页浏览器。
vw:视窗宽度的百分比(1vw 代表视窗的宽度为 1%)
vh:视窗高度的百分比
vmin:当前 vw 和 vh 中较小的一个值
vmax:当前 vw 和 vh 中较大的一个值
(1)% 是相对于父元素的大小设定的比率,vw、vh 是视窗大小决定的。
(2)vw、vh 优势在于能够直接获取高度,而用 % 在没有设置 body 高度的情况下,是无法正确获得可视区域的高度的,所以这是挺不错的优势。
vmin、vmax 用处
做移动页面开发时,如果使用 vw、wh 设置字体大小(比如 5vw),在竖屏和横屏状态下显示的字体大小是不一样的。
由于 vmin 和 vmax 是当前较小的 vw 和 vh 和当前较大的 vw 和 vh。这里就可以用到 vmin 和 vmax。使得文字大小在横竖屏下保持一致。
1:三种单位的转换
2:如何适配移动端的不同设备
前提知识:
手机端的长宽是实际设计过程中的两倍
比如手机端是 750 * 1200
那么具体实现的时候应该是 375px * 600px
好,记住这个结论,当有一张设计图摆在你面前的时候,你只需要将它长宽除以二,就没问题了。
这样说不知道有没有讲明白,没有的话请留言。
三种单位的转换
1,vw / vh
分别是 viewwidth 和 viewheight 的缩写
100vw 等于整个屏幕宽度 100vh等于整个屏幕高度
例如某设备宽高是 375px * 600px
那么 1vw = 3.75px 1vh = 6px
要想适配移动端的设备,只需要讲 html font-size设置为合适的 vw值就可以了(这是其中一种方法)
如果想要让一个盒子覆盖整个页面 需要设置为
width: 100vw;
height: 100vh;
2,rem
1rem 等于HTML的字体大小(默认为16px)
使用rem可以使得编写的移动端网页尽可能地适配设备,而不会出现在iphone没有乱,到华为就一团糟的场景
3,px:浏览器的像素,一种相对单位
三者如何转化呢?
例如有一张设计图 375px * 600px
我们可以这样设置HTML的字体大小
html {font-size: 37.5vw;}
这样的话 1rem=37.5vw=100px
代码区内的font-size 37.5也可以取其他的值(1-100),我这样取是因为1rem等于10px的话使用起来更有优势
如何适配移动端的不同设备
例如转换后的长宽分别为 375px 600px
1:定义HTML的字体大小(选择一个对rem和px的转换比较有好的值)
2:下载对应编辑器上的插件,px转rem(vscode是cssrem)
插件安装以及设置的链接:https://www.jianshu.com/p/bb48fbdacb26
3:设置插件的属性 这是最关键的一步
即px转rem的比例
4:正常编写代码,将这个当做一个PC端的网页写
5:边写边转化为对应的rem值
vscode使用cssrem
3. 设置根字体
点击VScode左下方图标,选中设置
往下滑到cssrem,三个选项随你改
!function(win,doc){
var d=doc.documentElement;
function change(){
d.style.fontSize= d.clientWidth/96+'px';
}
win.addEventListener('resize',change,false);
change();
}(window,document);