重学前端之 CSS 布局

443 阅读6分钟

之前在公司一直的做中后台业务,大部分都是表单和列表,导致CSS布局能力有点儿弱化,so,解这个机会重新梳理一下CSS布局方面的一些东西

前言

盒模型

CSS 基础框盒模型是 CSS 规范的一个模块,它定义了一种长方形的盒子——包括它们各自的内边距(padding)与外边距(margin ),并根据视觉格式化模型来生成元素,对其进行布置、编排、布局(lay out)。常被直译为盒子模型、盒模型或框模型

  • W3C标准盒模型(content-box)
    • 属性width,height只包含内容content,不包含border和padding。
  • IE 盒模型(border-box)
    • 属性width,height包含border和padding,指的是content+padding+border。

在ie8+浏览器中使用哪个盒模型可以由box-sizing(CSS新增的属性)控制,默认值为content-box,即标准盒模型;如果将box-sizing设为border-box则用的是IE盒模型。如果在ie6,7,8中DOCTYPE缺失会触发IE模式。在当前W3C标准中盒模型是可以通过box-sizing自由的进行切换的。

DOCTYPE

一种标准通用标记语言的文档类型声明,它的目的是要告诉标准通用标记语言解析器,它应该使用什么样的文档类型定义(DTD)来解析文档

因为若不声明DOCTYPE类型,IE浏览器会将盒子模型解释为IE盒子模型,FireFox等会将其解释为W3C盒子模型;若在页面中声明了DOCTYPE类型,所有的浏览器都会把盒模型解释为W3C盒模型。

FC

FC(Formatting Context)格式化上下文,其实指的是一个渲染区域,拥有一套渲染规则,它决定了其子元素如何定位,以及与其他元素之间的关系和相互作用。

BFC

BFC(Block Formatting Context)块级格式化上下文,一个独立的块级渲染区域,该区域拥有一套渲染规则来约束块级盒子的布局,且与区域外部无关。

  • 创建方法

    • 根元素或其它包含它的元素;
    • 浮动 (元素的float不为none);
    • 绝对定位元素 (元素的positionabsolutefixed);
    • 行内块inline-blocks(元素的 display: inline-block);
    • 表格单元格(元素的display: table-cell,HTML表格单元格默认属性);
    • overflow的值不为visible的元素;
    • 弹性盒 flex boxes (元素的display: flexinline-flex);
  • BFC的约束规则

    • 内部的Box会在垂直方向上一个接一个的放置
    • 垂直方向上的距离由margin决定。(完整的说法是:属于同一个BFC的两个相邻Box的margin会发生重叠(塌陷),与方向无关。)
    • 每个元素的左外边距与包含块的左边界相接触(从左向右),即使浮动元素也是如此。(这说明BFC中子元素不会超出他的包含块,而position为absolute的元素可以超出他的包含块边界)
    • BFC的区域不会与float的元素区域重叠
    • 计算BFC的高度时,浮动子元素也参与计算
    • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然
  • 应用

    • 防止margin重叠
      • 两个相邻Box垂直方向margin重叠
      • 相邻Box水平方向margin重叠
      • 嵌套元素的margin重叠
    • 清除内部浮动
    • 自适应多栏布局的
      • 自适应两栏布局
      • 自适应两栏布局

IFC

IFC (Inline Formatting Contexts)行内格式化上下文

  • 产生
    • 只有在一个块级元素中仅仅包含内联级别元素时才会生成
  • 特性
    • 从包含块顶部水平方向排列
    • 排列情况和浮动与否会改变行盒的高度
    • 当一个行盒被分割,margin,border,padding都不会再有视觉效果了
  • 应用
    • 水平居中:当一个块要在环境中水平居中时,设置其为inline-block则会在外层产生IFC,通过text-align则可以使其水平居中。
    • 垂直居中:创建一个IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align:middle,其他行内元素则可以在此父元素下垂直居中。

GFC

GFC (GridLayout Formatting Contexts)网格布局格式化上下文,当为一个元素设置display:grid的时候,此元素将会获得一个独立的渲染区域

FFC

GFC (Flex Formatting Contexts)自适应格式化上下文,样式设置为display:flex或者display:inline-flex的元素将会生成自适应容器(flex container),设置为 flex的容器被渲染为一个块级元素,而设置为inline-flex的容器则渲染为一个行内元素

布局实例

三栏布局

三栏布局也是我们常常会使用到的布局之一。它的特点主要是:两边定宽,中间自适应

浮动

思路:

  • 左右两栏使用float浮动到相应位置
  • 中间栏通过margin属性进行撑开

浮动

定位

思路:

  • 左右两栏使用position定位到相应位置
  • 中间栏通过margin属性进行撑开

定位

圣杯布局

思路:

  • 三个元素分别设置float: left;
  • 中间元素占据第一位置优先渲染,设置该元素width: 100%
  • 左元素设置margin-left: -100%;以使得左元素上升一行并且处于最左位置,右元素设置左边距为自身宽度的负值使得右元素上升一行处于最右位置。
  • 设置父元素的左右padding为左右两个元素留出空间,以展示中间元素内容。
  • 设置左右元素为position: relative;,左元素的left和右元素的right为内边距的宽度的负值。

双飞翼布局

思路:

  • 三个元素分别设置float: left;
  • 中间元素占据第一位置优先渲染,设置该元素width: 100%
  • 左元素设置margin-left: -100%;以使得左元素上升一行并且处于最左位置,右元素设置左边距为自身宽度的负值使得右元素上升一行处于最右位置。
  • 设置中间元素的子元素左右边距为左右元素留空位,以展示中间元素内容

两栏布局

两栏布局和三栏布局有异曲同工之效,方法也类似

不定宽高元素水平垂直居中

flex

<style>
    .wrapper1{
      display: flex;
      justify-content: center;
      align-items: center;
    }
</style>
<div class="wrapper wrapper1">
  <div class="wrapper-inner">
       不定宽高元素水平垂直居中
  </div>
</div>

flex + margin

<style>
    .wrapper2{
      display: flex;
    }
    .wrapper2 .wrapper-inner{
      margin: auto;
    }
</style>
<div class="wrapper wrapper2">
  <div class="wrapper-inner">
       不定宽高元素水平垂直居中
  </div>
</div>

transform + absolute

<style>
    .wrapper3{
      position: relative;
    }
    .wrapper3 .wrapper-inner{
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
    }
</style>
<div class="wrapper wrapper3">
  <div class="wrapper-inner">
       不定宽高元素水平垂直居中
  </div>
</div>

absolute + 四个方向的值相等

<style>
    .wrapper4 {
      position: relative;
    }
    .wrapper4 .wrapper-inner {
      position: absolute;
      position: absolute;
      margin: auto;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
    }
</style>
<div class="wrapper wrapper4">
  <div class="wrapper-inner">
       不定宽高元素水平垂直居中
  </div>
</div>

······ 类似的方法还有很多,就不一一列举了