欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

像素理论、视口理论及移动端适配

程序员文章站 2024-01-24 17:34:10
...

首先需要说明一点,css像素不等同于物理像素,css像素是一个抽象单位,而物理像素是实实在在,大小固定的像素点。


一、做移动端需要了解的四个像素

  • 物理像素
    物理像素的实际大小及个数由设备本身决定。

  • 设备独立像素
    设备独立像素也是根据设备而定,生产出来就固定不变,iPhone6的设备独立像素是375 X 667。当你打开浏览器开发者模式,调成移动端就可以看到,它是css像素转换成最终物理像素的一个重要媒介。

  • CSS像素
    css像素浏览器上的概念,在没有做适配之前,它和实际物理尺寸扯不上半毛钱关系,css像素大小是随用户放大或缩小而改变的。最终转换成物理像素到设备上成像。

  • 位图像素
    图片尺寸相关的像素单位,如果一个位图像素刚好放在一个物理像素上成像,那么这时的显示效果最好,如果一个位图像素交给多个物理像素来显示则会失真(放大),如果一个物理像素要塞下多个位图像素,则会锐化。

二、像素比

  • 概念:在一个方向上(如X轴上)占满一块屏幕所需要的物理像素个数 / 所需要的设备独立像素个数
    好,那么来算一下iPhone6的像素比 :iPhone6的X轴上的物理像素个数为750 ,而iPhone6的X轴上的设备独立像素为375 ,所以像素比为750 / 375 = 2
    像素理论、视口理论及移动端适配

  • 如果按面积来比就不是2了

三、视口


  移动端是如何将PC端的站点放到屏幕里面显示而不产生横向滚动条的呢?
  • 布局视口
    布局视口的尺寸各浏览器厂商提供了一个默认值,它决定页面元素要不要换行,移动端缩放操作不影响布局视口,而PC端缩放会影响布局视口。
    像素理论、视口理论及移动端适配
    一般PC端页面960 css像素

  • 视觉视口
    视觉视口的实际面积其实就是屏幕大小,但是它的尺寸是会改变的,因为他的单位是CSS像素,当你放大页面,你屏幕上的CSS像素点面积逐渐变大,屏幕所能呈现的CSS像素个数逐渐变少,所以视觉视口的尺寸逐渐变小,不要觉得这是谬论,你可以调用API取出视觉视口大小,当你一边放大页面,这个值一边变小。默认移动端的视觉视口是980CSS像素,这就意味着你移动端屏幕可以看到整张网页,视觉视口的作用就是为了要包住整张网页。

  • 将布局视口的大小设置为设备独立像素的尺寸
<meta  name="viewport"  content="width = device-width"/>


四、缩放

  • 用户缩放
    用户缩放改变的是视觉视口,不会改变布局视口
  • 系统缩放
    系统缩放是指设置initial-scale=xx来进行缩放,系统缩放会改变布局视口和视觉视口

五、获取各视口宽度

  • 布局视口
   let width = document.documentElement.clientWidth
  • 视觉视口
   let width = window.innerWidth


六、设置完美视口

<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0,maximum-scale=1">
  • width=device-width 将布局视口尺寸设置为设备独立像素尺寸。
  • initial-scale=1 将缩放比设为1,并将布局视口和视觉视口尺寸设置为设备独立像素尺寸。
  • maximum-scale=1 maximum-scale=1 IOS不支持initial-scale,所以要设置最大缩放和最小缩放。
  • user-scalable=0 禁止用户缩放


七、适配

  设置完完美视口就会产生一个问题:在不同设备上元素的高宽比不一样,因为不同的设备布局视口大小不一样,iPhone6为375 css单位 ,而iPhone6plus为414css单位,而你的代码写10px时,所占据的屏幕比例是不一样的,所以就需要我们做适配工作。
  • rem适配方案
    rem适配的前提是已经设置了完美视口,已经将布局视口的宽度设置成了设备独立像素的宽度。然后将跟标签的font-size大小设置为布局视口的大小,或者布局视口的百分之多少,如布局视口的1 / 16 ,那么 16rem 就占据整个屏幕宽度,8rem就占据宽度的一半,所有设备上都一样。

  • 一份最粗糙的rem适配代码
  <!DOCTYPE html>
  <html>

  <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,
      initial-scale=1,maximum-scale=1,user-scalable=0,maximum-scale=1">
      <title>菜鸟教程(runoob.com)</title>
      <style>
      * {
          margin: 0;
          padding: 0;
      }

      .re {
          width: 180px;
          height: 8em;
          background: #000;
      }
      </style>
  </head>

  <body>

      <div class="re"></div>

  </body>
  <script>
      // 将跟标签的字体大小设置为布局视口宽度
      var rSize = document.documentElement.clientWidth;
      console.log(rSize);
      // 获取跟标签
      var html = document.querySelector('html');
      html.style.fontSize = rSize/16+'px';

      // 以上代码会有一个问题:根标签的font-size有可能会被改变
      // 所以要加上!important

      let style = document.createElement("style")
      let rSize = document.documentElement.clientWidth/16
      // 16分之1的布局视口大小
      style.innerHTML = "html{ font-size: "+ rSize + "px!important }"
      document.head.appendChild(style)
  </script>
  </html>
  • viewport适配方案
    viewport适配方案的思路是将布局视口的宽度设置为设计图的宽度,但是安卓手机是不允许直接设置布局视口宽度,所以就需要通过设置 initial-scale值来改变布局视口大小,这个值的大小为:设备独立像素 / 设计图位图像素

  • 一份viewport适配方案代码
<!DOCTYPE html>
    <html>

    <head>
        <meta charset="utf-8">
        <!--  先将设备独立像素大小赋值给布局视口值,之后替换掉 -->
        <!--  因为js暂时没法直接读取设备独立像素 -->
        <meta name="viewport" content="width=device-width>
        <title>菜鸟教程(runoob.com)</title>
        <style>
        * {
            margin: 0;
            padding: 0;
        }

        .re {
            width: 180px;
            height: 8em;
            background: #000;
        }
        </style>
    </head>

    <body>

        <div class="re"></div>

    </body>
    <script>
        var target = 375;
        var scale = document.documentElement.clientWidth/target;
        console.log(scale)
        var meta = document.querySelector("meta[name='viewport']")
        meta.content = "initial-scale="+scale+",maximum-scale="+scale+",user-scalable=0,maximum-scale="+scale
    </script>
    </html>