移动端适配方案

159 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1.视口相关

<meta name='viewport' content='width=device-width,initial-scale=1,user-scaleable=no' />

手机浏览器,如果不做任何调整,所有手机得到的默认宽度都是980px

属性名取值描述
width正整数或device-width定义视口的宽度,单位为像素
height正整数或device-height定义视口的高度,单位为像素,一般不用
initial-scale[0.0-10.0]定义初始缩放值
minimum-scale[0.0-10.0]定义缩放的最小值,它必须小于或等于maximum-scale 设置
maximum-scale[0.0-10.0]定义缩放的最大值,它必须大于或等于minimum-scale 设置
user-scalableyes / no定义是否允许用户手动缩放页面,默认值 yes

2.为什么要设置视口

viewport 的设置不会对 PC 页面产生影响,但对于移动页面却很重要

媒体查询 @media响应式布局中,会根据媒体查询功能来适配多端布局,必须对 viewport 进行设置,否则根据查询到的尺寸无法正确匹配视觉宽度而导致布局混乱。

如不设置 viewport 参数,多数移动端媒体查询的结果将是 980px 这个节点布局的参数,而非我们通常设置的 768px 范围内的这个布局参数。

**像素比DPR **

像素比(DPR) = 物理像素/逻辑像素

  • 1920*1080 物理像素(一个个的发光二极管)
  • 1660*900 逻辑像素 (用多个发光二极管显示一个像素的内容)
  • 1440 * 800 逻辑像素

由于目前多数手机的 dpr 都不再是 1,为了产出高保真页面,我们一般会给出 750px 的设计稿,那么就需要通过设置 viewport 的参数来进行整体换算,而不是在每次设置尺寸时进行长度的换算。

3.适配

  1. 如何在移动端实现一个宽度50%的元素

  2. 如何保证这个元素在任何地方任何位置都是50%

    在页面中的元素,其实占用固定的比例,不管手机多大多小,都能完整的显示页面,并且没有结构上的差异。

  • 适配方案 - vm
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=no">
    <title>Document</title>
     <style>
        body{
            margin: 0;
        } 
        .box{
            width:calc(375vw/7.5);
            height: 50px;
            background-color: #ee6600 ;
        }
    </style>
</head>
<body>
    <!-- 1vw = 屏幕宽度的百分之一; 1vh = 屏幕高度的百分之一 -->
    <!-- 750px设计图 = 100vw => 1vw = 7.5px  -->
    <div class="box"></div>
</body>
</html>
  • 适配方案 - rem

    1. 分割屏幕 width / 25
    2. 分割设计图 750px / 25 = 30px → 1rem = 30px
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        html{
            font-size: 4vw;
        } 
        body{
            margin: 0;
        } 
        .box{
            width:calc(375rem/30);
            height: 50px;
            background-color: #ee6600 ;
        }
    </style>
    <script>
        let rootEl = document.documentElement;
        let viewWidth = window.innerWidth;
        rootEl.style.width = viewWidth / 25 + 'px' 
    </script>
</head>
<body>
    <!-- em   相对于当前元素的font-size大小 -->
    <!-- rem  相对于根元素(html)的font-size大小 -->
    <!-- 屏幕分成 25份 => html-font-size =  width / 25 = 4vw -->
    <!-- 设计稿750px分成 25份 => 750 / 25 = 30px => 1rem = 30px-->

    <div class="box"></div>
</body>
</html>

4.像素

(1)物理像素(physical pixel)

手机屏幕上显示的最小单元,该最小单元具有颜色及亮度的属性可供设置。(屏幕上有多少个发光二极管)

(2)设备独立像素(density-indenpendent pixel)

此为逻辑像素,计算机设备中的一个点,css 中设置的像素指的就是该像素。老早在没有 retina 屏之前,设备独立像素与物理像素是相等的。

(3)设备像素比(device pixel ratio)

设备像素比(dpr) = 物理像素/设备独立像素。如 iphone 6、7、8 的 dpr 为 2,那么一个设备独立像素便为 4 个物理像素,因此在 css 上设置的 1px 在其屏幕上占据的是 2个物理像素,0.5px 对应的才是其所能展示的最小单位。这就是 1px 在 retina 屏上变粗的原因,目前有很多办法来解决这一问题。

5.flex

作用在父级身上的属性

flex-direction: row | row-reverse | column | column-reverse;
/*用来控制子项整体布局方向,是从左往右还是从右往左,是从上往下还是从下往上。*/
flex-wrap: nowrap | wrap | wrap-reverse;
/*用来控制子项整体单行显示还是换行显示,如果换行,则下面一行是否反方向显示。*/
flex-flow: <‘flex-direction’> || <‘flex-wrap’>
/*是flex-direction和flex-wrap的缩写*/
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
/*属性决定了水平方向子项的对齐和分布方式*/
align-items: stretch | flex-start | flex-end | center | baseline;
/*子项们相对于flex容器在垂直方向上的对齐方式*/
align-content: stretch | flex-start | flex-end | center | space-between | space-around | space-evenly;
/*针对多行子项们相对于flex容器在垂直方向上的对齐方式*/

作用在子级身上的属性

order: <integer>;
flex-grow: <number>;/* 数值,默认值是 1 */
/*flex-grow属性中的grow是扩展的意思,扩展的就是flex子项所占据的宽度,扩展所侵占的空间就是除去元素外的剩余的空白间隙。*/
flex-shrink: <number>; /* 数值,默认值是 1 */
/*shrink是“收缩”的意思,flex-shrink主要处理当flex容器空间不足时候,单个元素的收缩比例。*/
flex-basis: <length> | auto; /* 默认值是 auto */
/*定义了在分配剩余空间之前元素的默认大小。相当于对浏览器提前告知我要占据这么大的空间,提前帮我预留好。*/
flex: none | auto | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
/*flex属性是flex-grow,flex-shrink和flex-basis的缩写。*/
align-self: auto | flex-start | flex-end | center | baseline | stretch;

在Flex布局中,flex子元素的设置floatclear以及vertical-align属性都是没有用的。