css - rem和vw

物理像素

物理像素在不同的设备中1px里可以容纳的像素颗粒是不相同的,所以1px这个单位其实也是有N个像素颗粒填充的。同一尺寸屏幕的每个像素点所能容纳的像素颗粒越多显示效果越清晰、分辨率越高。也即1个像素点所有容纳的颗粒越多,效果越好。现在的手机屏幕用肉眼已经看不到颗粒,这是由于设备支持越来越细小的像素颗粒,这些屏幕被称为retina(视网膜屏幕)。现在假设有一个1px的图片,该图片的1px容纳了1个像素颗粒,现在将该图片放进支持1px可容纳2个颗粒的屏幕中,这会将图片的那个颗粒拆分成两半放进设备的1个px里,而由于该设备的1px必须有两个颗粒才能填满,现在它的两个颗粒都没有被填满,这就会造成图片显示效果模糊。所以不是1px的图片在某个屏幕上显示是非常清楚的,那么它在另一个屏幕上就一定也清楚,清楚不清楚要看屏幕的物理像素。

像素比

像素比指的是1个px单位可以容纳的像素颗粒

分辨率

分辨率=宽*高*像素比。

简单区分屏幕的各种概念,以iphone6 plus的屏幕为例:

1.414、736是屏幕的宽高、尺寸

2.414*3*736*3是屏幕的物理像素总量、物理尺寸、物理分辨率

3.该手机屏幕的总物理像素是414*3*736*3=‭2742336‬,即1242*2208=‭2742336‬,这个尺寸的屏幕可容纳‭2742336‬个像素颗粒。pc的像素比是1,所以pc的分辨率是1920*10808*1,结果是1920*1080*1=2073600,整个pc屏幕容纳了2073600个像素颗粒。

pc与手持设备的物理像素差别

在pc屏幕里,css的1px只占用一个像素单位,这1个像素在具有大于1的像素比的手机屏幕里会变小,因为pc的1px小于手机屏幕的1px,pc的1px不能填满手机屏幕的1px。pc端的像素比是1:1,也就是说如果为某个元素设定一个16px的fontsize,那么在屏幕上就有16个像素颗粒。而手持设备的像素比是1:3及其以上,1个px单位必须填充3个px颗粒,那么把pc端的16像素放进手持设备后会发现16个像素颗粒只有5.3个物理像素(16÷3=5.3),单位太小就会导致文字太小看不清楚。

body{
    font-size:16px;
    background:#0094ff;
}

为了让手持设备正常显示16px的字号,可以改成48px(16*3)

body{
    font-size:48px;
    background:#0094ff;
}

viewport

viewport是一个视口容器,viewport可以在不改变pc端对元素的尺寸设置就可以立即实现pc端与手机端呈现相同的显示效果。也即viewport可以自动计算从而保证pc端和手持设备的分辨率一致。比如一个pc端的16px的字体,在手机端自动呈现为48px的,不需要手动更改字号大小。

声明viewport

 <meta name="viewport" />

通过content设置viewport的各个配置

<meta name="viewport" content="width=device-width,height=device-height,initial-scale=2,user-scalable=yes,maximum-scale=1.0" />  
width height :指定了视口的宽高为手持设备的宽高
initial-scale:缩放比是2倍(自动将pc端的网页放大两倍,这会导致pc端整体尺寸变大两倍,比如字号16px,将pc端浏览器放大200%就是在手机端呈现的效果)
user-scalable:允许或禁止用户缩放网页
maximum-scale:允许用户在浏览器上操作网页的最大缩放比

使用viewport通常都是将自动缩放比设为1,让pc端和手持设备的分辨率保持一致

<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1,user-scalable=no" />  

viewport的问题

viewport的优点是不需要我们手动去计算像素比,它包办让pc端和手持设备分辨率看起来一致。但它也有缺点,比如图片在手持设备中会失真。这是由于页面每个元素都计算了像素比,一个16px的文字在手机端被viewport呈现为16*3=48,现在假设一张图片的真实像素是100px,它在pc端正常显示,如果放到手持设备上,那么它会被viewport暴力拉大,100*3=300px,这就会导致图片模糊失真。所以很多程序在手持设备上都把图片做成了字体以避免失真。

rem布局

尺寸单位的对比

px:固定单位

em:相对单位,根据当前元素的字体大小进行运算得出一个px的值,计算方法是:em*自身的font-size

rem:相对单位,根据当前文档的根节点<html>节点的字体大小进行运算得出一个px的值,计算方法是:rem*根元素html的font-size

em与rem都有灵活性,适合在移动端布局,两者区别仅在于em看自身的字体大小决定最终尺寸,而rem只看根html元素字体大小决定最终尺寸。浏览器都有默认字体大小,如chrome的默认字体大小是16px,16px=1rem,除非你用css去控制元素的字体大小,否则你页面上的根元素即<html>元素的字体大小就是浏览器的默认字号16px。

rem布局原理

相对于em来说,rem明显更容易计算。使用em来设置元素尺寸,如果当前元素没有设置fontSize,那么你还需要逐层找到当前元素继承的字号大小,而rem只需要知道html节点的字体大小即可。我们主要利用方便计算的rem来实现移动端的布局,这个原理就是通过媒体查询获取当前屏幕的尺寸,然后根据不同的尺寸动态设置html根节点的fontSize,然后rem可以乘以不同屏幕尺寸的fontSize,实现等比例缩放。

@media screen and (min-width:320px) {
    html {
        font-size: 50px; 
    }
}
@media screen and (min-width:414px) {
    html {
        font-size: 64.6875px; 
    }
}
@media screen and (min-width:640px) {
    html {
        font-size: 100px; 
    }
}

div {
    font-size:0.48rem; //48px字体。48÷100=0.48
    width: 2rem; //200px的盒子 200÷100=2
    height:2rem;
    background: #ff6a00;
}

<div>鸷鸟</div>
less rem适配

手持设备的尺寸太多,用less进行计算比较方便

@charset "UTF-8";
/*主流屏幕尺寸列表*/
@screen-size-list: 320px,360px,375px,384px,400px,411px,414px,424px,480px,540px,640px,720px,750px,768px;
/*主流屏幕尺寸列表总长度*/
@secreen-size-list-length: length(@screen-size-list);
/*photoshop设计图尺寸*/
@phtoshop-size: 768px;
/*基字号*/
@base-font-size: 100px;
//主题色
@subject-color: #ff6a00;
//白色
@font-color-white: #fff;
//白色
@font-color-gray: #373737;
//input底色
@input-bg-color: #fa8e65;

/*媒体查询,根据屏幕尺寸设置基font-size*/
.set-screen-font-size(@i) when ( @i =< @secreen-size-list-length ) {
    @array-child: extract(@screen-size-list,@i); 
    @media ( min-width: @array-child ) {
        html {
            font-size: @array-child / ( @phtoshop-size / @base-font-size );
        }
    }
    .set-screen-font-size( @i + 1 );
}
.set-screen-font-size(1);
dpr rem适配

阿里高清方案

这个是阿里巴巴的rem布局,算法利用了屏幕的dpr,拷贝以下代码在head元素里,这个方案同样是1rem = 100px,设置元素尺寸的时候直接width÷100得到rem值

<script>!function (e) { function t(a) { if (i[a]) return i[a].exports; var n = i[a] = { exports: {}, id: a, loaded: !1 }; return e[a].call(n.exports, n, n.exports, t), n.loaded = !0, n.exports } var i = {}; return t.m = e, t.c = i, t.p = "", t(0) }([function (e, t) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); var i = window; t["default"] = i.flex = function (normal, e, t) { var a = e || 100, n = t || 1, r = i.document, o = navigator.userAgent, d = o.match(/Android[\S\s]+AppleWebkit\/(\d{3})/i), l = o.match(/U3\/((\d+|\.){5,})/i), c = l && parseInt(l[1].split(".").join(""), 10) >= 80, p = navigator.appVersion.match(/(iphone|ipad|ipod)/gi), s = i.devicePixelRatio || 1; p || d && d[1] > 534 || c || (s = 1); var u = normal ? 1 : 1 / s, m = r.querySelector('meta[name="viewport"]'); m || (m = r.createElement("meta"), m.setAttribute("name", "viewport"), r.head.appendChild(m)), m.setAttribute("content", "width=device-width,user-scalable=no,initial-scale=" + u + ",maximum-scale=" + u + ",minimum-scale=" + u), r.documentElement.style.fontSize = normal ? "50px" : a / 2 * s * n + "px" }, e.exports = t["default"] }]); flex(false, 100, 1);</script>

以上js代码会自动生成一个viewport,不要再手动设置。具体参考:dpr rem适配

*iphone5的屏幕宽只有320,按照dpr=2计算,它最大只有640的宽度,如果你在css中设置了7rem(700px)的尺寸,那么iphone5的屏幕上就会出现横向滚动条,这种情况逐一要使用width:100%解决。

*高清屏幕dpr = 2用普通图片会模糊,因为四个物理像素要共享一个设备独立像素,会导致模糊效果,请用分辨率是两倍的图片来解决。

hotcss高清方案

具体参考:移动端布局终极解决方案

此包需要支持scss才能起效。scss是sass的升级版,需要sass支持,而且需要全局的scss支持。如果你是在vue-cil and webpack中使用,你可以参考:全局引入scss(vue-cil + webpack适用),sass相关支持的包安装完成后,再使用cnpm i hotcss安装hotcss包或直接下载hotcss包后放到src/assets目录里

css目录中的main.scss是你自己创建的全局scss文件,你可以在这个文件中导入hotcss的px2rem.scss文件,以下在main.scss中导入了hotcss的相关文件,然后定义了一个变量存储颜色

@import "../hotcss/src/px2rem.scss";
$color:red;

在main.js中导入hotcss.js,必须把这个js文件放在其它导入文件之前。

import hotcss from "hotcss"; //npm装的包的导入方式,不要在index.html入口文件中导入hotcss,直接在此处导入最佳
import hotcss from './assets/hotcss/src/hotcss' //手动下载的包的导入方式

操作完以上几步后,由于你的全局main.scss文件在任何组件文件里都有定义,hotcss的px2rem也已经导入到main.scss里,所以现在在你的.vue文件中可以如下使用它们

<style scoped lang="scss">
h1, h2 {
  
  font-size:px2rem(40);   //所有需要长度单位的地方都用px2rem来设置(hotcss提供的),px2rem(100)表示100px
  color:$color; //调用了全局的main.scss的变量
}
</style>

vw适配

关于vw单位,可以参考:css3自适应布局单位vw, vh

在vue-cil项目中已经自动配置好了.postcssrc.js文件,这个文件是各种处理你的css文件的插件(比如为打包后的css添加各种css属性前缀、转换px单位)的集中配置处,目前有超过几百个针对css的插件可以使用,你只需要安装它们,然后在.postcssrc.js中注册它们即可。vw适配需要安装以下插件:

npm i 
postcss-aspect-ratio-mini 
postcss-px-to-viewport 
postcss-write-svg 
postcss-cssnext 
postcss-viewport-units 
cssnano 
cssnano-preset-advanced --S
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
  "plugins": {
    "postcss-import": {},
    "postcss-url": {},
    "postcss-aspect-ratio-mini": {},
    "postcss-write-svg": {
      utf8: false
    },
    "postcss-cssnext": {},
    "postcss-px-to-viewport": {
      viewportWidth: 750,   // 视窗的宽度,对应的是我们设计稿的宽度,一般是750
      viewportHeight: 1334, // 视窗的高度,根据750设备的宽度来指定,一般指定1334,也可以不配置
      unitPrecision: 3,     // 指定`px`转换为视窗单位值的小数位数
      viewportUnit: "vw",   //指定需要转换成的视窗单位,建议使用vw
      selectorBlackList: ['.ignore', '.hairlines'],// 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
      minPixelValue: 1,     // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
      mediaQuery: false     // 允许在媒体查询中转换`px`
    },
    "postcss-viewport-units": {},
    "cssnano": {
      preset: "advanced",
      autoprefixer: false,
      "postcss-zindex": false
    }
  }
}

配置完成后,你只需要按照曾经在pc端的写法为元素添加px值即可,插件会在打包时自动计算你的px,将其转换为vw。  

参考

postcss真的太好用了!

CSS像素、物理像素、逻辑像素、设备像素比、PPI、Viewport

css - 学习总目录

css - rem和vw的更多相关文章

  1. 理解并使用CSS3中的单位rem vh vw vmin vmax

    rem vh vw vmin vmax做为CSS3中的新单位,其实都出来挺久的了,这篇文章将总结并理解下它们. rem 如果你给body设置了font-size字体大小,那么body的任何子元素的1e ...

  2. mobile css & rem & em & px

    mobile css & rem & em & px 1 rem === 16px 任意浏览器的默认字体高都是 16px, 所有未经调整的浏览器都符合: 1em=16px, 那 ...

  3. 7个你可能不认识的CSS单位:rem vh vw vmin vmax ex ch

    rem 我们首先介绍下和我们熟悉的很相似的货.em 被定义为相对于当前对象内文本的字体大小.炒个栗子,如果你给body小哥设置了font-size字体大小,那么body小哥的任何子元素的1em就是等于 ...

  4. 关于CSS单位:rem vh vw vmin vmax

    rem(root em) 如果你给body设置了font-size字体大小,那么body的任何子元素的1em就是等于body设置的font-size demo: body {  font-size: ...

  5. css长度单位学习(em,rem,px,vw,vh)

    绝对长度单位 绝对长度单位代表一个物理测量 [像素px(pixels)] 像素,为影像显示的基本单位,译自英文"pixel",pix是英语单词picture的常用简写,加上英语单词 ...

  6. rem vh vw vmin vmax ex ch

    rem 我们首先介绍下和我们熟悉的很相似的货.em 被定义为相对于当前对象内文本的字体大小.如果你给body小哥设置了font-size字体大小,那么body小哥的任何子元素的1em就是等于body设 ...

  7. 尺寸单位em,rem,vh,vw

    这几天做demo,看了网上教程有用到尺寸单位vh,vw, 这些单位不是很熟悉,所以上网上找了些资料来认识了这些不认识的单位 1.em 在做手机端的时候经常会用到的做字体的尺寸单位 说白了 em就相当于 ...

  8. CSS3中的px,em,rem,vh,vw辨析

    1.px:像素,精确显示 2.em:继承父类字体的大小,相当于"倍",如:浏览器默认字体大小为16px=1em,始终按照div继承来的字体大小显示,进场用于移动端 em换算工具:h ...

  9. css3中单位px,em,rem,vh,vw,vmin,vmax的区别及浏览器支持情况

    原文地址: http://blog.csdn.net/jyy_12/article/details/42557241 px:绝对单位,页面按精确像素展示 em:相对单位,基准点为父节点字体的大小,如果 ...

随机推荐

  1. 高校表白App-团队冲刺第二天

    今天要做什么 今天要把昨天的activity进行完善,并且加上计时跳转的功能,将其设置为主页面,设置两种跳转功能. 遇到的问题 今天没遇到什么大的问题,只是在进行编写的时候,又出现了R文件无法找到的情 ...

  2. Java基础00-方法引用32

    1. 方法引用 Java8新特征之方法引用 1.1 体验方法引用 代码示例: 需求: 1:定义一个接口(Printable):里面定义一个抽象方法: void printString(String s ...

  3. [刘阳Java]_Java基础面试中的常识问题

    1. anonymous inner class(匿名内部类)是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)? 不行,对于匿名内部类,看到的一句话 ...

  4. [刘阳Java]_Spring AOP注解详细介绍_第8讲

    这节内容非常关键,我们会比较详细地介绍Spring AOP注解的使用 1. 要使用Spring AOP注解,必须满足如下的事项 导入Aspectj的jar.Spring3.0-AOP.jar.aopa ...

  5. vite插件-自动生成vue组件文档

    特点 支持热更新 快速启动,依赖于 vite,无需另起服务 自动生成组件导航 ui 采用了vant-ui的样式 核心方法覆盖率达到了 92.86% 使用 yarn add vite-plugin-vu ...

  6. PAT乙级:1015 德才论 (25分)

    1015 德才论 (25分) 宋代史学家司马光在<资治通鉴>中有一段著名的"德才论":"是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人 ...

  7. Spring Boot Mail通过QQ邮箱发送邮件

    本文将介绍如何在Spring Boot工程完成QQ邮箱配置,实现邮件发送功能. 一.在pom文件中添加依赖 <dependency> <groupId>org.springfr ...

  8. IOS自动化测试环境搭建(Python & Java)

         一.前言 IOS的App自动化测试与Android的一样,也可以用appium来进行.但是IOS自动化依赖苹果的osx系统.Xcode构建等,且封闭的系统需要苹果开发者账号才可以驱动真机.A ...

  9. FreeRTOS-04-内核控制函数+时间管理函数

    说明 本文仅作为学习FreeRTOS的记录文档,作为初学者肯定很多理解不对甚至错误的地方,望网友指正. FreeRTOS是一个RTOS(实时操作系统)系统,支持抢占式.合作式和时间片调度.适用于微处理 ...

  10. [C++]-string类的常用操作

    代码 #include<iostream> #include<string> #include<algorithm> using namespace std; in ...