CSS定位布局

学习 html+css 有个把月了,今天总结下CSS的布局定位。本文所有代码效果演示均为 html 渲染生成而非截图。

开始

CSS提供五种定位(position)属性:
staticrelativeabsolutefixedinherit。理解这些属性用途是掌握 CSS 布局的关键。

认识文档流

首先,让我们先熟悉默认的 html 文档布局模式,一个简单的 html 文档。

<html>  
<head></head>  
<body>  
<h1>******************</h1>  
<p><em>***********</em></p>  
<h2>******************</h2>  
<p><img><span>**</span></p>  
</body>  
</html>  

在浏览器中呈现时从上至下,由左到右流动排列布局。每个块级元素都从新的一行开始,并且其后的元素也另起一行,块元素(block-level elements)如h1pdiv等标签包围的元素独占一行,它们的左右不会出现其他元素。内联元素(inline-level elements)如aimgemspan等标签包围的元素则由左至右,挤满一行后流动到下一行开始。这种默认的排列方式,称之为常规流Normal flow。

注意:元素的自然流动,不受它本身内容影响,就算一张图片尺寸很高,但跟在它两旁的文字只能有一行。

static 默认值

staticposition属性的默认值,此时元素正常出现在文档流中,这种情况下对元素设置偏移量 leftrighttopbottom还有z-index都是无效的。实际上,static元素甚至不能为其后代元素的定位提供坐标参照(下文有解释),它后代元素设置leftright等偏移属性跟它没有任何关系。

示例A代码和演示结果

<style>  
  div{ width:200px;height:200px; }
  #box1{ position: static; background: #b7d84b; }
  #box2{ position: static; background: #FFA500; }
  #box3{ position: static; background: #44accf; }
</style>  
<body>  
  <div id="box1">  </div>
  <div id="box2">  </div>
  <div id="box3">  </div>
</body>  
示例A、B演示

relative 相对定位

relativestatic对元素定位的影响表面看上去很像,在未设置left,top等偏移属性时,元素依然是按照正常流排列.

示例B代码,效果如示例A相同。

<style>  
  div{ width:200px;height:200px; }
  #box1{ position: relative; background: #b7d84b; }
  #box2{ position: relative; background: #FFA500; }
   #box3{ position: relative; background: #44accf; }
</style>  
<body>  
  <div id="box1">  </div>
  <div id="box2">  </div>
  <div id="box3">  </div>
</body>  

设置leftright偏移属性后,相对定位元素依然存在于文档流中,按照设置的偏移量移动到目标位置.但是它在原本文档流中占用的空间依然被保留,前后的元素不会受到影响,该在哪儿还是在哪儿.这也意味着相对定位可能产生元素的重叠。

示例C代码

<style>  
    div{ width:100px;height:100px; }
    #box1{ position: relative; background: #b7d84b; }
    #box2{ 
    position: relative;
    background: #FFA500;
    top: -40px;
    left: 40px;
    } 
    #box3{ position: relative; background: #44accf; }
</style>  
<body>  
    <div id="box1">  </div>
    <div id="box2">  </div>
    <div id="box3">  </div>
</body>  
示例C演示

演示效果中虚线框里的白色部分就是box2偏移前位置。

注意:相对定位设置偏移量的参照系是元素自己在原本常规流中的位置!设置相对定位不会改变元素的 display 属性。设置相对定位的作用之一是可以为后代其他定位提供坐标参照。

absolute 绝对定位

和前两个不同,绝对定位的元素会被从正常文档流中剔除,它元素在常规流中被消失,在设置绝对定位后,原来位置的前后元素会当它不再存在。这意味着我们可以使用绝对定位把元素放在想要的位置,而不影响其他元素文档流。绝对定位元素也不会被其他元素影响。

示例D代码

<style>  
 div{ width:100px;height:100px; } 
 #box1{ position: absolute; background: #b7d84b; top: 0px;left: 0px;} 
 #box2{ position: absolute; background: #FFA500; top: 0px; right: 0px;} 
 #box3{ position: absolute; background: #44accf; bottom: 0px;left: 0px;}
 #box4{ position: absolute; background: #9685BA; bottom: 0px;right: 0px;}
</style>  
<body>  
    <div id="box1">  </div>
    <div id="box2">  </div>
    <div id="box3">  </div>
    <div id="box4">  </div>
</body>  
示例D演示

绝对定位元素设置偏移属性时的参照系很有讲究, 参照目标为该元素的祖先元素里第一个position值为非static的元素。如果它所有父辈元素的position都不存在非static值,则根据浏览器边界定位。注意不是根据body元素定位。前面提到元素设置相对定位的一个用途就是为后代元素提供绝对定位的参照系。

示例E代码

<style>  
  #grandpa {
    width: 350px;
    height: 250px;
    position: relative;
    background: #b7d84b;
  }
  #papa {
    width: 300px;
    height: 200px;
    background: #FFA500;
  }
  #kids {
    width: 100px;
    height: 100px;
    position: absolute;
    background: #44accf;
    bottom: 0px;
    right: 0px;
  }
</style>  
<body>  
  <div id="grandpa">我是爷爷
    <div id="papa">我是爸爸
      <div id="kids">我是爸爸的儿子,爷爷的孙子</div>
    </div>
  </div>
</body>  
我是爷爷#grandpa
我是爸爸#papa
我是爸爸的儿子,爷爷的孙子#kids
示例E演示

可以看到,div#kids的父元素div#papa未定义position属性值,默认是static。所以div#kids绝对定位的bottom: 0px;right: 0px是以div#grandpa为参照系。 当然,如果对div#papa设置position: relative结果会如下。

我是爷爷#grandpa
我是爸爸#papa
我是爸爸的儿子,爷爷的孙子#kids
示例E的坐标系演示

注意:设置绝对定位的元素display属性会变成block(可设置高宽度)。

fixed 固定定位

固定定位元素和绝对定位的规则基本相同,因为position:fixed本身就是position:absolute的一个子类。它们的区别是固定元素定位的参照系是浏览器窗口。将元素固定定位到页面某个位置后,上下滚动页面时元素会始终钉在窗口不动。

固定定位示例代码

#iamfixed{
         position:fixed;
         left:0px;bottom:0px;
         width:30px;
         height:30px;
         background: #D9D9D9;
        }
    <div id="iamfixed"></div>

演示效果请看本页面左下角灰色方块

inherit 继承

继承就是从父元素继承position属性,不过要注意,position无继承性。元素不会主动去继承父元素的定位属性,没设置任何position时默认为static

结束。

参考: CSS Positioning 101