CSS 有三种基本的定位机制:普通流、浮动和绝对定位,这个三种定位方式在CSS position 属性通过使用 position 属性,我们可以选择 4 种不同类型的定位,这会影响元素框生成的方式,在理解定位之前,我们需要熟悉几个概念。
1、一切皆为框
我们定义的任何html元素,都是一个外包框中,这个外包框决定了元素所占有的尺寸,我们通常说的盒子模型,就是一个标准的外包框包裹的区域,而我们的html元素,就是一个个标准的盒子堆切而成。而这种盒子又有两种呈现方式:
块元素
div、h1 或 p 元素常常被称为块级元素。这意味着这些元素显示为一块内容,即"块框",他们在html的文档流中,以占用整行的方式排列。如以下代码:
<h1>1</h1> <div>2</div> <p>3</p>
呈现的效果如下图:
行元素
span 和 strong 等元素称为"行内元素",这是因为它们的内容显示在行中,即"行内框",在html文档流中,这些元素会挨着一个个显示,直到充满一整行为止。如以下代码:
<a href="HtmlPage.html">1</a> <span>2</span> <strong >3</strong>
呈现的效果如下:
2、文档流
所谓的文档流,指的是元素排版布局过程中,元素会根据自己的特性自动从左往右,从上往下的流式排列。并最终窗体自上而下分成一行行, 并在每行中按从左至右的顺序排放元素。脱离文档流即是元素打乱了这个排列,或是从排版中拿走。当前所知的脱离文档流的方式有两种:浮动和定位。我们这里主要讲解定位
3、position定位
position 属性值的含义:
static:
这个是元素默认的定位方式,元素正常生成,作为文档流的一部分,行内元素则会创建一个或多个行框,置于其父元素中。
relative(相对定位)
生成相对定位的元素,通过top,bottom,left,right的设置相对于其正常(原先本身)位置进行定位。相对有两个概念,假如有父元素,则相对父元素,没有父元素,则相对上一个元素。可通过z-index进行层次分级,relative定位要注意几个概念:
1、定位为relative的元素脱离正常的文本流,但其在文本流中的位置依然存在。
代码1-1
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>案例</title> <style type="text/css"> #main { 300px; height: 300px; background-color: #e0fade; } #re1 { position: relative; 100px; height: 100px; left: 200px; right: 50px; background-color: #ff6a00 } #re2 { 100px; height: 100px; background-color: #b6ff00; } </style> </head> <body> <div id="main"> <div id="re1">re1</div> <div id="re2">re2</div> </div> </body> </html>
我们定义了re1和re2两个div,其效果如下:
re1虽然通过相对位置偏移,但是re1原来占有的区域并没有被释放出来,任然被占用。这里就会产生一个新问题,如果re1占有原来元素,那么到新的位置了,会不会占用新位置的空间呢,我们把div换成span试试,代码如下:
代码1-2
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>案例</title> <style type="text/css"> #main { 300px; height: 300px; background-color: #e0fade; } #re1 { position: relative; 100px; left: 60px; right: 50px; background-color: #ff6a00; } #re2 { 100px; background-color: #b6ff00; } #re3 { 100px; background-color:#0094ff } </style> </head> <body> <div id="main"> <span id="re1">re1</span> <span id="re2">re2</span> <span id="re3">re3</span> </div> </body> </html>
申明了三个span,第一偏移了60像素,那么这个span会偏移到第三个span的位置,我们看看效果:
可以看到,re1所占有的区域,没有释放,且re1偏移到新的位置后,并没有挤出以前的元素,而是和原来的元素进行了叠加,如果我们改变z-index层次,是否能让re3显示到上部呢?我们将re3的z-index设置为2,re1的z-index设置为1,效果显示如下:
显然,z-index并不能改变其显示次序,被浮动的对象,会默认显示在上方。
2、相对定位是默认参照父级的原始点为原始点,无父级,则按照元素文本流的位置进行偏移。
3、当父级内有padding等CSS属性时,当前级的原始点则参照父级内容区的原始点进行定位。
4、Top的值表示对象相对原位置向下偏移的距离,bottom的值表示对象相对原位置向上偏移的距离,两者同时存在时,只有Top起作用。left的值表示对象相对原位置向右偏移的距离,right的值表示对象相对原位置向左偏移的距离,两者同时存在时,只有left起作用。
如图所示,relative定位总是按照父元素或者上一个元素进行定位,其定位不受父元素是何种定位的定位影响。
这里要特别说明一点,假如其没有父元素,且上一个元素发生了偏移,当前元素如何处理呢?
代码1-3
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>案例</title> <style type="text/css"> #main { 300px; height: 300px; background-color: #e0fade; z-index:1; } #re1 { position: relative; 100px; height:100px; left: 100px; right: 100px; background-color: #ff6a00; z-index:2; } #re2 { position: relative; 100px; height: 100px; left: 10px; top: 10px; background-color: #b6ff00; } </style> </head> <body> <div id="re1">re1</div> <div id="re2">re2</div> </body> </html>
我们可以看到效果如下:
re2的偏移并没有受到re1的影响,说明不管上一个元素如何,re2都是按照原本自己所在的位置进行偏移。
absolute(绝对定位)
生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定。可通过z-index进行层次分级。absolute定位也要注意几个概念:
1、定位为absolute的元素脱离正常文本流,但是其在正常流中的位置不再存在。
这个特性和相对定位相反,我们把上一个案例1-1修改为绝对定位,其代码如下:
代码2-1
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>案例</title> <style type="text/css"> #main { 300px; height: 300px; background-color: #e0fade; } #re1 { position:absolute; 100px; height: 100px; left: 200px; right: 50px; background-color: #ff6a00 } #re2 { 100px; height: 100px; background-color: #b6ff00; } </style> </head> <body> <div id="main"> <div id="re1">re1</div> <div id="re2">re2</div> </div> </body> </html>
那么呈现的效果如下图所示:
可以明显知道,re1偏移后,其原来占有的区域被完全释放出来了,那么re2可以去re1的区域。那么也存在相对定位同样的问题,re1到新区域后,和新区域的老对象是如何共存的呢,我们把代码1-2改为绝对定位。
代码2-2
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>案例</title> <style type="text/css"> #main { 300px; height: 300px; background-color: #e0fade; } #re1 { position:absolute; 100px; left: 20px; background-color: #ff6a00; } #re2 { 100px; background-color: #b6ff00; } #re3 { 100px; background-color: #0094ff } </style> </head> <body> <div id="main"> <span id="re1">re1</span> <span id="re2">re2</span> <span id="re3">re3</span> </div> </body> </html>
得到的结果如下:
可以看到,其基本上和相对定位一样,出现叠加在原有元素之上,那么我们设置z-index是否可以改变其显示次序呢?得到的结果和相对定位是一样的,在定位发生变化的浮动对象永远浮动在原有对象之上。
2、没有父级的时候,他是参照浏览器左上角,如果在没有父级元素的情况下,存在文本,则以它前面的最后一个文字的右上角为原点进行定位但是不断开文字,覆盖于上方。
3、有父级,但父级没有设定position属性,那么当前的absolute则以浏览器左上角为原始点进行定位。
4、父级设定position属性(无论是absolute还是relative),则以父级的左上角为原点进行定位。
5、总是以父级左上角为原点进行定位,父级的padding对其根本没有影响。
根据以上的规则,我们是知道了,设置为absolute绝对定位的对象,其只会按照父元素左上角进行定位,这个所说的父元素,是浏览器左上角或者设置了position属性进行相对定位或者绝对定位的元素。其他的元素都不会被绝对定位识别为父亲元素。
代码2-3
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>案例</title> <style type="text/css"> #main { 300px; height: 300px; background-color: #e0fade; } #re1 { position:absolute; 100px; height:100px; left: 100px; top:100px; background-color: #ff6a00; } #re2 { 100px; height: 100px; background-color: #b6ff00; } #re3 { position:absolute; left:20px; top:20px; 100px; height: 100px; background-color: #0094ff; z-index: 3; } #re4 { position: absolute; left: 20px; top: 20px; 100px; height: 100px; background-color: #0001ff; z-index: 3; } </style> </head> <body> <div id="main"> <div id="re1"> <div id="re3">re3</div> </div> <div id="re2"> <div id="re4">re4</div> </div> </div> </body> </html>
以上代码,我们对re1、re3、re4进行了绝对定位,re2没有定位,那么效果如下图
可以看到re3的偏移,是被re1影响的,是参照的父元素的左上角进行偏移的,那么re4呢,到底是参照re2还是浏览器呢,我们对上面的代码进行修改,在mian的div上增加一个div,代码如下:
代码2-4
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>案例</title> <style type="text/css"> #main { 300px; height: 300px; background-color: #e0fade; } #re1 { position:absolute; 100px; height:100px; left: 100px; top:100px; background-color: #ff6a00; } #re2 { 100px; height: 100px; background-color: #b6ff00; } #re3 { position:absolute; left:20px; top:20px; 100px; height: 100px; background-color: #0094ff; z-index: 3; } #re4 { position: absolute; left: 20px; top: 20px; 100px; height: 100px; background-color: #0001ff; z-index: 3; } #header { height:30px; background-color:#92cb7b } </style> </head> <body> <div id="header"></div> <div id="main"> <div id="re1"> <div id="re3">re3</div> </div> <div id="re2"> <div id="re4">re4</div> </div> </div> </body> </html>
其显示效果如下:
由此可知,在设置为绝对定位的元素,其定位参考对象,是设置了绝对和相对定位的父元素和浏览器本身。不会以文档流中设置为static定位的对象为参照。
4、fixed(固定定位)
生成绝对定位的元素,相对于浏览器窗口进行定位。元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定。可通过z-index进行层次分级。其和absolute的区别就是,总是以浏览器窗口为父元素。就不需要特别的说明了。