前端强化课程 - 第 4 章: 页面架构

布局方案

本节只是介绍了常用的一些页面布局如何实现,并没有进行很系统的划分,例如区分父元素和子元素的定宽定高等情况。

水平居中

水品居中

基本使用两层嵌套就可以了,HTML 代码如下:

1
2
3
<div class="parent">
<div class="child">DEMO</div>
</div>

不同的实现代码如下:

  1. inline-block + text-align

    1
    2
    3
    4
    5
    6
    .parent{
    text-align: center;
    }
    .child{
    display: inline-block;
    }
  • 优点:兼容性好(低版本 IE 可以用 display: inline + zoom: 1 兼容);

  • 缺点:居中的元素中的文字会继承文字居中,不需要文字居中时,需要额外设置文字对齐方式;

  1. table + margin

    1
    2
    3
    4
    .child{
    display: table;
    margin: 0 auto;
    }
    • 优点:代码简单;

    • 缺点:暂时没有?

  2. absolute + transform

    1
    2
    3
    4
    5
    6
    7
    8
    .parent {
    position: relative;
    }
    .child {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    }
    • 优点:居中元素不会影响周围元素;

    • 缺点:兼容性稍差;

  3. flex + justify-content / margin

    1
    2
    3
    4
    5
    6
    7
    8
    .parent {
    display: flex;
    /*justify-content: center;*/
    /*为父元素设置此属性后,子元素可以不设置margin属性*/
    }
    .child {
    margin: 0 auto;
    }
    • 优点:效果最好最靠谱;

    • 缺点:兼容性稍差;

垂直居中

垂直居中

HTML 结构仍然是两层:

1
2
3
<div class="parent">
<div class="child">DEMO</div>
</div>

不同的实现代码如下:

  1. table-cell + vertical-align

    1
    2
    3
    4
    .parent {
    display: table-cell;
    vertical-align: middle;
    }
    • 优点:兼容性好;

    • 缺点,父盒子无法设置外边距;

  2. absolute + transform

    1
    2
    3
    4
    5
    6
    7
    8
    .parent {
    position: relative;
    }
    .child {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    }
    • 优点:居中元素不会影响周围元素;

    • 缺点:兼容性稍差;

  3. flex + align-items

    1
    2
    3
    4
    .parent {
    display: flex;
    align-items: center;
    }
    • 优点:效果最好最靠谱;

    • 缺点:兼容性稍差;

中心居中

中心居中

基本就是将水平居中和垂直居中的方法组合使用,直接上样式代码:

  1. 第一种:

    1
    2
    3
    4
    5
    6
    7
    8
    .parent {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
    }
    .child {
    display: inline-block;
    }
  2. 第二种:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    .parent {
    position: relative;
    }
    .child {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    }
  3. 第三种:

    1
    2
    3
    4
    5
    .parent {
    display: flex;
    justify-content: center;
    align-items: center;
    }

一列定宽与一列自适应布局

布局示例

基本 HTML 结构:

1
2
3
4
5
6
7
8
9
<div class="parent">
<div class="left">
<p>Left</p>
</div>
<div class="right">
<p>Right</p>
<p>Right</p>
</div>
</div>
  1. float + margin

    1
    2
    3
    4
    5
    6
    7
    .left {
    float: left;
    width: 150px;
    }
    .right {
    margin-left: 170px;
    }
    • 优点:简单易懂,兼容性较好;

    • 缺点:在 IE6 中有“3 像素”的 BUG,可以在定宽浮动盒子上加 margin: -浮动盒子宽 解决;

  2. float + margin + (fix):

    上一种方法的改进版,在左浮动元素外包一层右浮动元素,右浮动元素宽度撑满父元素,同时设置右浮动元素的左外边距为左浮动元素宽即可,但左浮动元素要用定位属性将层级提高。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <div class="parent">
    <div class="left">
    <p>Left</p>
    </div>
    <div class="right-fix">
    <div class="right">
    <p>Right</p>
    <p>Right</p>
    </div>
    </div>
    </div>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    .left {
    float: left;
    position: relative;
    width: 150px;
    }
    .right-fix {
    float: right;
    width: 100%;
    margin-left: -150px;
    }
    .right {
    margin-left: 170px;
    }
    • 优点:简单易懂,兼容性较好;

    • 缺点:代码较多;

  3. float + overflow

    将自适应元素加上 overflow: hidden,触发自适应元素的 BFC 模式,隔离与浮动盒子的关系。

    1
    2
    3
    4
    5
    6
    7
    8
    .left {
    float: left;
    width: 150px;
    margin-right: 20px;
    }
    .right {
    overflow: hidden;
    }
    • 优点:样式简单,最好用;

    • 缺点:不兼容 IE6;

  4. flex

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .parent {
    display: flex;
    }
    .left {
    width: 150px;
    margin-right: 20px;
    }
    .right {
    flex: 1;
    }
    • 优点:简单优雅;

    • 缺点:低版本浏览器不兼容,性能较差,适合小范围布局;

一列不定宽一列自适应布局:

布局示例

HTML 代码与上一种布局相同。

  1. float + overflow

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    .left {
    float: left;
    margin-right: 20px;
    }
    .right {
    overflow: hidden;
    }
    .left p {
    /*内容宽度任意设置*/
    width: 200px;
    }
    • 优点:可以非常好的支持此类布局;

    • 缺点:不兼容 IE6;

  2. flex

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    .parent {
    display: flex;
    }
    .left {
    margin-right: 20px;
    }
    .right {
    flex: 1;
    }
    .left p {
    /*内容宽度任意设置*/
    width: 200px;
    }
    • 优点:很好很强大;

    • 缺点:兼容性较差;

等高布局

布局示例

等高布局的结构代码与上面两种的双列布局相同,就不重复写了。不同方式如下:

  1. float + overflow

    称为“伪等高”,子元素都设置 padding-bottom 为极大值,同时设置 margin-bottom 为负极大值来抵消,父元素和右侧子元素设置 overflow:hidden 截取最高的子元素高度来模拟出等高。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    .parent {
    overflow: hidden;
    }
    .left,
    .right {
    padding-bottom: 9999px;
    margin-bottom: -9999px;
    }
    .left {
    float: left;
    width: 150px;
    margin-right: 20px;
    }
    .right {
    overflow: hidden;
    }
    • 优点:兼容性好;

    • 缺点:代码较复杂;

  2. flex

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    .parent {
    display: flex;
    align-items: stretch;
    }
    .left {
    /*千万别设置高度*/
    width: 150px;
    margin-right: 20px;
    }
    .right {
    flex: 1;
    }
    • 优点:非常好用,最舒服的布局方式;

    • 缺点:还是兼容性,性能方面的副作用其实可以忽略不计;

  3. table

    这是一种“多功能”布局,通过设置不同的属性,可以用这种方式实现以上三种布局,先看等高布局:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    .parent{
    display: table;
    table-layout: fixed;
    }
    .left,
    .right{
    display: table-cell;
    background-clip: content-box;
    }
    .left {
    width: 150px;
    padding-right: 20px;
    }
    • 优点:天然的等高特性;

    • 缺点:不能设置外边距,只能用内边距做间隔,但是如果有背景色或背景图,需要另外设置 background-clip: content-box;左侧定宽需要时,需要父元素设置 table-layout: fixed 用来使布局优先,提升性能;不支持 IE8 及更低版本;

    等高布局也包含一列定宽一列自适应布局,如果要设定左侧高度,只能给左边的元素设置 padding-bottom

    再来看一列不定宽一列自适应布局,需要将 table-layout: fixed 去掉,因为是内容决定宽度,而不是布局优先;另外在不定宽元素中要设置 width: 0.1%,用百分比是要兼容IE8;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    .parent{
    display: table;
    }
    .left,
    .right{
    display: table-cell;
    background-clip: content-box;
    }
    .left {
    width: 0.1%;
    padding-right: 20px;
    }
    .left p {
    /*内容宽度任意设置*/
    width: 200px;
    }
    • 优点:适用性广,

    • 缺点:繁琐,不支持 IE6、7;

等分布局

布局示例

等分布局需要将宽度和间距算好,需要特别注意的就是要处理多余一个间距的宽度,一般可以在算好后,指定第一个或末一个的间距为 0,但是等分要求高时要用公式计算:父元素宽度 + 间距 = (子元素宽度 + 间距) × N。

  1. float

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .parent {
    margin-left: -20px;
    }
    .column {
    float: left;
    width: 25%;
    padding-left: 20px;
    /*要避免内边距影响宽度*/
    box-sizing: border-box;
    }
    • 优点:代码简单易懂;

    • 缺点:需要给父元素设置 margin 负值来抵消多余的间距;如上面的效果图所示,如果父元素需要边框,则需要另做处理;子元素数量要改变就需要同时更改子元素宽度;子元素内的内容需要有其他元素包裹;

  2. table

    在上一种方法的结构外多加了一层元素,主要用于抵消多余间距;设置 table-layout: fixed 来加速渲染。

    1
    2
    3
    4
    5
    6
    7
    8
    <div class="parent-fix">
    <div class="parent">
    <div class="column"><p>1</p></div>
    <div class="column"><p>2</p></div>
    <div class="column"><p>3</p></div>
    <div class="column"><p>4</p></div>
    </div>
    </div>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    .parent-fix {
    margin-left: -20px;
    }
    .parent{
    display: table;
    width: 100%;
    table-layout: fixed;
    }
    .column {
    display: table-cell;
    padding-left: 20px;
    }
    • 优点:可以设置任意个子元素而不必设置子元素宽度;

    • 缺点:除了解决子元素的自由设置,其余与上一种相同;

  3. flex

    结构代码同第一种相同。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    .parent {
    display: flex;
    }
    .column {
    flex: 1;
    }
    .column + .column {
    margin-left: 20px;
    }
    • 优点:不需要为父元素添加宽度,代码量很少,用子子元素的相邻选择器添加间距即可,设置了 flex 占比后,浏览器会自动算出剩余空间并进行分配;

    • 缺点:仍然是兼容性问题;

基本全屏布局

布局示例