轻轻松松学CSS:position

position属性表示元素的定位类型,在CSS布局中,position发挥着非常重要的作用,一些元素的布局就是用position完成的,鉴于此,本文结合一些小实例详细讲解一下。

position属性在通常情况下有4个可选值,分别是:static、fixed、relative、absolute。(还有第5个属性sticky,因部分浏览器可能还不支持,本文暂不介绍)

一、static

默认值,因为实际设计网页的时候“用不着”,所以不做介绍。(你如果很好学,可以随便在网上搜一下,一搜就一大把,一般我们遇到一大把的解答就抓狂,似是而非的说法一大堆向你扑面而来,一定搞得你懵圈,但是我要负责地告诉你这个不会,随便看一个人的解答,他都会讲得清楚明白,几乎每个人讲解的核心意思都是:这是“默认值”,实践中几乎用不到,对很多人来说懂与不懂一个样!呵呵,这下你坦然了吧!)

fixed、relative、absolute好像性格不同的三个人物,掌握了三个人物的性格特点基本,就掌握了这块知识。我尽可能用最通俗、最形象的语言来描述他们,让读者在轻松快乐中学习。

二、fixed

轻松调侃完static之后,紧接着就聊fixed。在之前查阅的资料中,没有(几乎没有)马上就介绍fixed的,一般都是static-relative-absolute-fixed这样的顺序,fixed排在最后。我不随波逐流,我觉得fixed特立独行,他是野孩子,他不受祖制约束(不是“组织约束”,但他确实也不受“组织约束”),桀骜不驯。没有家长的管教,他无组织、无纪律,是典型的独行侠,因此学习他就相对简单(“相对简单”是指在html、css中牵扯因素少),先学简单的符合读者的认知规律。

现在,读者对fixed还没有一个具体的感知,先举个简单的例子-浮动广告,代码如下:

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>悬浮广告</title>
 6         <style>
 7             .content1{
 8                 height:1500px;
 9                 background:#ccc;
10             }
11             .content2{
12                 height:2000px;
13                 background:#ddd;
14             }
15 
16             .guanggao{
17                 position:fixed;
18                 top:100px;
19                 right:80px;
20             }
21         </style>
22     </head>
23     <body>
24         <div class="content1">
25             这是网站第一部分内容,右上角是悬浮广告,top和right的值都是相对浏览器窗口的位置
26         </div>
27         <div class="guanggao">
28             <img src="img/guanggao.jpg">
29         </div>
30         <div class="content2">
31             这是网站第二部分内容,浮动广告脱离文档流,所以它就和网站第一部分内容紧挨着了
32         </div>
33     </body>
34 </html>

悬浮广告 Code

悬浮广告是固定定位(position:fixed),他脱离了文档流,在html安排顺序中,悬浮广告(<div class=”guanggao”><img src=”…”></div>)本来的位置是在,第一部分内容(<div class=”content1”>…</div>)与第二部分内容(<div class=”content2”>…</div>)之间的,因为他脱离了文档流,第一部分内容和第二部分内容就当他不存在一样,两个块元素(block)紧挨在一起。浮动广告只相对于浏览器窗口定位,和position:fixed配合的偏移属性top:100px,right:80px都是相对于浏览器窗口来说的,效果图如下:

fixed叫“固定定位”,读者运行代码后应该能体会出,悬浮广告总是相对浏览器窗口保持top=100px,right=80px不动,滚动条怎么滚动都改变不了他的位置。

为了更加有力地说明固定定位不受祖制约束,请把上边地代码调整一下,把悬浮广告(<div class=”guanggao”><img src=”…”></div>)放在第一部分内容中或者是第二部分内容中,在此以放在第一部分内容中为例

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>悬浮广告2</title>
 6         <style>
 7             .content1{
 8                 height:1500px;
 9                 background:#ccc;
10             }
11             .content2{
12                 height:2000px;
13                 background:#ddd;
14             }
15 
16             .guanggao{
17                 position:fixed;
18                 top:100px;
19                 right:80px;
20             }
21 
22         </style>
23         <script>
24             
25         </script>
26     </head>
27     <body>
28         <div class="content1">
29             这是网站第一部分内容,右上角是悬浮广告,top和right的值都是相对浏览器窗口的位置
30             <div class="guanggao">
31                 <img src="img/guanggao.jpg">
32             </div>
33         </div>
34         <div class="content2">
35             这是网站第二部分内容,浮动广告脱离文档流,所以它就和网站第一部分内容紧挨着了
36         </div>
37     </body>
38 </html>

悬浮广告2 Code

运行效果和上面的第一段代码完全一样,故而不附效果图了。

他完全不受第一部分内容的约束(不受祖制的约束),运行后他的偏移属性(top、right)都是相对浏览器窗口来说的,他的位置跟第一部分内容一点关系都没有。各位读者,我说明白了吗?

 

下面再举个稍微复杂点(因为有jquery)的例子-遮罩

遮罩的应用广泛,一般用于凸显一部分内容同时也就淡化其他内容,比如注册、登录、新增表单、修改表单等,这里以登录为例(注册、新增表单、修改表单跟登录道理类似)

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>遮罩</title>
 6         <script src="//libs.baidu.com/jquery/2.0.0/jquery.js"></script>
 7         <style>
 8             .fixed{
 9                 position:fixed;
10                 width:100%;
11                 height:100%;
12                 left:0;
13                 top:0;
14                 display:none;
15                 background:rgba(0,0,0,0.5);
16             }
17             
18             .login{
19                 position:absolute;
20                 top:50%;
21                 left:50%;
22                 width:300px;
23                 display:none;
24                 margin-top:-200px;
25                 margin-left:-150px;
26                 border:1px solid #ccc;
27                 padding:60px 40px;
28                 background:orange;
29                 border-radius:20px;
30             }
31             
32             .login p{
33                 text-align:center;
34             }
35             .login p input{
36                 width:78%;
37                 height:40px;
38                 background:#ccc;
39                 border-radius:5px;
40             }
41             #submit{
42                 margin-top:80px;
43                 height:50px;
44             }
45             
46         </style>
47         <script>
48             $(function(){
49                 $('button').click(function(){
50                     $('.fixed').css('display','block');
51                     $('.login').css('display','block');
52                 });
53                 $('#submit').click(function(){
54                     $('.fixed').css('display','none');
55                     $('.login').css('display','none');
56                 })
57             })
58         </script>
59     </head>
60     <body>
61     <button class="button">登录</button>
62     <div class="fixed"></div>
63     <div class="login">
64             <p><input type="text" placeholder="请输入用户名"></p>
65             <p><input type="password" placeholder="请输入密码"></p>
66             <p><input id="submit" type="button" value="登录"></p>
67     </div>
68     </body>
69 </html>

遮罩 Code

点击下图中的“登录”按钮

此时,出现登录框,并且在登录框周围有遮罩效果(遮罩:凸显登录框,淡化周围元素。出现登录框和遮罩需要用到js或jQuery知识,这些知识不在本文讨论的范围之内)

点击上图登录框中的“登录”按钮,遮罩消失。(这里也用到js或jQuery知识)

因为遮罩应用较多,所以把上边的代码解释一下:

遮罩(<div class=”fixed”></div>)需要把整个屏幕遮罩住,所以定位在top=0,left=0,并且全屏宽(width:100%)、全屏高(height:100%),为了不使下面的元素完全看不见,设置了透明度为0.5,background:rgba(0,0,0,0.5)背景是黑色,透明度为50%。

有的读者注意到登录框(<div class=”login”>…</div>)也是固定定位(<style>  .login{position:fixed;…} … </style>),其实他也可以设置为absolute,如果没有设置登录框的position属性就无法保证登录框显示在遮罩之上(这涉及到定位元素的堆叠顺序的知识,因不是本文重点,故而点到为止)

这么一看,好像fixed也不简单呀。其实,悬浮广告还是非常好理解的,遮罩需要点js或jQuery知识,这样就增加了一点难度,但是对读者(要有一点点html、css基础,我的文章主要面对这样的读者)来说,努力一下应该能够克服,毕竟为了实现自己的理想,为了技术上有所提高,这样的难度应该不是大事。退一步说,遮罩你理解不了,悬浮广告总能理解吧?能理解这一关也算勉强通过了。

下一关,让我们见识见识relative,他又是怎样的一个人呢?

 

三、relative

请读者先看下面这段代码,为了增加读者阅读代码的愉悦感,先从最简单、最基本的入手。以下的代码非常简洁,只有Box2设置了定位属性(position:relative),其他元素均未设置定位属性,这样就简化了问题,便于读者理解。

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>relative_Box2</title>
 6         <style>
 7            div{
 8                 width:100px;
 9                 height:100px;
10                 
11            }
12            #Box2{
13             position:relative;
14             left:20px;
15             top:50px;
16             background:orange;
17            }
18            #Box1{
19             background:green;
20            }
21            #Box3{
22             background:blue;
23            }
24         </style>
25     </head>
26     <body>
27         <div id="Box1">Box1</div>
28         <div id="Box2">Box2</div>
29         <div id="Box3">Box3</div>
30     </body>
31 </html>

relative Code

效果图如下:

relative是相对定位,相对谁定位呢?相对于自己,确切地说是相对于自己偏移之前(图中虚线框就是Box2原本的位置)。别人的定位基准是html/body,或是祖辈,relative也挺个性,是个自恋狂,他以自我为中心,只和自己定位前的位置比较,未设置position:relative时在哪个位置,设置position:relative后的位置就和未设置时比较,进行偏移。Box2就相对于虚线框位置进行偏移。(position:relative当然要配合使用偏移属性top、left、right、bottom等,如果没有偏移属性配合使用,光有position:relative,跟没有设置position是一样的,瞎子点灯——白费蜡)。

读者发现一个问题没有?relative他虽然偏移了,但原来的位置还在那儿,Box1和Box3是不能挤占的,灵魂虽然走了,但躯体还在那儿,有点像单位里吃空饷的,拿着工资,办公桌还在那儿摆着,就是没见他上过班。这些让我想起了一个成语“尸位素餐”!

下面,举个relative应用的例子

读者在点击导航栏上的菜单时,可能会遇到超链接发生稍许偏移的情况,这是因为这种效果能和用户有个交互,增加用户体验。

代码很简单,如下:

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>relative_a</title>
 6         <style>
 7            li{
 8             display:inline-block;
 9             margin:0 20px;
10            }
11            li:hover{
12             position:relative;
13             top:10px;
14             left:6px;
15            }
16         </style>
17     </head>
18     <body>
19         <ul>
20             <li><a href="#">首页</a></li>
21             <li><a href="#">新闻</a></li>
22             <li><a href="#">联系我们</a></li>
23             <li><a href="#">关于我们</a></li>
24         </ul>
25     </body>
26 </html>

relative_a Code

效果图如下:

这个例子,读者理解吗?如果理解了,请往下看另一个例子——阴影效果,这个例子也不难

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>relative_shadow</title>
 6         <style>
 7         div.shadow{
 8             background:#ccc;
 9             float:right;
10         }
11         
12            img{
13             position:relative;
14             left:-5px;
15             top:-5px;
16             
17             border:1px solid #465B68;
18             padding:6px;
19             background:#fff;
20             width:208px;
21             height:151px;
22            }
23         </style>
24     </head>
25     <body>
26         <div class="shadow">
27             <img src="img/guanggao.jpg">
28         </div>
29     </body>
30 </html>

relative_shadow Code

效果图如下:

div的背景是灰色,照片本来是和它重叠的,看不到背景,可是照片相对定位(relative)后,(相对自己原来的位置)向左偏移5px,向上偏移5px,由于它未脱离文档流,它的躯壳还在原来的位置不动,并且露出了div的背景,这样就形成了阴影效果。

 

读者可能感觉出relative个性鲜明,只和自己比较,应该是最简单的呀!可以这么理解,但是relative不总是唱独角戏,他有时和absolute联袂出演,所以,读者还是先对absolute有个了解吧。

 

四、absolute

absolute是绝对定位,读者先看一段代码(凡是让读者上来就看一段代码,而不是讲解知识点然后再看代码,都是因为代码很简单,并且需要借助于代码说明问题,所以,读者尽管放心,不要一上来看到的是代码就有畏难情绪,以为代码比文字更费解,恰恰相反,这种情况下,代码一定很简单,我写文章尽量不给读者设置阅读障碍)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>absolute_Box2</title>
<style>
body{
background:gray;
height:5000px;
}
.wrap{
border:2px solid blue;
}
#Box1,#Box3{
height:200px;
background:orange;
border:1px dashed red;
}
#Box2{
position:absolute;
bottom:100px;
right:200px;
background:orange;
border:1px dashed red;
}
</style>
</head>
<body>
<div class="wrap">
<div id="Box1">Box1</div>
<div id="Box2">Box2</div>
<div id="Box3">Box3</div>
</div>
</body>
</html>

absolute_Box2 Code

效果图如下:

这段代码和relative第一段代码差别不是很大,这段代码只有Box2设置了定位属性(position:absolute),其他元素均未设置定位属性,这是为了简化问题,防止其他因素干扰,实际情况中未必这样,有时absolute和其他定位属性的值(比如:relative)可能同时出现,这是本文后面要讨论的,后面再说。

在这个前提条件下(上段文字中的“只有Box2….,其他元素均未….”),注意前提条件,本段的结论,如果脱离前提条件,就不成立了。在此,提示读者这一点。Box2设置了绝对定位,他的偏移属性(例如本例中bottom:100px,right:200px)是相对浏览器窗口来说的。(再次说明,在满足本段的前提条件下,结论才成立。后面会讲到前提条件变了,偏移属性就不再相对于浏览器窗口来说了。本段提到 “前提条件”有5次之多!)

absolute脱离了文档流(这一点和谁相像,对——是fixed),absolute(fixed)不在这个单位上班,调走了,就不在这个单位领工资了,更没有他的办公桌了,relative吃空饷,摆办公桌也不上班,灵魂走了,躯壳还在(占位)。这是absolute和fixed的相同点,同时也是absolute(fixed)和relative的区别。

absolute在满足“前提条件”(就是“只有Box2…,其他元素均未…”那个前提条件)时和fixed相同,偏移属性相对于浏览器窗口来说的。

有的读者问了,这么说fixed和absolute几乎完全一样了?确实,相同的地方很多,但不同的地方还是有的,比如,在滚动条滚动时,fixed在浏览器窗口中是不动的(fixed,固定不动的意思),absolute是随着滚动条滚动的。读者可以往回看,对比一下悬浮广告和满足“前提条件”下的Box2,就明白这一点了。

当然,absolute和fixed还有其它不同,读者在继续学完absolute后就知道了。

前面讲到absolute的那段代码(“前提条件”Box2那段),很简洁,当时是为了说明问题方便,实际情况下,在整个代码段中,absolute往往不是自己出现,经常和别的定位值一起使用,更多的时候是和relative一起出现。还记得在relative的最后那句话吗?——“relative不总是唱独角戏,他有时和absolute联袂出演”。

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>relative-absolute_Box2</title>
 6         <style>
 7             body{
 8                 background:gray;
 9                 height:5000px;
10             }
11             .wrap{
12                 border:2px solid blue;
13                 position:relative;
14             }
15             #Box1,#Box3{
16                 height:200px;
17                 background:orange;
18                 border:1px dashed red;
19             }
20             #Box2{
21                 position:absolute;
22                 bottom:100px;
23                 right:200px;
24                 
25                 background:orange;
26                 border:1px dashed red;
27             }
28         </style>
29     </head>
30     <body>
31     <div class="wrap">
32         <div id="Box1">Box1</div>
33         <div id="Box2">Box2</div>
34         <div id="Box3">Box3</div>
35     </div>
36     </body>
37 </html>

relative-absolute_Box2 Code

上面的代码里既有relative,也有absolute,还是Box2,只是外面的包裹器(class=“wrap”)多了一个定位属性(position:relative)。为了说明问题,在不改变代码含义前提下,稍微修改一下,结构可以描述成这样的:<div class=”wrap” style=”position:relative”>…<div id=”Box2” style=”position:absolute”>Box2</div>…</div>

这样relative-absolute联袂出现了,而且还是父子关系(当然不仅限于父子关系,也可以推广到爷孙关系等…)

效果图如下:

此时,Box2(position:absolute)的偏移属性(right:200px;bottom:100px)是相对于父元素(确切的说是:有static以外定位的祖辈元素)来说的。absolute有祖辈了(一般情况下祖辈是relative),有家长的孩子不再是野孩子了,出去玩玩可以,但是得在家长的附近玩,得到家长的宠爱,同时也受到家长的约束。这时,读者想到fixed了吗?这个可怜的孩子,一出生就走入社会,没有家长的宠爱,当然也没有家长去约束他。这也是absolute和fixed的区别,到最后,我们再好好总结一下relative、absolute、fixed的异同点。

absolute的家长有个正规的名字叫“包含框”,通俗的说就是“定位基准”,偏移属性的值都是相对于包含框(定位基准)来说的。

relative-absolute应用的第一个例子——提示框

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>relative-absolute_tip</title>
 6         <style>
 7             .tip{
 8                 position:relative;
 9                 color:red;
10                 cursor:pointer;
11             }
12             .tip:hover span{
13                 position:absolute;
14                 top:30px;
15                 left:-30px;
16                 
17                 display:block;
18                 width:100px;
19                 background:#424242;
20                 color:#fff;
21                 padding:10px;
22             }
23             .tip span{
24                 display:none;
25             }
26         </style>
27     </head>
28     <body>
29     <p>
30         Web前端知识包括:
31         <span class="tip">
32             CSS
33             <span>CSS 指层叠样式表 (Cascading Style Sheets),它是网页外观表现样式</span>
34         </span>35         <span class="tip">
36             Html
37             <span>超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言</span>
38         </span class="tip">39         <span class="tip">
40             JavaScript
41             <span>JavaScript 是互联网上最流行的脚本语言,这门语言可用于 HTML 和 web,更可广泛用于服务器、PC、笔记本电脑、平板电脑和智能手机等设备</span>
42         </span>
43     </p>
44     </body>
45 </html>

relative-absolute_tip Code

效果图如下:

提示框(position:absolute)是相对于父元素(position:relative)来定位的。

 

relative-absolute应用的第二个例子——悬浮出现二级子菜单

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>relative-absolute_zicaidan</title>
 6         <style>
 7             *{
 8                 margin:0;
 9                 padding:0;
10             }
11             .nav{
12                 background:blue;
13                 color:#fff;
14             }
15             .nav span{
16                 display:inline-block;
17                 padding:30px 50px;
18             }
19             li{
20                 list-style:none;
21             }
22             
23             .zicaidan{
24                 position:relative;
25                 cursor:pointer;
26                 
27             }
28             .zicaidan ul{
29                 display:none;
30                 background:#000;
31             }
32             .zicaidan ul li{
33                 padding:30px;
34             }
35             .zicaidan ul li:hover{
36                 background:#aaa;
37                 color:red;
38             }
39             .zicaidan:hover ul{
40                 position:absolute;
41                 top:80px;
42                 left:10px;
43                 display:block;
44                 
45             }
46         </style>
47     </head>
48     <body>
49         <div class="nav">
50             <span>首页</span>
51             <span class="zicaidan">
52                 新闻
53                 <ul>
54                     <li>新闻1</li>
55                     <li>新闻2</li>
56                     <li>新闻3</li>
57                     <li>新闻4</li>
58                 </ul>
59             </span>
60             <span class="zicaidan">
61                 联系我们
62                 <ul>
63                     <li>联系方式1</li>
64                     <li>联系方式2</li>
65                     <li>联系方式3</li>
66                 </ul>
67             </span>
68         </div>
69     </body>
70 </html>

relative-absolute_zicaidan Code

效果图如下:

悬浮出现二级子菜单和提示框道理上基本差不多,不再赘述。

 

 

好了,到了该总结总结的时候了,我先陈述一下每个人的特点,穿插着他们的异同点,最后用一个表格简单整理一下。

fixed,一出生就被家长抛弃了,他是野孩子,无拘无束,他脱离文档流,悬浮在一般元素之上,他在与不在对别人来说都一样,没啥影响。他的偏移属性值是相对于浏览器窗口来说的,也就是他相对于浏览器窗口固定,他不随滚动条一起滚动。典型应用,悬浮广告、遮罩。

relative是自恋狂,偏移属性值是相对于他在正常情况下来说的,他自己和自己比较。偏移后堆叠在一般元素之上,他原来的位置还在那儿占着,占着办公桌还不上班,吃空饷。典型应用,阴影效果(relative单独使用)。

absolute如果没有家长(没有家长:所有祖辈元素均没有static以外的定位),他就和fixed很像,脱离文档流,悬浮于一般元素之上,他在与不在对别人来说都一样,没啥影响。他的偏移属性值(top、right、bottom、left简称:TRBL 上右下左)是相对于浏览器窗口来说的,也就是他相对于浏览器窗口固定,他随着滚动条一起滚动(这是他和fixed的区别)。

absolute更多的时候是有家长的,家长一般就是relative,relative-absolute组合使用,这是的absolute就不再相对浏览器窗口定位了,而是相对于父元素(relative)定位,有了家长的孩子不再满世界撒野,而是在家长的管束下,但他仍然脱离文档流,不和一般的元素争抢位置,一般元素就当他不存在一样,他堆叠在一般元素之上。典型应用,提示框和悬浮出现二级子菜单。

position的主要可选值

是否脱离文档流

是否随着滚动条滚动

定位基准

应用

fixed

浏览器窗口

悬浮广告、遮罩

relative(单独)

自己在正常情况下的位置

超链接错位、阴影效果

absolute(单独)

浏览器窗口

应用不多

relative-absolute(组合)下的absolute

定位的直系祖辈元素(此时的定位基准也叫“包含框”)

提示框、悬浮出现二级子菜单

注:

relative-absolute(组合)在通常情况下,relative作为“定位父元素”。

先解释一下“父元素”确切的说应该是直系祖辈元素,各种资料说法不一,但表达的意思都是一样的,本文有时叫“父元素”,有时也叫“祖辈元素”,有时还叫“直系祖辈元素”,读者不用纠结叫法,知道它的涵义就可以了。

再解释一下“定位”,是指该元素的定位属性值是除static以外的值,更多的时候是position:relative,所以本文直接写成“relative-absolute”。

 

鉴于个别内容不便于文字表达,本人计划于近期在视频学习网站发布关于position的相关视频,内容较之本文稍有拓展,届时,我会将视频链接发布于此。读者如有兴趣,敬请关注。