前言
之前开发了一个功能,涉及到前端单位,基于这个,打算将前端css单位全部整理一遍。
目前前端css单位主要分为两种:绝对单位,相对单位。
绝对单位: 它们与其他任何东西都没有关系,通常被认为总是相同的大小。例如:px, mm, cm. pt
相对单位: 相对长度单位是相对于其他某些东西(屏幕)的。例如:em, rem, vh, vw
绝对单位
数值相对固定,是多长就是多长,基本不会根据其他变化而变化,如下图展示
px
像素,px定义为相对于显示器屏幕分辨率而言的,但由于现在设备的分辨率大都趋同,就可以当作绝对单位来看。也是前端开发经常出现的单位。
但由于受到设备分辨率的影响,打印中的对于px单位会进行处理。也就是页面显示的和实际打印中是有一定的区别的。如下图。
外面div是用mm单位,可以明显感知到,px单位一旦到打印页面,效果就跟实际想要打印效果不一致。
mm
毫米单位。相比于px使用场景较少,但如果想要实现页面实际打印效果,还是要选择mm,如下图比较
打印效果明显是比px单位要好,并且比例也没有px失调。如果想要实现页面配置打印页面以及实现打印效果,尽量选择mm,cm这种不会受到分辨率影响的单位。
px和mm转换
将说转换前,先了解这两个单位DPI和PPI
DPI
直接来说就是一个英寸有多少像素。根据上述描述,就可以在页面创建1in的div,用来获取像素数量,代码如下
function getDPI() {
// 创建一个1mm宽的元素插入到页面,然后坐等出结果
let div = document.createElement("div");
div.id = "dpi-div";
div.style.width = "1in";
document.querySelector("body").appendChild(div);
// 原生方法获取浏览器对元素的计算值
let dpi = document.getElementById("dpi-div").offsetWidth;
return dpi;
}
PPI
屏幕的像素显示密度, 如下图。
由于前端无法获取设备的物理高度和宽度,只能通过设备像素比(devicePixelRatio)和屏幕的宽度和高度来估算PPI。代码如下
function getPPI() {
// 获取设备像素比
const dpr = window.devicePixelRatio
// 获取屏幕的CSS像素宽度和高度
const screenWidth = window.screen.width
const screenHeight = window.screen.height
// 估算的物理宽度和高度(单位为英寸)
const estimatedWidthInInches = screenWidth / dpr / 96
const estimatedHeightInInches = screenHeight / dpr / 96
// 计算对角线上的像素数
const diagonalResolution = Math.sqrt(screenWidth ** 2 + screenHeight ** 2)
// 计算估算的对角线尺寸(单位为英寸)
const diagonalSizeInInches = Math.sqrt(estimatedWidthInInches ** 2 + estimatedHeightInInches ** 2)
// 计算PPI
const ppi = diagonalResolution / diagonalSizeInInches
this.ppi = ppi
return ppi
}
px => mm
px 转换为mm 是由公式,公式如下
mm = px / PPI ×25.4
根据公式就可以得出如下代码:
function pxToMM (px) {
const mm = px / this.ppi * 25.4
return Math.floor(mm)
},
mm => px
mm 转换为 px,公式如下:
px = mm / 25.4 * dpi
根据公式就可以得出如下代码:
function mmToPx(mm) {
const inches = mm / 25.4;
const px = inches * this.dpi;
return Math.round(px);
}
pt
全称为point,但中文不叫“点”,它大小为1/72英寸。所以它是一个自然界标准的长度单位。适配于打印时候使用的字体单位
相对单位
相对长度单位是相对于其他某些东西的,
em
相对于父元素字体大小,配合父元素的font-size,则会继承父元素的字体大小。
使用em单位,他会继承父元素的字体大小,而父元素又会继承自己的的父元素的字体大小等等。导致了如果其中一个元素的字体改变,会导致了连锁反应,大家一起会变。
.container {
font-size: 16px;
}
.container p {
font-size: 1em; // 16px
}
.container h2 {
font-size: 3em;// 48px
}
.container h3 {
font-size: 2em; // 32px
}
rem
相对于根元素的字体大小,也就是html元素。目前在移动端开发比较多,由于相对是html,只要不设置根元素的字体,rem单位就是绝对单位。对于移动端开发适配多个手机,也只需要更改根元素的字体大小,内容字体就会跟随变化,同时也不会受到其他元素的影响。
rem单位同时有绝对单位和相对单位的优点,既可以更改根元素来实现变化,同时也不会像em一样产生连锁反应
%
与前面介绍em一样相对于父元素,100% 单位相对于父元素的宽度和高度,和em单位一样,会有连锁反应。 适用于元素随着父元素的宽度变化而变化。
vh 和 vw
相对于视图高度,1vh 是视口高度的 1%, 1vw是视图高度的1%,视图变化,也就使用这两单位也会跟着一起改变。适用于要随着视图变化的场景,例如导航的侧边栏,表格高度适配视图高度等。
总结
在文档中整理了一些前端常用样式。在开发过程中,要正确使用样式单位,如果要自适应页面的宽高,尽量选择相对单位,如果是页面确定的宽高则选择绝对单位。使用相对单位的时候,要先考虑连锁反应。
如果是app开发的时候,因为要适配各种各样的手机,以及不同类型的手机分辨率,尽量选择相对单位进行页面排版。
如果是页面打印这种比较精确的,则要选择mm等物理单位。因为则可以避免px单位所带来的分辨率识别问题