前端通用单位

826 阅读5分钟

前言

之前开发了一个功能,涉及到前端单位,基于这个,打算将前端css单位全部整理一遍。

目前前端css单位主要分为两种:绝对单位相对单位

绝对单位: 它们与其他任何东西都没有关系,通常被认为总是相同的大小。例如:px, mm, cm. pt

相对单位: 相对长度单位是相对于其他某些东西(屏幕)的。例如:em, rem, vh, vw

绝对单位

数值相对固定,是多长就是多长,基本不会根据其他变化而变化,如下图展示

Untitled ‑ Made with FlexClip.gif

px

像素,px定义为相对于显示器屏幕分辨率而言的,但由于现在设备的分辨率大都趋同,就可以当作绝对单位来看。也是前端开发经常出现的单位。

但由于受到设备分辨率的影响,打印中的对于px单位会进行处理。也就是页面显示的和实际打印中是有一定的区别的。如下图。

image.png

外面div是用mm单位,可以明显感知到,px单位一旦到打印页面,效果就跟实际想要打印效果不一致。

mm

毫米单位。相比于px使用场景较少,但如果想要实现页面实际打印效果,还是要选择mm,如下图比较

image.png

打印效果明显是比px单位要好,并且比例也没有px失调。如果想要实现页面配置打印页面以及实现打印效果,尽量选择mm,cm这种不会受到分辨率影响的单位。

px和mm转换

将说转换前,先了解这两个单位DPIPPI

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

屏幕的像素显示密度, 如下图。

image.png

由于前端无法获取设备的物理高度和宽度,只能通过设备像素比(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单位所带来的分辨率识别问题