CSS布局总结(float、flex、grid、position、响应式布局)| 青训营

154 阅读17分钟

1_float 浮动布局

1.1_认识

  • 可指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它

    • 最初只用于在一段文本内浮动图像, 实现文字环绕的效果

    • 早期的CSS标准中并没有提供好的左右布局方案, 因此在一段时间里面它成为网页多列布局的最常用工具

  • 绝对定位、浮动都会让元素脱离标准流,以达到灵活布局的效果

  • 常用取值

      none:不浮动,默认值

      left:向左浮动

      right:向右浮动


1.2_浮动规则

浮动规则一

  • 元素一旦浮动后, 脱离标准流,朝着向左或向右方向移动,直到自己的边界紧贴着包含块(一般是父元素)或者其他浮动元素的边界为止

  • 层叠大小比较:普通元素<浮动元素<定位元素

浮动规则二:如果元素是向左(右)浮动,浮动元素的左(右)边界不能超出包含块的左(右)边界

浮动规则三:浮动元素之间不能层叠

  如果一个元素浮动,另一个浮动元素已经在那个位置了,后浮动的元素将紧贴着前一个浮动元素(左浮找左浮,右浮找右浮)

  如果水平方向剩余的空间不够显示浮动元素,浮动元素将向下移动,直到有充足的空间为止

浮动规则四:浮动元素不能与行内级内容层叠,行内级内容将会被浮动元素推出

  比如行内级元素、inline-block元素、块级元素的文字内容

浮动规则五::行内级元素、inline-block元素浮动后,其顶部将与所在行的顶部对齐

1.3_案例练习

案例一:百度搜索的页码

百度搜索的页码.jpg

  <style>
    /* 样式的重置 */
    ul, li {
      list-style: none;
      padding: 0;
      margin: 0;
    }

    a {
      text-decoration: none;
      color: #333;
    }

    /* 全局设置 */
    body {
      background-color: #f2f2f2;
    }

    /* 内容样式 */
    ul > li {
      float: left;
      margin-left: 12px;
    }

    ul > li > a {
      display: inline-block;
      width: 36px;
      height: 36px;
      text-align: center;
      /* text-align: center;水平方向居中 */ 
      line-height: 36px;
      /*  line-height 与height 值相等,垂直方向居中 */
      border-radius: 6px;
      background-color: #fff;
      color: #3951b3;
      font-size: 14px;
    }

    ul > li > a:hover, ul > li.active > a {
      background-color: blue;
      color: #fff;
    }

    ul > li.next > a {
      width: 80px;
    }

  </style>

<body>
  
  <!-- 结构: HTML -->
  <ul>
    <li class="item"><a href="#">1</a></li>
    <li class="item"><a href="#">2</a></li>
    <li class="item"><a href="#">3</a></li>
    <li class="item"><a href="#">4</a></li>
    <li class="item active"><a href="#">5</a></li>
    <li class="item"><a href="#">6</a></li>
    <li class="item"><a href="#">7</a></li>
    <li class="item"><a href="#">8</a></li>
    <li class="item"><a href="#">9</a></li>
    <li class="item"><a href="#">10</a></li>
    <li class="item next"><a href="#">下一页 &gt;</a></li>
  </ul>

</body>

案例二:京东5列布局

京东五列布局.jpg

  <style>
    /* 公共的class */
    .content {
      width: 1190px;
      /*  1190= 230*5+10*4   */
      margin: 0 auto;
      background-color: orange;
      height: 800px;
    }

    /* 布局样式 */
    .item {
      width: 230px;
      height: 322px;
      background-color: purple;
      color: #fff;
      /* 浮动 */
      float: left;
      /* 让每个 .item 向左浮动10px */
      margin-right: 10px;
      /* margin: 0 5px; */
    }
    
    .box {
      /* margin: 0 -5px; */
      /* 3.方案三: 设置负的的margin(没有兼容性) */
      /*  1190=1200+(-10) ||  1200=230*5+10*5 */
      margin-right: -10px;
    }

    /* 1.有可能存在兼容性 */
    /* .item:nth-child(5n) {
      margin-right: 0;
    } */
    
    /* 2.麻烦一点点 */
    /* .item.last-item {
      margin-right: 0;
    } */
  </style>
</head>
<body>
  
  <div class="content">
    <div class="box">
      <div class="item item1">1</div>
      <div class="item item2">2</div>
      <div class="item item3">3</div>
      <div class="item item4">4</div>
      <div class="item item5">5</div>
    </div>
  </div>

</body>

案例三:四列布局

三列布局.jpg

 <style>
    .content {
      width: 1190px;
      /* 1190=290*4+10*3  */
      margin: 0 auto;
      background-color: #f00;
      height: 1000px;
    }

    .wrapper {
      margin-right: -10px;
    }

    .item {
      width: 290px;
      background-color: purple;
      margin-bottom: 10px;

      float: left;
      margin-right: 10px;
    }

    .item.left {
      height: 370px;
      /* 370=180*2+10   ||  margin-bottom: 10px;  */
    }

    .item.right {
      height: 180px;
    }
  </style>
</head>
<body>
  
  <div class="content">
    <div class="wrapper">
      <div class="item left"></div>
      <div class="item left"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
    </div>
  </div>

</body>

案例四:考拉边框布局

考拉五列布局.jpg

<style>
    .content {
      width: 1100px;
      margin: 0 auto;
      height: 800px;
      background: #ccc;
    }

    .box {
      /* margin-left: 1px; */
    }

    .item {
      width: 221px;
      /* 221*5=1105 */
      height: 168px;
      background: orange;
      color: #fff;

      float: left;

      border: 1px solid #000;
      margin-right: -1px;
      /* margin-right让每个item向左移1px,达到边框重叠故宽度减少,所以1105-4=1101,多出来的1px向左移1px,不在父容器范围内*/

      box-sizing: border-box;
      /* 元素的总高度和宽度包含内边距和边框(padding 与 border) : */
    }

    .item.first {
      width: 220px;
    }
  </style>
</head>
<body>
  
  <div class="content">
    <div class="box">
      <div class="item first">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
      <div class="item">4</div>
      <div class="item">5</div>
    </div>
  </div>

</body>

1.4_浮动的问题 – 高度塌陷

  • 浮动元素脱离了标准流,变成脱标元素,不再向父元素汇报高度

 父元素计算总高度时,就不会计算浮动子元素的高度,导致了高度坍塌的问题

  • 解决父元素高度坍塌问题的过程,一般叫做清浮动(清理浮动、清除浮动)用clear属性

  • 清浮动的目的是: 让父元素计算总高度的时候,把浮动子元素的高度算进去


1.5_clear属性

  • clear 可指定一个元素是否必须移动(清除浮动后)到在它之前的浮动元素下面;

  • clear的常用取值

  left:要求元素的顶部低于之前生成的所有左浮动元素的底部

  right:要求元素的顶部低于之前生成的所有右浮动元素的底部

  both:要求元素的顶部低于之前生成的所有浮动元素的底部

  none:默认值,无特殊要求

1.6_清除浮动的方法

  • 方法一: 给父元素设置固定高度

​   扩展性不好(不推荐)

  • 方法二: 在父元素最后增加一个空的块级子元素,并且让它设置clear: both

      会增加很多无意义的空标签,维护麻烦

     违反了结构与样式分离的原则(不推荐)

  • 方法三: 给父元素添加一个伪元素

      推荐、编写好后可以轻松实现清除浮动;

<style>
    .content {
      width: 1190px;
      margin: 0 auto;
      background: #f00;
    }

    .wrapper {
      margin-right: -10px;
    }

    .item {
      width: 290px;
      background-color: purple;
      margin-bottom: 10px;

      float: left;
      margin-right: 10px;
    }

    .item.left {
      height: 370px;
    }

    .item.right {
      height: 180px;
    }

    /* 其他的内容 */
    .other {
      height: 100px;
      background: #0f0;
    }

    .line {
      /* height: 10px; */
      /* background: blue; */
      clear: both;
    }

    /* 清除浮动--最终的解决方案(给父元素添加一个伪元素) */
    .clear_fix::after {
      content: "";
      /*伪元素必须要有content*/
      clear: both;
      display: block;

      /* 浏览器兼容 */
      visibility: hidden;
      height: 0;
    }

    .clear_fix {
      /* IE6/7 */
      *zoom: 1;
    }
  </style>
</head>
<body>
  
  <!-- 因为所有的后代item元素都是浮动的, 脱离标准流 -->
  <!-- 不会向父元素汇报高度, 那么content元素压根就没有高度 -->
  <div class="content">
    <div class="wrapper clear_fix">
      <div class="item left"></div>
      <div class="item left"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>

      <!-- <div class="line"></div> -->
    </div>
  </div>
  </body>

1.7_布局方案总结

定位方案应用场景
normal flow(标准流)垂直布局
absolute positioning(绝对定位)层叠布局
float(浮动水平布局


2_ flex 弹性布局

2.1_认识flexbox

  • 英译中为弹性盒子

  弹性盒子是一种用于按行或按列布局元素的一维布局方法 ;

  元素可以膨胀以填充额外的空间, 收缩以适应更小的空间;

  通常我们使用Flexbox来进行布局的方案称之为flex布局(flex layout);

  • 是目前web开发中使用最多的布局方案:

      flex 布局(Flexible 布局,弹性布局);

      目前特别在移动端可以说已经完全普及;

      在PC端也几乎已经完全普及和使用, 只有非常少数的网站依然在用浮动来布局;

  • 为什么需要flex布局

      长久以来,CSS 布局中唯一可靠且跨浏览器兼容的布局工具只有 float和 positioning。

  但是这两种方法本身存在很大的局限性, 并且他们用于布局实在是无奈之举

2.2_flex布局的重要概念

  • 两个重要的概念:

  开启了 flex 布局的元素叫 flex container

  flex container 里面的直接子元素叫做 flex item

  • 当flex container中的子元素变成了flex item时, 具备特点:

  flex item的布局将受flex container属性的设置来进行控制和布局;

  flex item不再严格区分块级元素和行内级元素;

  flex item默认情况下是包裹内容的, 但是可以设置宽度和高度;

  • 设置 display 属性为 flex 或者 inline-flex 可以成为 flex container

  flex: flex container 以 block-level 形式存在

  inline-flex: flex container 以 inline-level 形式存在

2.3_flex布局的模型

flex布局模型

2.4_flex相关的CSS属性

flex container【父元素】

设置display:flex;

flex-direction:flex items 默认都是沿着 main axis(主轴)从 main start 开始往 main end 方向排布

  • flex-direction 决定了 main axis 的方向,有 4 个取值

  • row(默认值,水平从左到右)、row-reverse(水平从右到左)、

  • column(垂直从上到下)、column-reverse(垂直从下到上)

flex-wrap:决定了 flex container 是单行还是多行

  • nowrap(默认):单行

  • wrap:多行

  • wrap-reverse:多行(对比 wrap,cross start 与 cross end 相

flex-flow: 是 flex-direction 和 flex-wrap 的简写, 任何顺序, 并且都可以省略;


justify-content

在这里插入图片描述


align-items(交叉轴方向)

在这里插入图片描述

  • 当在normal或者stretch情况下,flex items的高度未设置或者为auto是,item会自动在垂直方向拉伸填充,相反的,如果height为一个确定值,不会被拉伸
  • center 用的最多

align-content

前提要设置 flex-wrap: wrap;

在这里插入图片描述

flex items【子元素】

  1. flex-grow(拉伸)
  • flex-grow 决定了 flex items 如何扩展

  可以设置任意非负数字(正小数、正整数、0)默认值是 0;   当 flex container 在 main axis 方向上有剩余 size 时,flex-grow 属性才会有效

  • 如果所有 flex items 的 flex-grow 总和 sum 超过 1: 每个 flex item 扩展的 size 为flex container 的剩余 size *( 对应flex-grow/ sum)

  • flex items 扩展后的最终 size 不能超过 max-width\max-height

  1. flex-shrink(缩小)
  • flex-shrink 决定了 flex items 如何收缩

  可以设置任意非负数字(正小数、正整数、0)默认值是 1;

  当 flex items 在 main axis 方向上超过了 flex container 的 size,flex-shrink 属性才会有效

  • 如果所有 flex items 的 flex-shrink 总和超过 1,每个 flex item 收缩的 size为  flex items 超出 flex container 的 size * 收缩比例 / 所有 flex items 的收缩比例之和

  • flex items 收缩后的最终 size 不能小于 min-width\min-heigh

  1. flex-basis【极少用】
  • flex-basis 用来设置 flex items 在 main axis 方向上的 base size。

  auto(默认值)、具体的宽度数值(100px)

  • 决定 flex items 最终 base size 的因素,从优先级高到低

  max-width\max-height\min-width\min-height ;

  flex-basis ;

  width\height ;

  内容本身 。


  1. flex flex是 flex-grow || flex-shrink || flex-basis 的简写,flex 属性可以指定1个,2个或3个值
  • 单值语法: 值必须为以下其中之一:

  一个无单位数(): 它会被当作的值。

  一个有效的宽度(width)值: 它会被当作 的值。

  关键字none,auto或initial.

  • 双值语法: 第一个值必须为一个无单位数,并且它会被当作 的值。

 第二个值必须为以下之一:

✓ 一个无单位数:它会被当作 的值。

✓ 一个有效的宽度值: 它会被当作 的值。

  • 三值语法:

  第一个值必须为一个无单位数,并且它会被当作 的值。

  第二个值必须为一个无单位数,并且它会被当作 的值。

  第三个值必须为一个有效的宽度值, 并且它会被当作 的值

	  /* flex-grow flex-shrink flex-basis */
      /* none: 0 0 auto */
      /* auto: 1 1 auto */
      flex: 1 1 10px;

  1. order

在这里插入图片描述

  1. align-self 在这里插入图片描述

2.5_解决一个案例

在这里插入图片描述

<style>
    .container {
      width: 500px;
      background-color: orange;

      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
    }

    .item {
      width: 110px;
      height: 140px;

      /* margin-right: 20px; */
    }

    .container > i {
      width: 110px;
    }

    /* .item:nth-child(4n) {
      margin-right: 0;
    } */
  </style>
</head>
<body>
  
  <div class="container">
    <div class="item item1">1</div>
    <div class="item item2">2</div>
    <div class="item item3">3</div>
    <div class="item item1">1</div>
    <div class="item item2">2</div>
    <div class="item item3">3</div>
    <div class="item item1">1</div>
    <div class="item item2">2</div>
    <div class="item item3">3</div>
    <div class="item item3">3</div>
    <!-- 添加span/i的个数是列数减2 -->
   <i></i><i></i>
  </div>

  <script src="./js/itemRandomColor.js"></script>
</body>


3_区别float与flex

float和flex在视觉上直观的区别就是:

float元素宽高和元素之间的间距都是固定的,随着页面缩小,元素会换行。(可以设置为 不换行)。

flex布局的元素宽高和元素之间的间距是变化的,随着页面缩小,父类空白空间减少,元素能分配到的空间也减少,元素的间距也减少。


4_grid布局

4.1_基础概念

Grid Container :元素设置 display:grid;

Grid Item:Grid Container 的直接子项

Grid Iine:构成网格的分割线,垂直线或水平线

Grid Track:两条相邻网格线之间的空间

Grid Area:四条网格线包围的总空间

4.2_常见属性

grid container常见属性:

  • display;
  • grid template(grid-template-rows;
  • grid-template-columns;grid-template-areas)
  • grid-gap(grid-colurmni-gap;grid-row-gap);
  • place-items(justify-items;align-items);
  • grid-area;place-content(justify-content;align-content);
  • grid auto flowsgrid(grid-auto-colurnns;grid-auto-rows);
  • grid;

grid item常见属性:

  • grid-column-start;
  • grid-column-end;
  • grid-row-start;
  • grid-row-end;
  • grid-column;
  • justify-self;
  • grid-row;
  • align-self;
  • place-self;

具体案例学习推荐网站css-tricks.com/snippets/cs…


5_ position 定位布局

5.1_认识元素定位

  • 定位允许从正常的文档流布局中取出元素,并使它们具有不同的行为

    • 例如放在另一个元素的上面;

    • 或者始终保持在浏览器视窗内的同一位置;

  • 常用于开发中

5.2_认识position属性值

静态定位 static (默认值)

  • 元素按照normal flow布局

  • left 、right、top、bottom没有任何作用

相对定位 relative

  • 元素按照标准流布局,

  • 可以通过left、right、top、bottom进行定位。​ 定位参照对象是元素left、right、top、bottom自己原来的位置

  • left、right、top、bottom用来设置元素的具体位置【向左右上下调整,正负值方向相反】

  • 相对定位的应用场景。 在不影响其他元素位置的前提下,对当前元素位置进行微调

  • 案例【让一张图片随着浏览器的宽度调整居中】

简单解决:

      <style>
        body {
          margin: 0;
          padding: 0;
        }
    
        .box {
          height: 489px;
          background-color: #f00;
          background: url(../images/mhxy.jpg) center;
           /* center即可居中 */
        }
      </style>
    
    <body>
        <div class="box"></div>
    </body>

realative解决:

      <style>
          body {
            margin: 0;
            padding: 0;
          }
      
          .box {
            height: 489px;
            background-color: #f00;
            overflow: hidden;
          }
      
          .box img {
            position: relative;
            /* left: 该值是图片宽度的一半 */
            left: -960px;
            /* translate中的百分比是相对于自己 ,第三种解决方法*/
            /* transform: translate(-50%); */
      
            /* 向右边移动div的一半 */
            margin-left: 50%;
          }
        </style>
      
      <body>
          <div class="box">
          <img src="../images/mhxy.jpg" alt="">
          </div>
      </body>

固定定位 fixed

  • 元素脱离标准流normal flow(脱标
  • 可以通过left、right、top、bottom进行定位
  • 定位参照对象是视口(viewport),浏览器用户可见窗口大小
  • 当画布滚动时,固定不动

画布 Canvas

  • 用于渲染文档的区域

  • 文档内容超出视口范围,通过滚动查看

视口 Viewport

  • 文档的可视区域

  • 从面积大小来看,画布 >= 视口

绝对定位 absolute

  • 元素脱离标准流normal flow(脱标

  • 可以通过left、right、top、bottom进行定位

    • 定位参照对象是最邻近的定位祖先元素
    • 如果找不到这样的祖先元素,参照对象是视口

定位元素:​position值为relative、absolute、fixed的元素, position值不为static的元素。

子绝父相

  • 大数情况,子元素的绝对定位都是相对于父元素进行定位

  • 子元素相对于父元素定位,又不让父元素脱标,解决方案【“子绝父相】

    • 父元素设置position: relative​ (让父元素成为定位元素,而且父元素不脱离标准流)

    • 子元素设置position: absolute(然后再设置Left、right…)


粘性定位sticky【新值】

​   可看做是相对定位和固定(绝对)定位的结合体;

​   它允许被定位的元素表现得像相对定位一样,直到它滚动到某个阈值点;

​   当达到这个阈值点时, 就会变成固定(绝对)定位;

​  sticky是相对于最近的滚动祖先包含滚动视口的(the nearest ancestor scroll container’s scrollport ) 在这里插入图片描述

5.3_元素position值为absolute/fixed的特点


特点一

  • 随意设置宽高

  • 宽高默认由内容决定

  • 不再受标准流的约束

​   不再严格按照从上到下、从左到右排布; ​  不再严格区分块级(block)、行内级(inline),行内块级(inline-block)的很多特性都会消失

  • 不再给父元素汇报宽高数据。​ 当父元素内部仅仅只有该元素,而该元素position值为absolute/fixed,那么父元素的空间将会消失

  • 脱标元素内部默认还是按照标准流布局

特点二

  • 绝对定位元素。position值为absolute或者fixed的元素 (这里的父元素:定位参照对象是最邻近的定位祖先元素)

  • 对于绝对定位元素来说

    • 父元素的宽度 = left + right + margin-left + margin-right + 绝对定位元素的实际占用宽度

    • 父元素的高度 = top + bottom + margin-top + margin-bottom + 绝对定位元素的实际占用高度

  • 希望绝对定位元素的宽高和父元素一样,可以给绝对定位元素设置属性

left: 0、right: 0、top: 0、bottom: 0、margin:0
  • 希望绝对定位元素在父元素居中显示,可以给绝对定位元素设置属性
left: 0、right: 0、top: 0、bottom: 0、margin: auto
//另外,还得设置具体的宽高值(宽高小于定位参照对象的宽高)

5.4_绝对定位的练习案例

 <style>
      /* 重置代码 */
      a {
        text-decoration: none;
        color: #333;
      }

      /* 公共的CSS */
      .sprite_01 {
        background-image: url(../images/music_sprite_01.png);
        display: inline-block;
      }

      .sprite_02 {
        background-image: url(../images/music_sprite_02.png);
        display: inline-block;
      }

      .sprite_02_icon_music {
        width: 14px;
        height: 11px;
        background-position: 0 -24px;
      }

      .sprite_02_icon_play {
        width: 16px;
        height: 17px;
        background-position: 0 0;
      }

      /* 布局代码 */
      .item {
        width: 140px;
        margin: 0 auto;
        /* 居中显示 */
      }

      .item .top {
        position: relative;
        /*父元素*/
      }

      .item .top img {
        /* 将图片下面的多出来的区域去除 ,有两种方法*/
        vertical-align: top;
        /* display: block; */
      }

      .item .top .cover {
        /* 对封面链接样式做设置,让用户一点击封面区域就能跳转链接 */
        position: absolute;
        /* absoluete让该元素相对于 .top参考定位 ,达到上诉效果 */
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;

        background-image: url(../images/music_sprite_01.png);
        background-position: 0 0;
      }

      .item .top .info {
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        height: 27px;
        padding-left: 10px;
        line-height: 27px;
        /* line-height与height数值相同可以让文字在垂直方向居中 */

        font-size: 12px;
        color: #ccc;

        background-image: url(../images/music_sprite_01.png);
        background-position: 0 -537px;
      }

      .item .top .info .icon-music {
        position: relative;
        top: 1px;
        /* display: inline-block; */
        /* width: 14px;
      height: 11px; */

        /* background-image: url(../images/music_sprite_02.png); */
        /* background-position: 0 -24px; */
      }

      .item .top .info .count {
        margin-left: 4px;
      }

      .item .top .info .icon-play {
        position: absolute;
        top: 0;
        bottom: 0;
        right: 10px;
        margin: auto 0;

        /* display: inline-block; */
        /* width: 16px;
      height: 17px; */
        /* background-image: url(../images/music_sprite_02.png); */
        /* background-position: 0 0; */
      }

      /* 底部的样式 */
      .item .bottom {
        display: block;
        margin-top: 8px;
        font-size: 14px;
      }

      .item .bottom:hover {
        text-decoration: underline;
      }
    </style>
    
    <body>
    <div class="item">
      <div class="top">
        <img src="../images/music_album01.jpg" alt="音乐封面" />
        <a class="cover" href="#"></a>
        <div class="info">
          <i class="sprite_02 sprite_02_icon_music icon-music"></i>
          <span class="count">62万</span>
          <i class="sprite_02 sprite_02_icon_play icon-play"></i>
        </div>
      </div>
      <a class="bottom" href="#"> 天气好的话,把耳机分给我一半吧 </a>
      <i class="sprite_02 sprite_02_icon_play"></i>
      <i class="sprite_02 sprite_02_icon_music"></i>
    </div>
  </body>

5.5_CSS属性 z-index

z-index属性用来设置定位元素的层叠顺序(仅对定位元素有效),取值可以是正整数、负整数、0【一般默认是0】

比较原则:

  • 兄弟关系

    • z-index越大,层叠在越上面;
    • z-index相等,写在后面的那个元素层叠在上面;
  • 不是兄弟关系

    • 各自从元素自己以及祖先元素中,找出最邻近的2个定位元素进行比较;

    • 而且这2个定位元素必须有设置z-index的具体数值。


6_响应式布局

响应式布局:会随着屏幕实时变动而自动调整,是一种自适应;

6.1_视口viewport

视口的概念:

  • 在一个浏览器中,可以看到的区域就是视口(viewport);
  • fixed就是相对于视口来进行定位的;
  • 在PC端的页面中,不需要对视口进行区分,因为布局视口和视觉视口是同一个;

在移动端,布局视口和视觉视口是不太一样的。

  • 移动端的网页窗口往往比较小,但希望一个大的网页在移动端可以完整的显示;
  • 所以在默认情况下,移动端的布局视口是大于视觉视口的;

移动端视口划分为三种情况:

  • 布局视口(layout viewport)
  • 视觉视口(visual layout)
  • 理想视口(ideal layout)

这些概念的区分,来自ppk,他在移动端浏览贡献很大

www.quirksmode.org/mobile/view…

6.2_布局视口(layout viewport)

  • 默认情况下,在PC端的网页在移动端的显示

    • 第一,它会按照宽度为980px来布局一个页面的盒子和内容;
    • 第二,为了显示可以完整的显示在页面中,对整个页面进行缩小;
  • 相对于980px布局的这个视口,称之为布局视口(layout viewport);

    • 布局视口的默认宽度是980px;

6.3_视觉视口(visual viewport)

  • 默认情况下,按照980px显示内容,右侧有一部分区域就会无法显示,所以手机端浏览器会默认对页面进行缩放以显示到用户的可见区域中;
  • 显示在可见区域的这个视口,就是视觉视口(visual viewport)
  • 在Chrome上按shift+鼠标左键可以进行缩放。

6.4_理想视口(ideal viewport)

  • 如果所有网页按照980px在移动端布局,最终页面都会被缩放显示。

    • 事实上这种方式是不利于移动端的开发,希望设置100px,那么显示的就是100px;
    • 这是通过设置理想视口(ideal viewport)做到的
  • 默认情况下的layout viewport并不适合进行布局;

  • 可以对layout viewport进行宽度和缩放的设置,以满足正常在一个移动端窗口的布局;

  • 这时可以设置meta中的viewport;

在这里插入图片描述

  <!-- width: 设置布局视口的宽度 -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

6.5_响应式布局——移动端适配方案

移动端的屏幕尺寸通繁多,有时希望在不同的屏幕尺寸上显示不同的大小;

  • 比如设置一个100x100的盒子

    • 在375px的屏幕上显示是100x100;
    • 在320px的屏幕上显示是(90+)x(90+);
    • 在414px的屏幕上显示是(100+)x(100+);
  • 其他尺寸也是类似,比如padding、margin、border、left,甚至是font-size等等;

多个方案来处理尺寸问题:

  • 方案一:百分比设置【基本不用】

    • 因为不同属性的百分比值,相对的可能是不同参照物,所以百分比往往很难统一;
    • 所以百分比在移动端适配中使用是非常少的;
  • 方案二:rem单位+动态html的font-size;

  • 方案三:vw单位;

  • 方案四:flex的弹性布局;

适配方案1:rem单位+动态html的font-size

 rem单位是相对于html元素的font-size来设置的,在不同的屏幕下有不同的尺寸,可以动态的修改html的font-size尺寸; 比如如下案例:

  1. 设置一个盒子的宽度是2rem;
  2. 设置不同的屏幕上html的font-size
    在这里插入图片描述

这个方案在开发中,需要考虑两个问题:

  • 问题一:针对不同的屏幕,设置html不同的font-size;html的font-size=(屏幕尺寸/10)
  • 问题二:将原来要设置的尺寸,转化成rem单位

问题一:如何设置不同屏幕尺寸的font-size ?

(1) 方案一:媒体查询(通过媒体查询来设置不同尺寸范围内的屏幕html的font-size尺寸)

  缺点:需要针对不同的屏幕编写大量的媒体查询;如果动态改变尺寸,不会实时的进行更新。

<style>
    @media screen and (min-width: 320px) {
      html {
        font-size: 20px;
      }
    }
    
    @media screen and (min-width: 375px) {
      html {
        font-size: 24px;
      }
    }

    @media screen and (min-width: 414px) {
      html {
        font-size: 28px;
      }
    }
    
    @media screen and (min-width: 480px) {
      html {
        font-size: 32px;
      }
    }

    .box {
      width: 5rem;
      height: 5rem;
      background-color: orange;
    }
  </style>

(2) 方案二:手动编写js代码(实时改变屏幕尺寸时,font-size也可以实时更改,可以通过js代码)

方法: 根据html的宽度计算出font-size的大小,并且设置到html上;监听页面的实时改变,并且重新设置font-size的大小到html上;

<script>
	// 1.获取html的元素
	const htmlEl = document.documentElement
	
	function setRemUnit() {
	  // 2.获取html的宽度(视口的宽度)
	  const htmlWidth = htmlEl.clientWidth
	  // 3.根据宽度计算一个html的font-size的大小
	  const htmlFontSize = htmlWidth / 10
	  // 4.将font-size设置到html上
	  htmlEl.style.fontSize = htmlFontSize + "px"
	}
	// 保证第一次进来时, 可以设置一次font-size
	setRemUnit()
	
	// 当屏幕尺寸发生变化时, 实时来修改html的font-size
	window.addEventListener("resize", setRemUnit)
</script>

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

    .box {
      width: 5rem;
      height: 5rem;
      background-color: orange;
    }
</style>

(3) 方案三——lib-flexible库。 GitHub上搜索lib-flexible,跟方案二做的事情是相同的,也可以直接引入它;

问题二:已设置不同屏幕尺寸的font-size,宽高如何转换成rem单位?

(1) 方案一:手动换算

比如在屏幕尺寸为375px中,有一个100px宽度和高度的盒子;计算根元素font-size=375px / 10=37.5px,然后将宽度高度100px转成对应的rem值; (100px)/(37.5px)=2.6667 rem,其他宽高也是相同的方法计算。

(2)方案二:less/scss函数。

编写一个less或者scss换算函数,需要宽高换算成rem时,带参数直接调用该函数。

//函数定义。@px是参数,是宽高原始的长度
.pxToRem(@px){
 //换算公式。返回的结果是rem单位
  result:1rem*(@px/@htnmFontSize)
}

.box{
 //调用换算函数。直接得到结果
 width: .pxToRem(100)[result];
 font-size:.pxToRem(18)[result];
}


  1. 方案三:postcss-pxtorem

在前端的工程化开发中,借助于webpack的工具来完成自动的转化;

  1. 方案四:VSCode插件【px to rem】

这个插件,在编写时自动转化;但是要确认fontsize数值;

适配方案2: vw

flexible库更推荐使用viewport的两个单位vw、wh

vw和rem的对比

  • rem事实上是作为一种过渡的方案,利用的也是vw的思想。

    • 前面rem方案,都是将1rem等同于设计稿的1/10,在利用1rem计算相对于整个屏幕的尺寸大小;
    • 1vw等于屏幕的1/100, 而且相对于rem还更加有优势;
  • vw相比于rem的优势:

    • 优势一:不计算html的font-size大小,不设置html的font-size;
    • 优势二:不因设置html的font-size大小,而必须给body再设置一个font-size,防止继承;
    • 优势三:不依赖font-size的尺寸,不担心某些原因html的font-size尺寸被篡改,页面尺寸混乱;
    • 优势四:vw相比于rem更加语义化,1vw刚才是1/100的viewport的大小;
    • 优势五:具备rem之前所有的优点;
  • 将尺寸换算成vw的单位即可。目前相比于rem,更加推荐使用vw(但是理解rem依然很重要)

宽高如何转换成vw单位?

(1)方案一:手动换算

  比如在375px屏幕上,有一个100px宽度和高度的盒子;font-size=375px/100=3.75px ;

  需要将100px转成对应的vw值;(100px)/(3.75px)=26.667 vw,其他也是相同的方法计算即可;

(2)方案二:less/scss函数。参考转换成rem的函数,只需把1/10改成1/100。

(3)方案三:postcss-px-to-viewport-8-plugin(。 和rem一样,在前端的工程化开发中,可以借助于webpack的工具来完成自动的转化;

(4)案四:VSCode插【px to vw】 这个插件,在编写时自动转化;