CSS布局相关

在经过了十几天的笔试和面试后,发现css的内容是很重要的,对于一个frontender,绝对不能掉以轻心。

关于居中

水平居中

  • 用inline-block和text-align实现
.parent {
	text-align: center;
}
.child {
	display: inline-block;
}

多个块状元素要一起实现水平居中,可以使用该方法
优点:兼容性好; 缺点:需要同时设置父子元素

  • margin: 0 auto 块状元素水平居中
.child { display: block; width: 100px; margin: 0 auto; }

优点:兼容性好;缺点:需要指定宽度

  • table
.child { 
	display: table;
	margin: 0 auto;
}

优点:只需要对自身进行设置;缺点:IE6、7兼容

  • 绝对定位实现
.parent { position: relative; }
.child {
	position: absolute;
	left: 50%;
	transform: translate(-50%);
}

缺点:IE9及其以上才可使用

  • flex布局
/* 方法1 */
.parent {
	display: flex;
	justify-content: center;
}
/* 方法2 */
.parent {
	display: flex;
}
.child {
	margin: 0 auto;
}

垂直居中

  • vertical-align 由于对齐的基线是用行高的基线作为标记,故需要设置line-height或设置display:table-cell
/* 方法1 */
.parent {
	display: table-cell;
	vertical-align: middle;
	height: 20px;
}
/* 方法2 */
.parent {
	display: inline-block;
	verticle-align: middle;
	line-height: 20px;
}
  • 绝对定位
.parent {
	position: relative;
}
.child {
	position: absolute;
	top: 50%;
	transform: translate(0, -50%);
}
  • flex
.parent {
	display: flex;
	align-items: center;
}

水平垂直居中

已知宽高的前提下

  • 绝对定位和负margin实现
.father {
	position: relative;
}
.child {
	position: absolute;
	width: 100px;
	height: 100px;
	top: 50%;
	left: 50%;
	margin-left: -50px;
	margin-top: -50px;
}
  • 绝对定位+calc
.father {
	position: relative;
}
.child {
	position: absolute;
	width: 100px;
	height: 100px;
	top: calc(50% - 50px);
	left: calc(50% - 50px);
}

缺点:兼容性不好,需要IE9及其以上,需要知道子元素宽高

在未知宽高的前提下

  • 绝对定位和margin: auto
.father {
	position: relative;
	width: 500px;
	height: 500px;
	border: 1px solid red;
}
.child {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	margin: auto;
	width: 100px;
	height: 100px;
}

优点:兼容性好,支持IE6+;缺点:需要设置父子元素宽高

  • 绝对定位+transform
.father {
	position: relative;
}
.child {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
}

缺点:兼容性不好,需要IE9及其以上

  • line-height line-height不仅可以用在文字的垂直居中上,也可以用在块级元素是垂直居中,不过需要注意,父元素line-height设置的高度要和其height的值一致
.father {
	line-height: 200px;
	text-align: center;  /*水平居中*/
	height: 200px;
	width: 200px;
}
.child {
	display: inline-block;
	vertical-align: middle;  /*垂直居中*/
	width: 20px;
	height: 20px;
}

优点:兼容性好,支持IE6+

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

缺点:兼容性还可以,需要IE8+

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

缺点:兼容性不好,需要IE10+,兼容的标准:

Chrome 29+
Firefox 28+
Internet Explorer 10+
Opera 17+
Safari 6.1+ (prefixed with -webkit-)
Android 4.4+
iOS 7.1+ (prefixed with -webkit-)

  • grid
.father {
    display: grid;
}
.child {
    align-self: center;
    justify-self: center;
}

建议不用,兼容性比flex还差

其他

浮动元素如何实现居中

  • 父元素margin:0 auto 注意,这个父元素需要设置随机宽度(或者设置display:table),并且设置margin: 0 auto
<style>
.box {
  margin: 0 auto;
  width: 100px;
}
.fl {
  float: left;
}
</style>
<div class="box">
	<div class="fl">box</div>
</div>
  • 父元素浮动 父元素按子元素反方向浮动,并设置对应的left或right为50%,同时要注意需要设置relative定位
<style>
.box{
    float:left;
    position:relative;
    left:50%;
}
.fl{
    float:left;
    position:relative;
    right:50%;
}
</style>
<div class="box">
    <div class="fl">box</div>
</div>

两栏布局

左栏定宽,右栏自适应

  • float+margin
.left {
	float: left;
	width: 100px;
}
.right {
	margin-left: 100px;
}

注意在IE6下两栏间有3px的bug

  • float:left + float:right
<style>
	.left{width:100px;float:left;}
	.right-fix{width:100%;margin-left:-100px;float:right;}
	.right{margin-left:100px;}
</style>
<div class="parent">
    <div class="left"></div>
    <div class="right-fix">
        <div class="right"></div>
    </div>
</div>
  • 绝对定位
.parent {
	position: relative;
}
.left  {
	position: absolute;
	left: 0;
	width: 100px;
}
.right {
	position: absolute;
	left: 101px;   /*多出的1px是间隔*/
	right: 0;
}

左栏不定宽,右栏自适应

  • float + BFC
.left {
	width: 100px;
	float: left;
}
.right {
	overflow: hidden;
}
  • table
.parent{display:table;table-layout:fixed;width:100%;}
.left{width:100px;}
.right,.left{display:table-cell;}
  • flex
.parent{display:flex;}
.left{width:100px;}
.right{flex:1;}

三栏布局

左右定宽,中间自适应

  • 左右绝对定位,中间设置margin
<style>
body,html{
	    padding: 0px;
	    margin:0px;
	}
.left,.right{
    position: absolute;
    top:0px;
    background: red;
    height:100px;
}
.left{
    left:0;
    width:100px;
}
.right{
    right:0;
    width:200px;
}
.main{
    margin-left: 100px;
    margin-right: 100px;
    height:100px;
    background: blue;
}
</style>
<div class="left">Left</div>
<div class="main">Main</div>
<div class="right">Right</div>
  • 左右两栏分别左右浮动,中间设置margin
<style>
#left {
	float: left;
	width: 220px;
	height: 200px;
	background: blue;
}
#right{
	float: right;
	  width: 220px;
	height: 200px;
	background: yellow;
}
		
#main {
	margin: 0 220px;
	background: red;
	height: 200px;
}
</style>
<div id="left">left </div>
<div id="right">right</div>
<div id="main">mian</div>
  • 三栏设置float,外部创建BFC
<style>
    .wrap {
    	overflow: hidden;
    }
    .left {
	    float: left; 
	    width: 200px; 
	    height: 100px; 
	    background: coral; 
	    margin-left: -100%;
    }
    .middle {
	    float: left;
	     width: 100%; 
	     height: 100px;
     }
	.main {
		text-align:center; 
		background: blue; 
		height: 100px;
	}
    .right {
	    float: left; 
	    width: 120px; 
	    height: 100px; 
	    background: gray; 
	    margin-left: -120px;
    }
</style>
<div class="wrap">
    <div class="middle">
        <div class="main">中间</div>
    </div>
    <div class="left">左侧</div>
    <div class="right">右侧</div>
</div>

这种方法的缺点是需要嵌套多一层的父元素

中间定宽,左右自适应

  • 三栏float布局,中间固定宽度
<style>
.left,.right {
	float: left;
	width: 50%;
	margin-right: -100px;
	background: orange;
	*width: 49.9%;   /*防止在IE下布局混乱*/
}
.main {
	width: 200px;
	float: left;
	background: green;
}
</style>
<div class="left">Left</div>
<div class="main">Main</div>
<div class="right">Right</div>
  • flex布局
<style>
.wrap {
  display: flex;
}
.left, .right {
  background: red;
  flex: 1;
}
.main {
  width: 300px;
  background: blue;
}
</style>
<div class="wrap">
	<div class="left">Left</div>
	<div class="main">Main</div>
	<div class="right">Right</div>
</div>

圣杯布局

它也是左右两侧定宽,中间自适应。实现原理类似前面提到的float+BFC方案
需要设置padding值,需要理解负边距的作用,左栏margin-left:-100%使它上移一行,同时右栏向左移占据左栏原先位置,同理,右栏的margin-left:-100px使它上移并靠右

<style>
	.wrap {
			overflow: hidden;
			padding: 0 100px;
		}
		.main {
			position:relative;			
			width: 100%;
			float: left;
			height: 80px;
			background: green;
		}
		.left {
			position:relative;
			width: 100px;
			float: left;
			left:-100px;
			height: 80px;
			margin-left: -100%;
			background: yellow;
		}

		.right {
			position:relative;			
			width: 100px;
			float: left;
			right:-100px;
			height: 80px;
			margin-left: -100px;
			background: pink
		}
</style>
  
<div class="wrap">
		<div class="main"></div>
		<div class="left"></div>
		<div class="right"></div>
</div>

双飞翼布局

也是左右定宽,中间自适应。和前面圣杯布局类似,不过使用的是margin。

<style>
.wrap {
	overflow: hidden;
}
.main {			
      width: 100%;
      float: left;
      background: green;	
      height: 80px;
}
.left {
	width: 100px;
	float: left;
	height: 80px;
	margin-left: -100%;
	background: yellow;
}

.right {			
	width: 100px;
	float: left;
	height: 80px;
	margin-left: -100px;
	background: pink
}
</style>
<div class="wrap">
		<div class="main"></div>
		<div class="left"></div>
		<div class="right"></div>
</div>



参考