一、移动端基础


1. 移动端浏览器现状

① 兼容性问题:目前国内尚无自主研发的内核,绝大多数浏览器的内核都是以 Webkit 为基础修改而来。
② 分辨率问题:移动端设备的屏幕尺寸非常多,分辨率也多样化,但作为开发者无需关注这些,用 px 即可。

2. 移动端开发选择

① 单独制作移动端页面【主流】:浏览器自动判断访问的设备,如果是移动设备则跳转至移动端专用的页面
② 制作响应式页面可兼容移动端【其次】:根据屏幕的宽度来改变样式,可适配各种尺寸的屏幕 (PC/移动端)

3. 移动端技术解决方案

① 移动端浏览器基本以 Webkit 内核为主,因此我们开发时主要考虑 Webkit 的兼容性问题即可。
② Webkit 支持 HTML5 与 CSS3,可放心使用它们。
③ 移动端的 CSS 初始化,推荐使用 normalize.css,官网 https://necolas.github.io/normalize.css/
④ 移动端开发推荐新的盒子模型

  • box-sizing: border-box; // padding 和 border 不会撑大盒子的宽高

⑤ 移动端常用的特殊样式代码:

  1. /* 点击高亮我们需要清除 设置为 transparent 完成透明 */
  2. * { -webkit-tap-highlight-color: transparent; }
  3. /* 在 iOS 上加上这个属性才能给按钮和输入框自定义样式 */
  4. input { -webkit-appearance: none; }
  5. /* 禁用长按页面时的弹出菜单 */
  6. img, a { -webkit-touch-callout: none; }

4. 视口【viewport】

① 定义:视口就是浏览器显示页面内容的屏幕区域。
② 分类:布局视口、视觉视口、理想视口。

③ 布局视口(layout viewport)

  • 作用:
    • 布局视口用于解决早期的PC端页面在手机上显示的问题,iOS、Android 将其设置为 980px,
    • 所以PC上的网页大多都能在手机上呈现,只不过元素看上去很小。
  • 总结:目前布局视口已经不适合做移动端页面开发,了解即可。

③ 视觉视口(visual viewport)

  • 作用:
    • 视觉视口是用户正看到的网站的区域;
    • 我们可以通过缩放操作去操作视觉视口,但不会影响布局视口,布局视口仍保持原来的宽度。
  • 总结:目前 视觉视口 已经不适合做移动端页面开发,了解即可。

③ 理想视口(ideal viewport)【重点】

  • 作用:
    • 为了使网站在移动端有最理想的浏览和阅读宽度而设定,需要手动添加 meta 标签通知浏览器;
    • 添加 meta 视口标签,使布局视口的宽度与理想视口的宽度一致,即设备有多宽,布局视口就多宽。
  • 总结:开发时添加 meta 视口标签,利用理想视口开发移动端页面。

④ meta 视口标签
【语法格式】

  • <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

【属性说明】

  • width:设置 视口viewport 的宽度,特殊值 device-width 可自动获取设备的宽度。
  • user-scalable:规定用户能否对网页进行缩放,yes(1) 或 no(0)。
  • initial-scale:初始的缩放倍数,大于 0 的数字。
  • maximum-scale:允许最大的缩放倍数,大于 0 的数字。
  • minimum-scale:允许最小的缩放倍数,大于 0 的数字。

    5. 多倍图

    ① 物理像素点 & 物理像素比

  • 物理像素点:

    • 即屏幕显示的最小颗粒,是真实存在的一个发光像素点 ( pixel );
    • 但进行移动端开发的时候 1px 不一定就等于1个物理像素点,根据屏幕不同的尺寸会有不同的比例。
  • 物理像素比:
    • 1px 能显示的物理像素点的个数,称之为物理像素比;
    • 例如,开发 : 实际,iPhone 6/7/8 的物理像素比是 1 : 2。

② 多倍图

  • 出现契机:现在的手机屏幕尺寸不大,但像素数量越来越多,即单位面积下的像素量翻了许多倍;
  • 问题暴露:原本50 * 50px的图片,在手机上会被放大一定倍数(像素比),于是图片就变糊了;
  • 解决方法:准备像素尺寸更大(更清晰)的图片,然后在CSS中手动缩小,这样在手机上看就不糊了。

③ background-size【CSS3新属性】
【语法】

  • background-size: 图片宽度 图片高度; // 单位为 px,也可以是百分比
  • background-size: 图片宽度; // 只写一个参数,相当于只指定宽度,高度会进行等比例缩放
  • background-size: n%; // 即指定宽度为盒子的n%,高度会进行等比例缩放
  • background-size: cover; // 按比例扩展背景图,使其能完全 覆盖 背景区域,图片可能会显示不全
  • background-size: contain; // 按比例扩展背景图,使宽度或高度能 适应 背景区域,背景区域可能会留白

【示例】

img {
  /* 原始图片尺寸 100 * 100px */
  width: 50px;
  height: 50px;
}
.box {
  /* 原始图片尺寸 100 * 100px */
  background: url(xxx/xxx.jpg) no-repeat;
  background-size: 50px auto;  // 确定了图片宽度后,图片高度可以用 auto 代替
}

④ 切图:使用PS的Cutterman插件可很方便地切出一倍、二倍、三倍图。

6. 多倍精灵图

① 新手的操作:用 background-position 定位好后直接用 background-size 进行缩小;
② 出现的问题:background-size 缩小的是整张精灵图,这时候的定位就不准确了。
③ 解决方法:先在 Fireworks 里手动把精灵图缩小(n倍图就缩小至n/1),再进行测量,之后的操作如上。

二、移动端常见布局


1. 流式布局【百分比布局】

① 特性:把盒子的宽度设置为百分比,并根据屏幕的宽度来进行收缩,这样就不会受到固定像素的限制。
② 搭配:盒子的宽度设置为百分比后,可以添加两个限制 -> max-width & min-width

  • max-width / max-height:最大宽度 / 最大高度
  • min-width / min-height:最小宽度 / 最小高度

    2. Flex 弹性布局【重点】

    ① 技术现状

  • 操作方便,布局简单,在移动端应用广泛;

  • PC 端浏览器支持情况较差;
  • IE 11 仅部分支持,更低版本的 IE 甚至不支持。

② 布局原理

  • 任何元素都可以指定为 flex 布局,采用此布局的元素称为”容器”,其子元素称为”项目”;
  • 为父元素设置为 flex 布局后,子元素的 float、clear 和 vertical-align 属性将会失效;
  • 布局原理就是通过给父元素添加 flex 属性display: flex;,来控制子元素的位置和排列方式。

③ 主轴与侧轴:在 flex 布局中,分 主轴 和 侧轴 两个方向(其他叫法:X轴与Y轴、主轴与交叉轴)

  • 默认主轴的方向就是 X轴 的方向,水平向右;
  • 默认侧轴的方向就是 Y轴 的方向,垂直向下;

【注意1】主轴和侧轴只是一个称呼,是可以相互交换的,用 flex-direction 设置主轴的方向,另一边就是侧轴。
【注意2】子元素按主轴的方向进行排列,排列的起始点是主轴的原点,若主轴方向发生改变,则排列的起始点也会变。
④ 常用父元素属性
1) flex-direction :设置主轴的方向
【属性值】

  • row;默认值,从左到右
  • row-reverse;从右到左,会改变子元素自身的排列顺序
  • column;从上到下
  • column-reverse;从下到上,会改变子元素自身的排列顺序

2) flex-warp :设置子元素是否换行
【注意】flex 布局中默认子元素永不换行,若父元素装不下,则会自动缩小每个子元素的宽度,直至全部装下
【属性值】

  • nowarp;默认值,不换行
  • warp;允许换行,往下走
  • warp-reverse;允许换行,往上走

3) flex-flow :复合属性,同时设置 flex-direction + flex-warp
【例】flex-flow: column warp;

4) justify-content :设置主轴上的子元素排列方式
【注意】使用这个属性之前一定要确定好主轴是哪个轴!
【属性值】

  • flex-start;默认值,从头部开始
  • flex-end;从尾部开始(相当于子元素整体往尾部靠拢,不改变子元素自身的排列顺序)
  • center;子元素贴在一起在主轴上居中对齐(在X轴上就是水平居中对齐,在Y轴上就是垂直居中对齐)
  • space-around;所有子元素平均分配父元素在主轴方向上的剩余空间(分配的是外边距)
  • space-between;先两边贴边,再给每个子元素平均分配主轴方向上的剩余空间(重要)

5) align-items :设置侧轴上的子元素的排列方式【单行】
【注意】使用这个属性之前一定要确定子元素在父元素内只有一行,出现换行的话是没有效果的!
【属性值】

  • stretch;默认值,子元素独占父元素在侧轴方向上的所有空间(前提是父元素有侧轴方向上的长度而子元素没有)
  • flex-start;从头部开始排列
  • flex-end;从尾部开始排列(相当于子元素整体往尾部靠拢,不改变子元素自身的排列顺序)
  • center;子元素贴在一起在侧轴上居中对齐(在X轴上就是水平居中对齐,在Y轴上就是垂直居中对齐)
  • baseline;根据子元素内文本的基准线对齐,使得所有文本在同一条基准线上(基准线:英文字母 x 底部所在的水平线)

6) align-content :设置侧轴上的子元素的排列方式【多行】
【注意1】使用这个属性之前一定要确定子元素在父元素内出现换行,只有一行的话是没有效果的!
【注意2】该属性没有默认值,必须手动设置!
【属性值】

  • flex-start;从头部开始
  • flex-end;从尾部开始(相当于子元素整体往尾部靠拢,不改变子元素自身的排列顺序)
  • center;所有子元素贴在一起在侧轴上居中对齐(在X轴上就是水平居中对齐,在Y轴上就是垂直居中对齐)
  • stretch;子元素平分父元素在侧轴方向上的所有空间(前提是父元素有侧轴方向上的长度而子元素没有)
  • space-around;所有子元素平均分配父元素在侧轴方向上的剩余空间(分配的是外边距)
  • space-between;先两边贴边,再给每个子元素平均分配侧轴方向上的剩余空间(重要)

⑤ 常用子元素属性
1) flex-basis :定义子元素在主轴上的长度
【属性值】(数值 + 单位) / auto;
【注意】

  • 如果 flex-direction: row / row-reverse; 那么 flex-basis 的值会覆盖子元素的宽度 width 。
  • 如果 flex-direction: column / column -reverse; 那么 flex-basis 的值会覆盖子元素的高度 height 。

2) flex-grow :在主轴方向上存在多余的宽度时,定义单个子元素能额外获得多少宽度
【运行原理】

  • 首先统计所有子元素内该属性的值的和,然后用多余宽度除以这个和,得到的就是单位宽度;
  • 最后各个子元素的 flex-grow 值 (份数) 乘以单位宽度,就是它们各自分配到的额外宽度(累加到 width 或 height 上)。

【属性值】

  • [number];填数字即可,默认为 0,即不会获得额外宽度。
  • [百分比];默认为 0,效果就是按照百分比分配剩余宽度。

3) flex-shrink :在主轴方向上宽度不足时,定义单个子元素需要如何减少自身的宽度
【运行原理】大致同上,这里的单位宽度是由超出宽度除以 flex-shrink 值的和而得到的。
【属性值】[number];填数字即可,默认为 1,即所有子元素都会自动收缩并且平分总宽度。

3) flex :flex-grow、flex-shrink、flex-basis 三种属性的综合写法
【语法】flex: flex-grow flex-shrink flex-basis;

5) align-self :控制单个子元素在侧轴上的排列方式
【注意】该属性允许单个子元素拥有与其它子元素不同的排列方式,因此会覆盖 align-items 属性的效果
【属性值】

  • auto;默认值,即继承父元素的 align-items 属性的效果;若没有父元素,则等同于 stretch
  • stretch;子元素独占父元素在侧轴方向上的所有空间(前提是父元素有侧轴方向上的长度而子元素没有)
  • flex-start;从头部开始排列
  • flex-end;从尾部开始排列(相当于子元素整体往尾部靠拢,不改变子元素自身的排列顺序)
  • center;子元素贴在一起在侧轴上居中对齐(在X轴上就是水平居中对齐,在Y轴上就是垂直居中对齐)
  • baseline;根据子元素内文本的基准线对齐,使得所有文本在同一条基准线上(基准线:英文字母 x 底部所在的水平线)

6) order :定义子元素的排列顺序(先后顺序)
【注意】数值越小,排列越靠前!可用于实现元素置顶效果。
【属性值】[number];填数字即可,默认为 0,可以填负数。

⑥ 常见 Flex 布局下功能入口的代码思路

  • 在 Flex 布局内,所有子元素都按照主轴方向排列,默认 X 轴,而大部分功能入口都是图标 + 文字的 Y 轴排列;
  • 所以我们需要为每个功能入口盒子加一个 display: flex; 然后设置主轴为 Y 轴 flex-direction: column;
  • 最后,在侧轴上设置 align-items: center; 使图标 + 文字在 X 轴上居中对齐,效果就更好了。

    3. rem单位 + 媒体查询 + less语法

    ① rem单位

  • rem 即 root em 的缩写,是一个相对长度单位,类似于 em。

  • em 也是相对长度单位,它相对于当前元素的字体大小,即 font-size。
  • 假如当前元素的 font-size 为 12px(没有则继承父元素的),那么 1em = 12px。
  • rem 与 em 不同的是,rem 的基准是根 (root) 元素即 元素中定义的字体大小。
  • rem 优点:
    • 因为网页中 元素只有一个,那么 1rem 的值只有一种,不像 em 那样多变;
    • 又因为统一了基准,那么以后只需要修改 元素中的字体大小,即可实现全局修改。

② 媒体查询【Media Query】

  • 简介:
    • 使用 @media 查询,可以针对不同的媒体类型定义不同的样式;
    • @media 可以针对不同的屏幕尺寸设置不同的样式;
    • 在你重置浏览器大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面;
    • 目前针对很多苹果手机、Android手机、平板等设备都用得到多媒体查询。
  • 语法:

    @media mediatype  and | not | only  (media feature) {
      [CSS-Code];
    }
    

    【说明】

  • 用 @media 开头,注意@符号(与CSS动画类似 @keyframes);

  • mediatype 即媒体类型(打印机、手机屏幕、电脑屏幕等);
    • 值:all(用于所有设备)、print(用于打印机和打印预览)、screen(用于设备屏幕等)
  • 关键字 and | not | only(三种关键字,用于连接媒体类型与媒体特性);
    • and:可以将多个媒体特性连接到起,相当于“且”的意思,不可省略。
    • not:排除某个媒体类型,相当于“非”的意思,可以省略。
    • only:指定某个特定的媒体类型,可以省略。
  • media feature 即媒体特性,必须用小括号包含。
    • width:定义输出设备中页面可见区域的宽度(等于 = )
    • min-width:定义输出设备中页面最小可见区域宽度(大于等于 >= )
    • max-width:定义输出设备中页面最大可见区域宽度(小于等于 <= )

【例1】媒体查询可以根据不同的屏幕尺寸在改变不同的样式

/* 媒体查询 max-width 的最好的书写顺序是从大到小 */
/* 利用CSS层叠性可让 max-width: 500px 的效果覆盖 max-width: 800px 的效果 */
@media screen and (max-width: 800px) {
  body {
    background-color: pink;
  }
}
@media screen and (max-width: 500px) {
  body {
    background-color: purple;
  }
}
/* 以上两句规定 0~500px 时背景色为 purple,501~800px 时为 pink,大于 800px 时则默认为白色 */

【例2】注意我们的最大值 max-width 和最小值 min-width 都是包含等于号的,所以需要提前计算好界限值。

  • 当屏幕小于 540px 时,背景颜色变为蓝色( x <= 539 )
  • 当屏幕大于等于 540px 并且小于 970px 时,背景颜色为绿色( 540 =< x <= 969 )
  • 当屏幕大于等于 970px 时,背景颜色为红色( x >= 970 )

    @media screen and (max-width: 539px) {
    body {
      background-color: blue;
    }  
    }
    /* 媒体查询 min-width 的最好的书写顺序是从小到大 */
    /* 利用CSS层叠性可让 min-width: 970px 的效果覆盖 min-width: 540px 的效果 */
    @media screen and (min-width: 540px) {
    body {
      background-color: green;
    }
    }
    @media screen and (min-width: 970px) {
    body {
      background-color: red;
    }
    }
    

    3)媒体查询 + rem 实现元素动态的大小变化
    【例1】根据屏幕宽度改变元素各项属性的大小

    <style>
        /* 根据屏幕宽度改变<html>元素内设定的字体尺寸 */
      @media screen and (min-width: 320px) {
          html {
              font-size: 50px;
          }
      }
      @media screen and (min-width: 640px) {
          html {
              font-size: 100px;
          }
      }
        /* <html>元素内设定的字体尺寸发生变化的话,.top 的各种属性也会发生变化 */
      .top {
          height: 1rem;
          font-size: 0.5rem;
          background-color: green;
          color: #fff;
          text-align: center;
          line-height: 1rem;
      }
    </style>
    <body>
      <div class="top">购物车</div>
    </body>
    

    【例2】根据屏幕宽度改变 .css 文件

    <head>
      /* 当屏幕宽度大于等于 320px 时,引用这个css文件 */
      <link rel="stylesheet" href="style320.css" media="screen and (min-width: 320px;)" >
      /* 当屏幕宽度大于等于 640px 时,引用这个css文件 */
      <link rel="stylesheet" href="style640.css" media="screen and (min-width: 640px;)" >
    </head>
    

    ③ Less 基础
    1)介绍

  • Less ( Leaner Style Sheets 的缩写 ) 是一门CSS扩展语言,也成为了CSS预处理器。作为CSS的一种形式的扩展,它并没有减少CSS的功能,而是在现有的CSS语法上为CSS加入程序式语言的特性。

  • 它在CSS的语法基础之上引入了变量、Mixin(混入)、运算以及函数等功能,大大简化了CSS的编写,成功降低了CSS的维护成本,就像它的名称所说的那样,Less可以让我们用更少的代码做更多的事情。

2)Less 编译
【编译原因】浏览器不能识别 .less 文件,需要把它编译生成 .css 文件,才能应用于 html 页面上。
【编译方法】在 IDE 内安装 Less 编译器插件。
3)Less 变量
【语法】@变量名: 值; // 调用变量时直接写 @变量名
【规范】必须以 @ 作为前缀、不能包含特殊字符、不能以数字开头、大小写敏感

/* 声明变量 */
@color: pink;
/* 调用变量 */
div {
  color: @color;
  background-color: @color;
}

4)Less 嵌套
【说明1】对于父元素和子元素的样式代码,它们在 Less 文件中以嵌套的格式存在。

<!-- HTML 文件 -->
<div class="header">
  <a href="#">123</a>
</div>
/* LESS 文件 */
.header {
  width: 200px;
  height: 200px;
  background-color: pink;

  a {
    color: blue;
  }
}

【说明2】

  • 对于交集、伪类、伪元素选择器,运用 & 符号来进行区分:
  • 如果嵌套内层选择器的前面没有 & 符号,则它会被解析为父元素的后代的选择器;
  • 如果嵌套内层选择器的前面有 & 符号,则它会被解析为父元素的伪类 / 伪元素的选择器。

    /* LESS 文件 */
    .header {
    width: 200px;
    height: 200px;
    background-color: pink;
    
    a {
      color: blue;
      /* a标签的伪类 */
      &:hover {
        color: green;  
      }
    }
    
    /* 类 .header 的伪元素 */
    &::after {
      cotent: "";
    }
    }
    

    5)Less 运算
    【说明】任何数字、颜色或者变量都可以参与运算(加减乘除)。
    【用法】在属性后直接写上运算符和数字即可,切记不要忘记写单位。
    【注意】

  • 运算符左右都需要有个空格隔开;

  • 对于两个不同的单位的值之间的运算,运算结果的值取第一个值的单位;★重要★
  • 如果两个值之间只有一个值有单位,则运算结果就取该单位。

【例子】

  • width: 200px + 50;
  • height: 80 / 52rem;
  • font-size: (@变量 + 5) * 3px;

④ 综合以上三种技术的适配方案
【简单说明】

使用媒体查询根据不同设备按比例设置 html 的字体大小,然后页面元素使用 rem 做尺寸单位; 当 html 字体大小发生变化,元素尺寸也会发生变化,从而达到等比缩放的适配。

【详细步骤】
1)假设设计稿是 750px
2)假设我们把整个屏幕划分为15等份(划分标准不一,可以是10份也可以是20等份)
3)每一份作为字体大小,这里就是 750/15 = 50px
4)那么在宽度为 320px 的设备里,字体大小为 320/15 = 21.33px
5)用我们页面元素的大小除以不同的字体大小会发现他们比例还是相同的
【公式总结】
1)先确定 设计宽度 和 屏幕划分份数,则可知 字体大小 = 设计宽度 / 屏幕划分份数;
2)于是可知 页面元素的 rem 值 = 页面元素的 px 值 / 字体大小。

【例】比如我们以 750px 为标准设计稿
1)一个 100100px 的页面元素在 750px 宽度下,就是 100/50 转换为rem是 2rem2rem,比例是1比1
2)320px 宽度下,字体大小为 21.33px,此时宽和高都是 42.66px,而且宽和高的比例还是1比1
3)所以就实现了不同屏幕下页面元素盒子等比例缩放的效果
【common.less 文件】
1)设置好常见的屏幕尺寸,利用媒体查询设置不同的字体大小,这样除了首页其他页面也能使用
2)需设置的尺寸有320px 360px 375px 384px 400px 414px 424px 480px 540px 720px 750px
3)屏幕划分的份数定为15份,这句话记得写出来让其他开发者知道!
4)因为PC端也可以打开,我们默认字体大小为50px,这句话一定要写在文件最上面!
5)在其他页面使用该 less 文件,用 @import “xxx\common” 语句即可,注意路径是否正确。

【例】common.less 示例

/* PC端打开则默认<html>字体大小为50px */
html {
  font-size: 50px;
}
/* 屏幕划分的份数定为15份 */
@num: 15;
/* 设置常见的屏幕尺寸,更改里面的<html>文字尺寸大小 */
@media screen and (min-width: 320px) {
  html {
    font-size: 320px / @num;
  }
}
@media screen and (min-width: 360px) {
  html {
    font-size: 360px / @num;
  }
}
// iPhone6/7/8 的宽度为375px
@media screen and (min-width: 375px) {
  html {
    font-size: 375px / @num;
  }
}
/* 以下省略 */
@media screen and (min-width: ???px) {
  . . .
}