Write By CS逍遥剑仙
我的主页: csxiaoyao.com
GitHub: github.com/csxiaoyaojianxian
Email: sunjianfeng@csxiaoyao.com QQ: 1724338257
最常用的 绝对单位,按精确像素计算
em
是 相对单位,基准为父节点字体大小,若自身定义了 font-size
则按自身计算,不推荐使用rem
是 相对单位,css3新加,按照根节点 <html>
的字号作为基准,下方提供的设置根节点 62.5% 的方案并不推荐,具体实践见第二节的介绍/* 根节点字体大小设置为 62.5%,即 10px 可以方便计算,否则将以浏览器默认字号 16px 为基准 */ /* 10 ÷ 16 × 100% = 62.5% */ /* 但 chrome 最小的字体大小为 12px,因此浏览器中的字体均 >= 1.2rem */ html { font-size: 62.5%; } body { font-size: 1.4rem; } /* 1.4 × 10px = 14px */
vw
/ vh
即 viewpoint width / height,按照 视窗 的宽高的百分比进行计算,和 css 中的 %
按照父元素的宽高作为计算基准的方式不同vmin
/ vmax
取视窗宽高二者中较小 / 大值的百分比进行计算/* 元素始终在屏幕上可见 */ .box { width: 100vmin; height: 100vmin; } /* 元素始终铺满整屏 */ .box { width: 100vmax; height: 100vmax; }
%
百分比,一般相对于父元素,但对于 position: absolute;
的元素是相对于已定位的父元素,对于 position: fixed;
的元素是相对于可视窗口,并且当父元素没有指定高度时,子元素设置百分比没有效果,高度直接为子元素的实际高度vm
css3 新单位,相对于视窗宽高较小的那个的百分比,兼容性较差下面的单位几乎用不到:
in
寸cm
厘米mm
毫米pt
point,约1/72寸pc
pica,大约6pt,1/6寸ch
...ex
......
移动端适配最简单的是通过js动态计算 viewport 的缩放值,但过于粗暴,会导致页面图片文字失真模糊。目前,移动端页面一般使用 rem
或 vw
/ vh
开发会较为方便,下面以 rem
为例:
为了方便计算,约定:100px = 1rem
,若设计师给到一张宽度为 750px 的设计稿,那么可以设置 html 的字体大小为 设备宽度 / 设计稿宽度 * 100
个px像素,以 iPhone 6/7/8 的宽度 375px 为例,则 html 字体的大小为 50px,即在宽度为 375 px 的设备上,1rem = 50px
。对于开发人员,一个宽度为 50px 的 div,就可以很轻松的通过除以 100,计算出对应的 rem 为 0.5rem,不需要再根据各种机型进行适配,0.5rem 换算到 iPhone 6/7/8 为 25px,而放到 750px 宽的设备上对应的是 50px。
总体来说,使用 rem 进行适配需要以下四步:
<meta name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1">
var clientWidth = document.documentElement.clientWidth document.documentElement.style.fontSize = 100 * clientWidth / 750 + 'px'
建议设置监听,在页面尺寸变化时仍能正常展示
if (!document.addEventListener || !window.addEventListener) return document.addEventListener('DOMContentLoaded', setScale, false) window.addEventListener('orientationchange' in win ? 'orientationchange' : 'resize', setScale, false) window.addEventListener('load', setScale, false)
上面第二部分通过动态设置 html 的 font-size 已经实现了页面随设计稿比例缩放,这种方式是页面宽度 100% 撑满设备宽度的,但是很多情况下,我们更希望部分横版页面能够高度撑满设备高度,而左右部分留白,此时有两种方式可以实现:
var clientHeight = document.documentElement.clientHeight document.documentElement.style.fontSize = 100 * clientHeight / 375 + 'px'
var maxWidth = 670 var calWidth = Math.min(document.documentElement.clientWidth, maxWidth) document.documentElement.style.fontSize = 100 * calWidth / 750 + 'px'
微信等 App 内可以设置默认字号,若用户修改了默认文字大小,会给上述的适配造成困扰,解决方法是先获取 App 的原始缩放比例,再在此基础上计算 font-size,实现如下:
// 创建1rem宽度的不可见元素,用于计算原始缩放比例 var scaleDom = (function () { var scaleDom = document.createElement('div') scaleDom.style.cssText = 'width:1rem;height:0;overflow:hidden;position:absolute;z-index:-2;visibility:hidden;' document.body.appendChild(scaleDom) return scaleDom })() // 计算使用过fontSize缩放(如微信)下的原始缩放比例 function getOriginScale () { var htmlFontSize = Number(String(document.querySelector('html').style.fontSize || 16).replace('px', '')) var instanceWidth = Number(String(window.getComputedStyle ? window.getComputedStyle(scaleDom).width : scaleDom.offsetWidth).replace('px', '')) var scale = (htmlFontSize && instanceWidth) ? htmlFontSize / instanceWidth : 1 return scale } // 设置 html 用于处理 rem 的 font-size function setScale () { var scale = getOriginScale() var clientWidth = document.documentElement.clientWidth if (!clientWidth) return window.uimakerScale = clientWidth / designWidth * scale document.documentElement.style.fontSize = 100 * window.uimakerScale + 'px' }
针对上述的适配方案,本文提供一套已在 html 自助化系统的生产环境中使用的适配代码作为最佳实践。
首先是 html 代码中需要配置视窗参数:
<!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> ... </head> <body data-page-type="{{jsonData.pageType}}" data-design-width="{{jsonData.width}}" data-max-width="{{jsonData.maxWidth}}"> ... </body> </html>
在初始化代码中执行下面的自执行函数,即可完成适配。
;(function (doc, win) { // 页面数据 var pageType = parseInt(doc.body.getAttribute('data-page-type')) || 0 // 页面方向 0竖1横 var designWidth = parseInt(doc.body.getAttribute('data-design-width')) || 750 // 设计宽度 var maxWidth = parseInt(doc.body.getAttribute('data-max-width')) || designWidth // 最大页面适配宽度 // 创建1rem宽度的不可见元素,用于计算原始缩放比例 var scaleDom = (function () { var scaleDom = doc.createElement('div') scaleDom.style.cssText = 'width:1rem;height:0;overflow:hidden;position:absolute;z-index:-2;visibility:hidden;' doc.body.appendChild(scaleDom) return scaleDom })() // 计算使用过fontSize缩放(如微信)下的原始缩放比例 function getOriginScale () { var htmlFontSize = Number(String(doc.querySelector('html').style.fontSize || 16).replace('px', '')) var instanceWidth = Number(String(win.getComputedStyle ? win.getComputedStyle(scaleDom).width : scaleDom.offsetWidth).replace('px', '')) var scale = (htmlFontSize && instanceWidth) ? htmlFontSize / instanceWidth : 1 return scale } // 设置 html 用于处理 rem 的 font-size 和 页面二次缩放 function setScale () { var scale = getOriginScale() var clientWidth = doc.documentElement.clientWidth var clientHeight = doc.documentElement.clientHeight if (!clientWidth || !clientHeight) return var calWidth = maxWidth > 0 ? Math.min(clientWidth, maxWidth) : clientWidth win.uimakerScale = calWidth / designWidth * scale doc.documentElement.style.fontSize = 100 * win.uimakerScale + 'px' } setScale() setTimeout(() => { setScale() }, 300) if (!doc.addEventListener || !win.addEventListener) return doc.addEventListener('DOMContentLoaded', setScale, false) win.addEventListener('orientationchange' in win ? 'orientationchange' : 'resize', setScale, false) win.addEventListener('load', setScale, false) })(document, window)
移动端的适配已是老生常谈,市面上也有不少成熟的第三方库,但或多或少需要进行额外的配置,本文的方案是结合本人在一个自助化生成网页的项目的生产环境的实践中总结得出,若有更好的方案和建议欢迎和我交流。
前言 微服务成了互联网架构的标配模式,对微服务之间的调用的流量治理和管控就尤...
3月24日,腾讯发布2020年Q4及全年财报,其中金融科技及企业服务第四季收入385亿...
1.某女生寝室门口贴着一个告示男生与饭盒不得入内,问何解?答曰两者都会搞大女...
本文转载自微信公众号「后端Q」,作者conan。转载本文请联系后端Q公众号。 概述 ...
作者 | 楚奕 来源 | 阿里技术公众号 这篇文章主要从技术视角介绍下跨平台WebCanv...
基于阿里巴巴的互联网架构、大数据技术,利用混合云架构打造全新的云化电子税 务...
1.在报名的路上,我看见远处的学校,轰!的一声没了。希望如此。 2.男:我一直...
背景 有时候我会碰到快速搭建测试服务的需求,比如像这样: 搭建一个 HTTP Servi...
创业与投资的本质,都是追寻一种能够穿越时空,抵达未来的高效方式。 德勤管理咨...
1.百度是个大骗子,我抄了十几年的满分作文却从未得过满分。 2.学神在刷难题,...