专栏首页前端进阶CSS尺寸单位介绍

CSS尺寸单位介绍

前端开发过程中,尺寸单位是我们必须用到的,下面我们对css中常见的几种尺寸单位px,em,rem,rpx进行逐一介绍 在这之前,需要先对几个概念进行普及介绍

基本概念

(以下概念读起来可能有些晦涩,如果看不懂也没关系)

像素

它不是自然界的物理长度,指基本原色素及其灰度的基本编码。

css中的像素只是一个抽象的单位,在不同的设备或不同的环境中,css中的1px所代表的设备物理像素是不同的。 在为桌面浏览器设计的网页中,我们无需对这个津津计较,但在移动设备上,必须弄明白这点。 在早先的移动设备中,屏幕像素密度都比较低,如iphone3,它的分辨率为320x480,在iphone3上,一个css像素确实是等于一个屏幕物理像素的。 后来随着技术的发展,移动设备的屏幕像素密度越来越高,从iphone4开始,苹果公司便推出了所谓的Retina屏,分辨率提高了一倍,变成640x960,但屏幕尺寸却没变化,这就意味着同样大小的屏幕上,像素却多了一倍,这时,一个css像素是等于两个物理像素的。其他品牌的移动设备也是这个道理。

物理像素

它是显示器(电脑、手机屏幕)最小的物理显示单位,物理像素指的是显示器上最小的点。物理像素的大小取决于屏幕。是一个无法改变的属性。

设备独立像素

我上一张图,你就会理解什么是设备独立像素

就是我们开发过程中使用的css中的px

设备像素比(device pixel radio)

设备像素比 = 物理像素 / 设备独立像素,单位是dpr!(device pixel radio)

Retina屏幕

所谓“Retina”是一种显示标准,是把更多的像素点压缩至一块屏幕里,从而达到更高的分辨率并提高屏幕显示的细腻程度。也被称为视网膜显示屏 ——百度百科

因为Retina屏幕的出现,在pc端默认情况下,css中的1px等于1物理像素,但在移动端1px不一定等于1物理像素,比如说iPhone的设备独立像素是375 667,因为它使用了Retina屏幕,他的dpr是2,所以iPhone 6 的物理像素为 750 1334

在不同的屏幕上(普通屏幕 vs retina屏幕),css中1px所呈现的大小(物理尺寸)是一致的,不同的是1px所对应的物理像素个数是不一致的。

在普通屏幕下,1px 对应 1个物理像素(1:1)。 在Retina屏幕下(dpr=2),1px对应 2x2个物理像素(1:4)。

你会发现,在移动端开发中使用了图片(img标签),2倍图要比1倍图清晰,就是这个缘故

px

默认情况下像素px是相对于屏幕分辨率而言,比如说我们的屏幕分辨率是1440 X 900,说的就是像素1440px X 900px;

这里会遇到另一种情况

浏览器缩放

缩放是缩放CSS像素(缩放比例为1时,一个CSS像素等于一个屏幕像素),就是在屏幕分辨率不变的情况下,用户对浏览进行了缩放

强调一点,用户的缩放行为是对浏览器进行的,缩放的是css像素,而非分辨率,分辨率是屏幕的分辨率,不论你怎么缩放当前页面,屏幕分辨率都不会改变

我们知道在移动端可以在一定程度上控制用户的缩放行为,也可以禁止用户缩放

<meta name="viewport" content="width=device-width,initial-scale=1.0">

content属性值 :

  1. width:可视区域的宽度,值可为数字或关键词device-width
  2. height:可视区域的高度,值可为数字或关键词device-height
  3. intial-scale:页面首次被显示是可视区域的缩放级别,取值1.0则页面按实际尺寸显示,无任何缩放
  4. maximum-scale=1.0, minimum-scale=1.0;可视区域的缩放级别,
  5. maximum-scale用户可将页面放大的程序,1.0将禁止用户放大到实际尺寸之上。
  6. user-scalable:是否可对页面进行缩放,no 禁止缩放

但是在pc端就麻烦了 windows:

  • ctrl + +/-
  • ctrl + 滚轮
  • 浏览器菜单栏

mac:

  • cammond + +/-
  • 浏览器菜单栏

由于浏览器菜单栏属于系统软件权限,没发控制,我们可以通过js控制ctrl/cammond + +/- 或 Windows下ctrl + 滚轮 缩放页面的情况

em

本人在实际开发过程中并没有使用过em单位,但是后面要说的rem是基于em的,所以,对em进行简单介绍

em 是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。

  • em的值并不是固定的;
  • em会继承父级元素的字体大小;
  • 任意浏览器的默认字体高都是16px。所有未经调整的浏览器都符合: 1em=16px。body选择器中声明Font-size=62.5%<==>1em=10px。

看个栗子吧

<body>
  <style>
    html {
      font-size: 50px;
    }

    .my-div {
      width: 100%;
      height: 500px;
      margin-top: 50px;
      background-color: gray;
      font-size: 40px;
    }

    .my-div .parent-font {
      font-size: 30px;
    }

    .my-div .parent-font .child-font {
      font-size: 0.5em;
    }
  </style>
  <div class="my-div">
    <p class="parent-font">
      我是父级文字
      <span class="child-font">我是子级文字</span>
    </p>
  </div>
</body>

html代码中,

第一级,html的 font-size: 50px;

第二级,my-div 的 font-size: 40px;

第三级,parent-font 的 font-size:30px;

第四级,child-font 的 font-size: 0.5em;

我们通过浏览器查看,发现第四级的fong-size为15px;

我们取消第三级parent-font 的字体大小

我们通过浏览器查看,发现第四级的fong-size为20px;

当我们取消第三级font-size后,第三级的字体大小为40px;

所以我们说em的字体大小不是固定的,em的大小取决于父级的字体大小

当父级的字体大小为20px,子级的1em就是20px

当父级的字体大小为30px,子级的1em就是30px

那么说font-size存在着继承父级的特点

我们在第一级html中设置font-size,第二级继承第一级,第三级继承第二级,第四级继承第三级,以此类推

每一级都继承自它的父级,也就是说每一级的em所代表的px大小都不是固定的,因为他们的父级不是同一个,所以em的应用场景并不多。

那么如果是em的都继承自同一个地方,是不是可以解决很多问题呢?

这时候rem出现了

rem

rem 是CSS3的一个相对单位(root em,根em)

使用rem为元素设定字体大小时,仍然是相对大小,但相对的只是HTML根元素

只要html的font-size大小不变,1rem所代表的font-size大小就不会变,rem只取决于html的font-size

rem解决了哪些问题

移动设备的宽度是各种各样的,每个设备的dpr也不同,换句话说就是不同设备每一行的物理像素数不同,能显示的css的px数也不同,

如果我们写一个div,宽度是375px,375px在这个屏幕(iPhone6)上是刚刚满屏,因为这个屏幕宽度刚刚是375px( 设备独立像素),

当我们换另一个宽度是414px的设备(iPhone6Plus)时,这个宽度375px的div就无法铺满这个屏幕,同样的当换一个iPhone5(320px),又会出现滚动条,安卓机的宽度更是五花八门,使用media媒体查询不靠谱,因为它不能覆盖所有的机型宽度

我们之前说rem的大小是相对于html的font-size的,如果html的font-size根据不同设备的宽度做动态计算,问题就会得到解决

我们写页面都是根据UI设计稿来做的,我们假设UI设计稿的宽度是750px(750px是常规宽度,当然也可以是640px或是其他宽度,但是整个项目,宽度必须统一),唯一不变就是就屏幕宽度,我们的html的font-size(rem)只取决于设备宽度

于是

document.documentElement.style.fontSize = 100 * ( document.documentElement.clientWidth / 750) + 'px'

html的font-size:document.documentElement.style.fontSize

设备的宽度:document.documentElement.clientWidth

750:UI设计稿的宽度

为了方便计算我们将font-size x 100,方便计算(乘100不是必须的,我接触过一些项目就不是乘以100,但是UI设计稿中使用了sketch做了动态计算,但我还是建议乘100,不然遇到psd的设计图就很麻烦了)

对上面的js做些完善

const fontFun = function () {
  let docEl = document.documentElement
  let resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'
  const recalc = function () {
    let clientWidth = docEl.clientWidth
    if (!clientWidth) return
    docEl.style.fontSize = 100 * (clientWidth / 750) + 'px'
  }
  if (!document.addEventListener) return
  window.addEventListener(resizeEvt, recalc, false)
  window.addEventListener('pageshow', recalc, false)
  document.addEventListener('DOMContentLoaded', recalc, false)
}
export {
  fontFun
}

对以上代码不做过多解释

也可以这样写

(function(doc, win) {
  var docEl = doc.documentElement,
    resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
    recalc = function() {
      var clientWidth = docEl.clientWidth
      if (!clientWidth) return
      docEl.style.fontSize = 100 * (clientWidth / 750) + 'px'
    }
  if (!doc.addEventListener) return
  win.addEventListener(resizeEvt, recalc, false)
  win.addEventListener('pageshow', recalc, false)
  doc.addEventListener('DOMContentLoaded', recalc, false)
})(document, window)

iPhone5(320px)下html的font-size:42.6667px,1rem=42.6667px

iPhone6(375px)下html的font-size:50px,1rem=50px

iPhone6Plus(414px)下html的font-size:55.2px,1rem=55.2px

rem是继承自html的font-size,但是小程序中没有html,那怎么办呢?

rpx

我不基于html的font-size了,我基于一个别的值就行了,你也不需要计算这个值,我给你计算了,这就是rpx。 最终的效果就是,你开发时在iphon6的设计稿上量了多少px,就写多少rpx就行了,完美适配,perfect!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 库克不想靠iPhone坐吃山空!苹果开启管理层重组:加码AI,向服务要收入

    为了进一步扭转iPhone失势带来的影响,库克大刀阔斧,对苹果管理层进行调整与重组。

    量子位
  • 升级和游戏音效 如何在场景和声音效果之间切换

    在游戏中,您通常需要一项功能,以便在游戏进行时使游戏更难。例如,在Mario中,您需要清除每个阶段以传递到下一个区域。每次通过舞台,难度都会变得更难。在本节中,...

    iOSDevLog
  • 『互联网架构』软件架构-spring源码之spring ioc(九)

    PS:读源码确实很麻烦,但是spring的源码大概120多MB,相当于一个JAVA的JDK了,读了怼咱们日常开发真的很有用,设计到的模式:单例模式,工厂模式,建...

    IT故事会
  • 苹果提交折叠屏新专利,可正折、反折、还能三折,未来iPhone长这样?

    2月18日晚上,美国专利商标局(USPTO)公布了一份苹果公司的专利,展示了苹果在折叠屏上的新想法:

    量子位
  • 码农也该懂点sketch

    sketch是一款轻量的,易用的矢量设计工具,有了它,可以让你进行更加简单高效的UI设计。

    brzhang
  • SpriteKit简介-创建您的第一个iPhone平台游戏

    在本节中,您将学习如何使用SpriteKit创建自己的平台游戏。您将学习如何实现所有基本游戏功能,如玩家移动,玩家跳跃,相机工作,动画等。

    iOSDevLog
  • 苹果人事“大地震”,意图减少对iPhone的依赖性

    近一段时间以来,苹果高管变动的新闻一直没有停歇,包括以往被看作苹果下一任接班人的零售主管安吉拉·阿伦茨企卸任,约翰·詹南德雷亚被任命为机器学习和人工智能业务高级...

    镁客网
  • iOS[UIImage imageNamed:]生成的对象释放时机

    如果使用imageNamed这个方法加载一些比较大的资源文件就容易崩溃,从而引发了imageNamed生成的对象什么时候释放?

    赵哥窟
  • 5G和区块链会给我们带来什么?

    高晓松近期在清华园大谈5G和区块链,重点谈到了这两个赛道可能会给内容产业(音乐、视频、文章、书......)带来许多新的变化,视频链接:

    申龙斌
  • Flutter进阶篇(5)-- 使用Flutter创建插件详解并发布到Pub库

    下面详细的讲解一下Flutter如何创建一个插件,并且教大家上传到Pub库,让大家也体验一把自己的库被别人使用的自豪感。

    AWeiLoveAndroid

扫码关注云+社区

领取腾讯云代金券