页面布局解决方案
居中布局
水平居中
子元素相对于父元素居中且子元素宽度可变。
除了另外声明,HTML
结构为以下内容:
<div class="parent">
<div class="child">Demo</div>
</div>
inline-block + text-align
.parent {
text-align: center;
}
.child {
display: inline-block;
width: 300px; /*宽度可变*/
background: #ffff00;
}
优点
- 兼容性好(甚至可以兼容
IE6
和IE7
)
table + margin
<div class="parent">
<div class="child">Demo</div>
</div>
.parent {
text-align: center;
}
.child {
display: table;
margin: 0 auto;
width: 200px; /*宽度可变*/
background: #ffff00;
}
NOTE:
display: table
在表现上类似block
元素,但是宽度为内容宽度。
优点
- 不需要设置父元素样式 (支持
IE8
及其以上版本)
NOTE:兼容
IE8
以下版本需要调整为<table>
的结果。
absolute + transform
.parent {
position: relative;
text-align: center;
}
.child {
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 200px; /*宽度可变*/
background: #ffff00;
}
优点
- 绝对定位脱离文档流,不会对后续元素的布局造成影响。
- 子元素设置绝对定位
position: absolute;
,父元素设置相对定位position: relative;
是典型的定位方法,多用于为子元素设置定位的参考点。
缺点
-
transform
为CSS3
属性,有兼容性问题。
NOTE:
transform
属性的translateX
和translateY
对元素进行旋转、缩放、移动或倾斜,其中移动功能可以用于定位。
flex + justify-content
.parent {
display: flex;
justify-content: center;
text-align: center;
}
.child {
width: 200px; /*宽度可变*/
background: #ffff00;
}
/* 下面的方法,可以达到一样的效果 */
.parent {
display: flex;
text-align: center;
}
.child {
margin: 0 auto;
width: 200px; /*宽度可变*/
background: #ffff00;
}
优点
- 只需设置父元素属性,无需设置子元素。
优点
-
flex
有兼容性问题。
垂直居中
子元素相对于父元素居中且子元素高度可变。
table-cell + vertical-align
.parent {
display: table-cell;
vertical-align: middle;
height: 200px;
background: #ffff00;
}
优点
- 兼容性好(支持
IE8
,以下版本需要调整页面结构至table
)
absolute + transform
.parent {
position: relative;
width: 200px;
height: 200px;
background: #ffff00;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
优点
- 绝对定位脱离文档流,不会对后续元素的布局造成影响。但如果绝对定位元素是唯一的元素则父元素也会失去高度。
缺点
-
transform
为CSS3
属性,有兼容性问题。
flex + align-items
.parent {
display: flex;
align-items: center; /*垂直居中*/
justify-content: center; /*水平居中*/
width: 200px;
height: 200px;
background: #ffff00;
}
优点
- 只需设置父节点属性,无需设置子元素
缺点
- 有兼容性问题
水平与垂直居中
水平与垂直居中的一般性布局在另一篇文章中有过总结,可以作为参考学习。
子元素相对于父元素水平垂直居中且其(子元素与父元素)高度宽度均可变。
inline-block + text-align + table-cell + vertical-align
.parent {
text-align: center;
display: table-cell;
vertical-align: middle;
width: 300px; /*宽度和高度均可变*/
height: 300px;
background: #ffff00;
}
.child {
display: inline-block;
}
优点
- 兼容性好
absolute + transform
.parent {
position: relative;
width: 300px; /*宽度和高度均可变*/
height: 300px;
background: #ffff00;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
优点
- 绝对定位脱离文档流,不会对后续元素的布局造成影响。
缺点
-
transform
为CSS3
属性,有兼容性问题。
flex + justify-content + align-items
.parent {
display: flex;
justify-content: center;
align-items: center;
width: 300px; /*宽度和高度均可变*/
height: 300px;
background: #ffff00;
}
优点
- 只需设置父节点属性,无需设置子元素
多列布局
多列布局在网页中很常见(例如两列布局),多列布局可以是两列定宽,一列自适应, 或者多列不定宽一列自适应,还有等分布局等。
一列定宽,一列自适应
除了另外声明,HTML
结构为以下内容:
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
float + margin
p {
margin: 0; /*清掉 p 标签的默认margin*/
}
.left {
float: left;
width: 100px;
background: #ffff00;
}
.right {
margin-left: 100px;
background: #c7254e;
}
float + margin + (fix)
改造版
<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>
p {
margin: 0; /*清掉 p 标签的默认margin*/
}
.left {
float: left;
width: 100px;
background: #ffff00;
position: relative;
}
.right-fix {
float: right;
width: 100%;
margin-left: -100px;
}
.right {
margin-left: 100px;
background: #c7254e;
}
NOTE:此方法不会存在
IE6
中3
像素的BUG
,但.left
不可选择, 需要设置.left {position: relative}
来提高层级。 此方法可以适用于多版本浏览器(包括IE6
)。缺点是多余的HTML
文本结构。
float + overflow
p {
margin: 0; /*清掉 p 标签的默认margin*/
}
.left {
float: left;
width: 100px;
background: #ffff00;
}
.right {
overflow: hidden;
background: #c7254e;
}
设置
overflow: hidden
会触发BFC
模式(Block Formatting Context
)块级格式化文本。BFC
中的内容与外界的元素是隔离的。
overflow: hidden;
除了隐藏溢出内容外,还具有清除浮动的功能,具体实现是触发BFC
或者IFC
,而这也是很常用的方法。overflow: hidden;
对与父元素显示区域重叠部分进行切割,只在BFC
区域显示,从而实现浮动的清除。
clear: both;
是经典的清除浮动方法,但它与overflow: hidden;
有很大的区别。clear: both;
是清除父元素同一侧的浮动元素,即同一侧不允许存在其他浮动内容,子元素需换行显示。如果布局目标是同侧有其他浮动元素,可以选择overflow: hidden;
。这个特性称为浮动元素闭合。如果有对这个特性感兴趣或者研究透彻的朋友请多多指教,这个在解决高度坍塌、触发BFC
等方面应用广泛,且非常实用。
table
.parent {
display: table;
width: 100%;
table-layout: fixed;
}
.left {
display: table-cell;
width: 100px;
background: #ffff00;
}
.right {
display: table-cell;
/*宽度为剩余宽度*/
background: #c7254e;
}
table
的显示特性为每列的单元格宽度和一定等于表格宽度。table-layout: fixed;
可加速渲染,也是设定布局优先。NOTE:
table-cell
中不可以设置margin
但是可以通过padding
来设置间距。
flex
.parent {
display: flex;
}
.left {
width: 100px;
background: #ffff00;
}
.right {
flex: 1;
background: #c7254e;
}
NOTE:
flex-item
默认为内容宽度。
缺点
- 低版本浏览器兼容问题。
- 性能问题,只适合小范围布局。
两列定宽,一列自适应
除了另外声明,HTML
结构为以下内容:
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="center">
<p>center</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
p {
margin: 0; /*清掉 p 标签的默认margin*/
}
.left, .center {
float: left;
width: 100px;
background: #ffff00;
}
.right {
overflow: hidden;
/*等价于*/
/*flex: 1 1 0;*/
background: #c7254e;
}
多列定宽的实现可以根据单列定宽的例子进行修改与实现。
一列不定宽 + 一列自适应
不定宽的宽度为内容决定,下面为可以实现此效果的方法:
-
float + overflow
,此方法在IE6
中有兼容性问题 -
table
,此方法在IE6
中有兼容性问题 -
flex
,此方法在IE9
及其以下版本中有兼容性问题
多列不定宽 + 一列自适应
其解决方案同一列不定宽加一列自适应相仿。
多列等分布局
除了另外声明,HTML
结构为以下内容:
<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>
float
.parent {
/*margin-left: -20px;*/
}
.column {
float: left;
width: 25%;
box-sizing: border-box;
/*padding-left: 20px;*/
background: #c7254e;
}
NOTE:此方法可以完美兼容
IE8
以上版本。 NOTE+:此方法结构和样式具有耦合性。
table
<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>
.parent-fix {
/*margin-left: -20px;*/
}
.parent {
display: table;
width: 100%;
/*可以布局优先,也可以单元格宽度平分在没有设置的情况下*/
table-layout: fixed;
}
.column {
display: table-cell;
/*padding-left: 20px;*/
background: #c7254e;
}
NOTE:缺点是多了文本结果
flex
.parent {
display: flex;
}
.column {
flex: 1;
background: #c7254e;
}
NOTE:
flex
的特性为分配剩余空间。 NOTE+:兼容性有问题。
两列等高布局
除了另外声明,HTML
结构为以下内容:
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
table
table
的特性为每列等宽,每行等高可以用于解决此需求。
.parent {
display: table;
width: 100%;
table-layout: fixed;
}
.left {
display: table-cell;
background: #ffff00;
}
.right {
display: table-cell;
background: #c7254e;
}
flex
两列布局,一列定宽,一列自适应
.parent {
display: flex;
}
.left {
width: 100px;
background: #ffff00;
}
.right {
flex: 1;
background: #c7254e;
}
float
.parent {
overflow: hidden;
}
.left, .right {
padding-bottom: 99px;
/*此处设置 9999px 很大的值,实际满足一定大小即可*/
margin-bottom: -99px;
}
.left {
float: left;
width: 100px;
background: #ffff00;
}
.right {
overflow: hidden;
background: #c7254e;
}
NOTE:此方法为伪等高(只有背景显示高度相等),左右真实的高度其实不相等。 NOTE+:此方法兼容性较好。
全屏布局
除了另外声明,HTML
结构为以下内容:
<div class="parent">
<div class="top"></div>
<div class="middle">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="bottom"></div>
</div>
定宽需求
实现方案
-
position
常规方案 -
flex
CSS3
新实现
position
<div class="parent">
<div class="top"></div>
<div class="left"></div>
<div class="right"></div>
<div class="bottom"></div>
</div>
html, body, .parent {
height: 100%;
/*用于隐藏滚动条*/
overflow: hidden;
}
.top {
/*相对于 body 定位*/
position: absolute;
top: 0;
left: 0;
right: 0;
height: 100px;
background: #ffff00;
}
.left {
position: absolute;
top: 100px;
left: 0;
bottom: 50px;
width: 200px;
background: #c7254e;
}
.right {
position: absolute;
left: 200px;
top: 100px;
right: 0;
bottom: 50px;
overflow: auto;
background: #5cb85c;
}
.bottom {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 50px;
background: #2a6496;
}
Flex
html, body, .parent {
height: 100%;
/*用于隐藏滚动条*/
overflow: hidden;
margin: 0;
padding: 0;
}
.parent {
display: flex;
flex-direction: column;
}
.top {
height: 100px;
background: #ffff00;
}
.bottom {
height: 50px;
background: #2a6496;
}
.middle {
/*居中自适应*/
display: flex;
flex: 1;
/*flex-direction: row 为默认值*/
}
.left {
width: 200px;
background: #c7254e;
}
.right {
flex: 1;
overflow: auto;
background: #5cb85c;
}
百分比宽度需求
只需把定宽高(
px
为单位的值)的实现改成百分比(%
)既可。
内容自适应
只有右侧栏占据剩余位置,其余空间均需根据内容改变。 所以 postion
的定位方法不适合实现此方案。下面列出了两种布局方案:
flex
-
grid
,W3C
草案并不稳定,浏览器支持也并不理想。
flex
只有不给宽和高进行限制,即可对其中的内容做出自适应的布局。把定宽实现方案中设置了宽度和高度的部分去掉。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。