愿你坚持不懈,努力进步,进阶成自己理想的人

—— 2017.09, 写给3年后的自己

CSS常用布局总结

一、单列布局

1、水平居中

1)使用text-align: centerdisplay: inline-block

<div class="parent">
    <div class="child">Hello, world</div>
</div>

CSS:

.parent {
    width: 300px;
    text-align: center;
    background: #888;
}
.child {
    display: inline-block;
    width: 200px;
    height: 100px;
    background: #36C;
    text-align: left; /* 修正父容器带来的副作用 */
}

优点:兼容性好(完美兼容IE8+),可以不用指定宽度
缺点:需要同时设置子元素和父元素
2)使用margin: auto
利用CSS计算margin的特点,左右指定为auto的时候能够水平居中

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

CSS:

.box {
    width: 200px;
    height: 100px;
    margin: auto;
    background: #36C;
}

优点:兼容性很好,实现方便
缺点:需要指定容器的宽度
3)使用display: table

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

CSS:

.box {
    display: table;
    margin: auto;
}

优点:可以兼容IE8+,且不需要指定宽度
缺点:IE6/7不兼容
4)使用定位和transform

<div class="parent">
    <div class="child">Hello, world</div>
</div>

CSS:

.parent {
    width: 300px;
    background: #888;
}
.child {
    position: relative; left: 50%;
    width: 200px;
    height: 100px;
    transform: translateX(-50%);
    background: #36C;
}

缺点:兼容性一般(transform仅支持IE9+)
5)使用flex布局

<div class="parent">
    <div class="child">Hello, world</div>
</div>

CSS:

.parent {
    display: flex;
    justify-content: center;
    width: 300px;
    background: #888;
}
.child {
    height: 100px;
    background: #36C;
}

优点:实现简单,且不需要知道子容器的宽度
缺点:兼容性不好(flex仅支持IE10+)


2、垂直居中

1)使用display: table-cell

<div class="parent">
    <div class="child">Hello, world</div>
</div>

CSS:

.parent {
    display: table-cell;    /* 关键部分 */
    vertical-align: middle; /* 关键部分 */
    height: 300px;
    background: #000;
}
.child {
    width: 100px;
    height: 200px;
    background: #36C;
}

2)采用定位和transform

<div class="parent">
    <div class="child">Hello, world</div>
</div>

CSS:

.parent {
    height: 300px;
    background: #888;
}
.child {
    position: relative; top: 50%; /* 关键部分 */
    transform: translateY(-50%);  /* 关键部分 */
    width: 100px;
    height: 200px;
    background: #36C;
}

3)使用flex布局

<div class="parent">
    <div class="child">Hello, world</div>
</div>

CSS:

.parent {
    display: flex;
    align-items: center;
    height: 300px;
    background: #888;
}
.child {
    width: 100px;
    height: 200px;
    background: #36C;
}

3、水平垂直都居中

以下的示例基于HTML:

<div class="parent">
    <div class="child"></div>
</div>

1)利用vertical-align: middletext-align: centerdisplay: inline-block

.parent {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
    width: 500px;
    height: 500px;
    background: #F7F7F7;
}
.child {
    display: inline-block;
    text-align: left;
    width: 200px;
    height: 200px;
    background: #36C;
}

2)结合定位和transform

.parent {
    position: relative;
    width: 500px;
    height: 500px;
    background: #F7F7F7;
}
.child {
    position: absolute; left: 50%; top: 50%;
    transform: translate(-50%, -50%);
    width: 200px;
    height: 200px;
    background: #36C;
}

3)使用flex布局

.parent {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 500px;
    height: 500px;
    background: #F7F7F7;
}
.child {
    width: 200px;
    height: 200px;
    background: #36C;
}


二、多列布局

1、左侧固定,右侧自适应

1)使用floatmargin

<div class="box">
    <div class="left"></div>
    <div class="right-fix">
        <div class="right">Hello, world</div>
    </div>
</div>

CSS:

.box { overflow: hidden }
.left {
    float: left;
    width: 200px;
    height: 100px;
    margin-right: -200px;
    background: #888;
}
.right-fix {
    float: right;
    width: 100%;
}
.right {
    margin-left: 200px;
    height: 90px;
    background: #36C;
}

2)使用display: table实现

<div class="box">
    <div class="left"></div>
    <div class="right">Hello, world</div>
</div>

CSS:

.box {
    display: table;
    table-layout: fixed;
    width: 100%;
}
.left {
    display: table-cell;
    width: 200px;
    height: 100px;
    background: #888;
}
.right {
    display: table-cell;
    height: 100px;
    background: #36C;
}

3)使用定位实现

<div class="box">
    <div class="left"></div>
    <div class="right">Hello, world</div>
</div>

CSS:

.box {
    position: relative;
}
.left {
    position: absolute; left: 0; top: 0;
    width: 200px;
    height: 100px;
    background: #888;
}
.right {
    height: 100px;
    margin-left: 200px;
    background: #36C;
}

4)使用flex布局

<div class="box">
    <div class="left"></div>
    <div class="right">Hello, world</div>
</div>

CSS:

.box {
    display: flex;
}
.left {
    flex: 0 0 200px;
    width: 200px;
    height: 100px;
    background: #888;
}
.right {
    flex: 1;
    height: 100px;
    background: #36C;
}

2、右侧固定,左侧自适应

<div class="box">
    <div class="left-fix">
        <div class="left">Hello, world</div>
    </div>
    <div class="right"></div>
</div>

CSS:

.box { overflow: hidden; }
.left-fix {
    float: left;
    width: 100%;
    height: 100px;
    background: #777;
}
.left {
    margin-right: 200px;
}
.right {
    float: right;
    width: 200px;
    height: 100px;
    margin-left: -200px;
    background: #36C;
}

其他实现方式有display: table、定位以及flex,原理和左侧固定右侧自适应一致。

3、左侧和右侧定宽,中间自适应

<div class="box">
    <div class="left"></div>
    <div class="center-fix">
        <div class="center">Hello, world</div>
    </div>
    <div class="right"></div>
</div>

CSS:

.box { overflow: hidden; }
.left {
    float: left;
    width: 100px;
    height: 100px;
    margin-right: -100px;
    background: #888;
}
.center-fix {
    float: left;
    width: 100%;
}
.center {
    height: 100px;
    margin-left: 100px;
    margin-right: 100px;
    background: #36C;
}
.right {
    float: left;
    width: 100px;
    height: 100px;
    margin-left: -100px;
    background: #888;
}

4、左侧、中侧定宽,右侧自适应

<div class="box">
    <div class="left"></div>
    <div class="center"></div>
    <div class="right-fix"></div>
        <div class="right">Hello, world</div>
    </div>
</div>

CSS部分:

.box { overflow: hidden; }
.left {
    float: left;
    width: 100px;
    height: 100px;
    background: #888;
}
.center {
    float: left;
    width: 100px;
    height: 100px;
    margin-right: -200px;
    background: #36C;
}
.right-fix {
    float: left;
    width: 100%;
}
.right {
    height: 100px;
    margin-left: 200px;
    background: #F60;
}

5、总结

对于这种有一列自适应,而其他列固定的布局,是有套路的。使用float+margin实现的一般方式为:
1)在书写HTML的时候,对于需要自适应的那一列,应该包裹一层<div class="fix"></div>层,这样子可以使得修复IE6下显示的BUG
2)对于固定的列,都使用float: left来向左居中,而自适应的那一列,本身不写float: left,fix层才需要写float: left
3)计算自适应列距离最左边界的宽度A,距离最右边界的宽度B。fix层设置:width: 100%; float: left; margin-left: -Apx; margin-right: -Bpx
4)fix层中包裹的列,设置:margin-left: Apx; margin-right: Bpx
5)父容器做清除浮动处理,可以用overflow: hidden