輕輕鬆鬆學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的相關影片,內容較之本文稍有拓展,屆時,我會將影片鏈接發佈於此。讀者如有興趣,敬請關注。