参考文章:http://www.cnblogs.com/gaohuijiao/p/6371010.html
http://www.cnblogs.com/gaohuijiao/p/6369138.html
CSS 有三种基本的定位机制:普通流、浮动和定位Position。影响元素定位的是浮动和Position。
在分析定位之前,理解一下行级元素和块级元素。行级元素:元素在一行内排列,高度由内容决定。块级元素:独自占一行且宽度会占满父元素宽度。
1、普通流
普通流:除非专门指定,否则所有框都在普通流中定位。普通流中元素框的位置由元素在(X)HTML中的位置决定。块级元素从上到下依次排列,框之间的垂直距离由框的垂直margin计算得到。行内元素在一行中水平布置。
2、浮动布局
浮动布局:CSS 的 Float(浮动),会使元素向左或向右移动,使元素共享一行,类似于给元素加了inline-block的作用。在w3c中这样描述浮动:浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。
浮动布局的影响
1、脱离文档流,不占据页面空间
<html>
<head>
<title></title>
<style type="text/css">
.div1{
width: 150px;
height: 100px;
background: pink;
}
.div2{
width: 100px;
height: 150px;
background: lavender;
}
.div3{
width: 300px;
height: 200px;
background: skyblue;
}
</style>
</head>
<body>
<div class="div1">150 * 100</div>
<div class="div2">100 * 150</div>
<div class="div3">300 * 200</div>
</body>
</html>
div 是块级元素,在标准文档流中,div各占一行,如果讲div1,div2添加float:left。
粉色的div和紫色的div覆盖在了蓝色div的上面。这是因为浮动元素脱离了标准流到了浮动层,浮动层比标准层要高并且不占据页面空间,所以我们看到div1和div2覆盖在了div3上面,虽然是覆盖但是div3里面的文字会被挤走,此时div3仍然在标准层所以仍然是占据页面空间的。
2、浮动元素将行内元素和行块元素转化为块元素
<html>
<head>
<title></title>
<style type="text/css">
.span1{
width: 200px;
height: 200px;
background: red;
}
.span2{
width: 200px;
height: 200px;
background: green;
}
.span3{
width: 200px;
height: 200px;
background: blue;
}
</style>
</head>
<body>
<span class="span1">span1</span>
<span class="span2">span2</span>
<span class="span3">span3</span>
</body>
</html>
行内元素共享同一行,中间有间隔,宽度和高度属性不起作用,此时,我们给每个span1加浮动属性float:left
很显然,浮动过后的元素宽度和高度属性开始起作用,说明span元素从行标签变成了块标签。
3、清除浮动
假如说我们要实现如下布局,上方是导航部分,下方是内容部分,导航部分两个块左右浮动。
<html>
<head>
<title></title>
<style type="text/css">
.nav{
width: 100%;
background: #c0c0c0;
padding: 10px;
}
.left{
width: 300px;
height: 50px;
background: pink;
float: left;
}
.right{
width: 300px;
height: 50px;
background: #abcdef;
float: right;
}
.content{
height: 400px;
background: url("a.jpg");
background-size: cover;
}
</style>
</head>
<body>
<!-- 导航部分 -->
<div class="nav">
<div class="left">logo</div>
<div class="right">右边区域</div>
<div class='clear'></div>
</div>
<!-- 内容部分 -->
<div class="content"></div>
</body>
</html>
结果解析: 块级元素如果没有给高度,那么高度是由子元素还有padding值撑起来的,当left和right浮动之后脱离了文档流,不再占据页面空间,所以它们的父级的高度只有padding值,因而造成了上图的结果
1、给浮动元素的父级一个高度。
.nav{
height: 50px; //增加高度
}
给浮动元素的父级一个高度,使之占据页面空间,这种写法的优点是简单容易理解,但是缺点也很突出,不适用于高度不固定的div。
2、给浮动元素的父级加overflow:hidden
.nav{
overflow: hidden; //增加
}
overflow:hidden 的意思是超出的部分要裁切隐藏掉,那么如果 float 的元素不占普通流位置,普通流的包含块要根据内容高度裁切隐藏。如果高度是默认值auto,那么不计算其内浮动元素高度就裁切,就有可能会裁掉float元素。所以如果没有明确设定容器高情况下,它要计算内容全部高度才能确定在什么位置hidden,浮动的高度就要被计算进去,顺带达成了清理浮动的目标。
3、给浮动元素的兄弟元素加clear:both
<html>
<head>
<title></title>
<style type="text/css">
.nav{
width: 100%;
background: #c0c0c0;
padding: 10px;
}
.left{
width: 300px;
height: 50px;
background: pink;
float: left;
}
.right{
width: 300px;
height: 50px;
background: #abcdef;
float: right;
}
.content{
height: 400px;
background: url("a.jpg");
background-size: cover;
}
.clear{
/*clear: both;*/
}
</style>
</head>
<body>
<!-- 导航部分 -->
<div class="nav">
<div class="left">logo</div>
<div class="right">右边区域</div>
<div class='clear'></div>
</div>
<!-- 内容部分 -->
<div class="content"></div>
</body>
</html>
这个也能达到目的的,但是个人倾向于 overflow: hidden;
Position属性有四个值,分别为static、relative、absolute、fixed,定位元素通过属性left和top来控制定位元素的位置,默认情况下为0。
1、static 静态定位
static是position属性的默认值。表示没有定位,元素出现在正常的流中。这个时候你给这个元素设置的left,right,bottom,top这些偏移属性都是没有效果的,不会生效,比如你设置一个距离左边距偏移100px的声明:left:100px 那么这条声明不会起到任何效果。还有z-index属性在这时也不会生效。
2、relative 相对定位
relative 相对定位的元素在标准流中,relative相对于正常的位置。
<html>
<head>
<title></title>
<style type="text/css">
.father{
width: 500px;
height: 500px;
background: pink;
margin: 0 auto;
}
.son{
width: 200px;
height: 200px;
background: lavender;
margin: 0 auto;
/* position: relative; 增加后看图二
left: 50px;
top: 20px;*/
}
</style>
</head>
<body>
<!-- 导航部分 -->
<div class="nav">
<div class="father">
<div class="son">son</div>
</div>
</body>
</html>
2、absolute 绝对定位
绝对定位元素会脱离文档流,其次,我们来分析绝对定位元素是根据什么来进行定位的,绝对定位元素首先会找其距离最近的定位(static除外)的父级元素,如果没有定位父级元素,则会一直往上找,直到根元素html,也就是说绝对定位元素如果没有定位父级元素,则会相对于html来进行定位。
<html>
<head>
<title></title>
<style type="text/css">
.father{
width: 500px;
height: 500px;
background: pink;
margin: 0 auto;
}
.son1{
width: 150px;
height: 150px;
background: lavender;
margin: 0 20px;
position: absolute;
left: 0px;
top: 0px;
}
.son2{
width: 150px;
height: 150px;
background: skyblue;
margin: 0 20px;
position: absolute;
left: 0px;
top: 0px;
}
</style>
</head>
<body>
<!-- 导航部分 -->
<div class="father">
<div class="son1">son1</div>
<div class="son2">son2</div>
</div>
</body>
</html>
效果分析:
绝对定位元素会脱离文档流,后面定位的会覆盖前面定位的,所以son2盖在了son1上面。son1和son2没有定位父级,所以相对于根元素html来进行定位。如果有定位元素又会怎么样,来看如下代码:
.father{
position: relative;
width: 500px;
height: 500px;
background: pink;
margin: 0 auto;
}
.son1{
width: 150px;
height: 150px;
background: lavender;
margin: 0 20px;
position: absolute;
left: 0px;
top: 0px;
}
.son2{
width: 150px;
height: 150px;
background: skyblue;
margin: 0 20px;
position: absolute;
left: 50px;
top: 50px;
}
效果分析:
father是son1和son2的定位父级,所以son1和son2相对于father进行定位,因为son2是后来定位的所以son2覆盖在了son1的上面。因为相对定位的特性,所以相对定位经常用来作为绝对定位的包含盒。
4、fixed 固定定位
很多时候页面中需要用到固定定位,比如说页面右下角的回到顶部按钮等。固定定位就是将元素根据浏览器窗口的大小始终固定在这个地方,即使页面滑动,也不影响它的位置。我们来看如下案例:
这个是没有定位时的效果。
添加css代码
.backTop{
width: 70px;
height: 70px;
background: pink;
position: fixed;
right: 30px;
bottom: 30px;
}
即使随着页面的滚动,按钮的位置也不会发生改变。页面中很多广告区域,即使页面滚动,广告的位置始终在那儿,这也是利用固定定位实现。注意,固定定位元素也是脱离文档流的。
总结:
对于浮动的几种情况,我们只需要从两方面来考虑,一方面是定位元素根据什么来进行定位的问题,另一方面是定位元素是否脱离文档流的问题(关于脱离文档流的问题此处不多加阐述)。只要这两方面理解透彻了就很容易明白定位了,我们接下来对几种定位来做一下总结:
position:static(静态定位) fixed(固定定位) relative(相对定位) absolute(绝对定位)
static:position的默认值,相当于没有定位。不脱离文档流,占据页面空间。
relative:位置相对于自身的位置。不脱离文档流,占据页面空间。
absolute:位置相对于已定位的父级元素。脱离文档流,不占据页面空间。
fixed:位置相对于浏览器窗口。脱离文档流,不占据页面空间。