CSS@12布局篇

作者 Jackie Anxis 日期 2017-04-03
CSS@12布局篇

居中布局

水平居中

table + margin

.child {
display: table; /*可以替换成width=xxx;*/
margin: 0 auto;
}

inline-block + text-align

.parent {
text-align: center;
}
.child {
display: inline-block;
}
  • 优点:兼容性非常好,虽然inline-block在IE6和IE7中不支持,但是可以通过其他的方法来模拟。
  • 缺点:子元素会继承父元素的text-align:center,子元素的内容也会是text-algin:center的。

display:table的元素表现上跟display:block比较像,但是它的宽度是根据内容决定的。

  • 优点:只要设置child即可。display:table在IE8以上的浏览器都是支持的。

absolute + transform

.parent {
position: relative;
}
.child {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
  • 优点:子元素不会对其他元素产生影响
  • 缺点:兼容性,因为transform是CSS3新增的。

flex + justify-content/margin

.parent {
display: flex;
justify-content: center;
}
/*.child {
margin: 0 auto;
}*/
  • 缺点:低版本浏览器的不支持

垂直居中

table-cell + vertical align

.parent {
display: table-cell; /*父元素变成单元格*/
vertical-align: middle;
}

absolute + transform

.parent{
position: relative;
}
.child{
position: absolute;
top: 50%;
transform: translateY(-50%);
}
  • 缺点:仍旧是兼容性的问题

flex + align-items

.parent {
display: flex;
align-items: center;
}
  • 缺点:兼容性问题

水平和垂直同时居中

inline-block + text-align + table-cell + vertical-align

.parent {
text-align: center;
display: table-cell;
vertical-align: middle;
}
.child {
display: inline-block;
}

absolute + transform

.parent {
position: relative;
}
.child {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%);
transform: translateY(-50%);
}

flex + justify-content + align-items

.parent {
display: flex;
justify-content: center;
align-items: center;
}

多列布局

定宽与自适应

float + margin

.left {
float: left;
width: 100px;
}
.right {
margin-left: 120px;
}
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
  • 缺点:在IE6及以下的浏览器中,因为右边的元素是没有浮动的,而左边的元素是浮动的,会有一个历史遗留的bug,导致right元素的文字会有3px的缩进。而且在对右边的元素清除浮动时,也会带来一些问题。于是就有了下面这个方法:

float + margin + (fix)

.left{
float: left;
width: 100px;
position: relative; /*解决被覆盖的问题*/
}
.right-fix{
float: right;
width: 100%;
margin-left: -100px;
}
.right{
margin-left: 120px;
}
<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>
  • 备注:因为右元素的层级高于左元素,右边的元素会遮盖左边的元素,导致某些事件无法被触发,所以需要对左元素设置position: relative;
  • 优点:不会存在IE6下那个3px的问题,也不会存在清除浮动的问题。
  • 缺点:结构比较复杂一些。

float + overflow

.left{
float: left;
width: 100px;
margin-right: 20px;
}
.right{
overflow: hidden; /* 会触发BFC模式 */
}
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>

table

.parent{
display: table;
width: 100%; /* table 默认是根据内容宽度来变化的,我们希望其撑满父元素 */
table-layout: fixed; /* 1.布局优先 2.加速table渲染 */
}
.left,.right{
display: table-cell; /* 将子元素变成单元格 */
}
.left{
width: 100px;
padding-right: 20px; /* table-cell没法设置margin */
}
  • 备注:table布局的一个特点是,所有列的宽度之和一定等于总和

flex

.parent{
display: flex;
}
.left{
width: 100px;
margin-right: 20px;
}
.right{
flex: 1; /* 剩余宽度分配给right */
}
  • 缺点:兼容性问题,flex在CSS3中才被支持;因为自适应带来的性能问题(只能用来做小范围的布局)

不定宽与自适应

不定宽指的是:不指定宽度,可以是任意宽度,或者也可以是,宽度是由内容决定的。

float + margin

.left{ /* 宽度由内容决定 */
float: left;
margin-right: 20px;
}
.right{
overflow: hidden;//block formatting context
}

table

.parent{
display: table; width: 100%; /* table 默认是根据内容宽度来变化的 */
table-layout: fixed;/* 布局优先 加速table渲染 */
}
.left,.right{
display: table-cell;
}
.left{
width: 0.1%; /* 设置很小的值,就能让其跟随内容变动 */
padding-right: 20px; /* table-cell没法设置margin */
}

flex

.parent {
display: flex;
}
.left {
margin-right: 20px;
}
.right {
flex: 1; /* 剩余宽度分配给right */
}

等分布局

float

.parent{
margin-left: -20px;
}
.column{
float: left;
width: 25%;
padding-left: 20px;
box-sizing: border-box;
}
<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>
  • 备注:存在的一个问题是,这种方法无法根据列数来变化

table

.parent-fix{
margin-left: -20px; /* table没有margin 只能转嫁给上一级 */
}
.parent{
display: table;
width: 100%;
table-layout: fixed; /* 布局优先,单元格宽度默认是平分 */
}
.column{
display: table-cell;
padding-left: 20px;
}
<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>

flex

.parent{
display: flex;
}
.column{
flex: 1;
}
.column+.column{
margin-left:20px; /* 自动分配 减去margin-left之后的空间 */
}
<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>

等高布局

同行的多个元素,保持相同高度。

table

.parent {
display: table;
width: 100%;
table-layout: fixed;
}
.left, .right {
display: table-cell;
}
.left {
width: 100px;
padding-right: 20px;
}
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>

flex

.parent{
display: flex;
}
.left{
margin-right: 20px;
}
.right{
flex: 1;
}
  • 备注:因为flex布局,默认的align-itemsstretch。所以就产生了等高的特性

float

.parent {
overflow: hidden;
}
.left{
padding-bottom: 9999px;
margin-bottom:-9999px;
}
.left{ /* 宽度由内容决定 */
float: left;
margin-right: 20px;
}
.right{
overflow: hidden; /* block formatting context */
}

全屏布局

position

<div class="parent">
<div class="top">top</div>
<div class="left">left</div>
<div class="right"><div class="inner">right</div></div>
<div class="bottom">bottom</div>
</div>
html, body, .parent
{
overflow: hidden;
height: 100%;
margin: 0;
} /*overflow禁用滚动条*/
body
{
color: white;
}
.top
{
position: absolute;
top: 0;
right: 0;
left: 0;
height: 100px;
background: blue;
}
.left
{
position: absolute;
top: 100px;
bottom: 50px;
left: 0;
width: 200px;
background: red;
}
.right
{
position: absolute;
top: 100px;
right: 0;
bottom: 50px;
left: 200px;
overflow: auto;
background: pink;
}
.right.inner
{
min-height: 1000px;
}
.bottom
{
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 50px;
background: black;
}

flex

<div class="parent">
<div class="top">top</div>
<div class="middle">
<div class="left">left</div>
<div class="right"><div class="inner">right</div></div>
</div>
<div class="bottom">bottom</div>
</div>
html,body,.parent{margin:0; height:100%; overflow:hidden;}
body{color: white;}
.parent{display: flex; flex-direction: column;}
.top{height:100px; background: blue;}
.bottom{height:50px; background: black;}
.middle{flex:1; display:flex;}
.left{width:200px; background: red;}
.right{flex: 1; overflow: auto; background:pink;}
.right .inner{min-height: 1000px;}