【前端Talkking】CSS系列——CSS深刻理解之absolute定位

1. 寫在前面

本篇將要介紹的絕對定位absolute屬性和此前介紹的CSS系列——CSS深刻理解之float浮動有着幾分的類似性,能夠認爲二者是兄弟關係,都具備「包裹性」、「高度塌陷」、「塊狀化」的特性,它們在不少場合均可以互相替代。不少人可能有這樣的疑問:一個屬性名是「position」,一個屬性名是「float」,從名字看起來,它們八竿子都打不着啊,怎麼仍是兄弟關係呢?要說position: absoluteposition: relative是兄弟關係還能理解,要說和float是兄弟關係我就納悶!!!呵呵~~~~,別急,這就是寫做本文的目的。javascript

2. absolute的特性

在介紹absolute以前,有如下公共CSS代碼:css

/* CSS代碼 */
.father{
    border: 2px solid deeppink;
    width: 200px;
}
.son {
    position: absolute;
    font-size: 0;
    border: 2px solid blue;
    padding: 5px;
}
.father img {
    width: 128px;
}

2.1 包裹性

而後有如下html代碼:html

<div class="father">
    <!--son1與son的惟一區別是son1的position設置爲static-->
    <div class="son1">
        <img src="../../lib/img/mm1.png">
    </div>
</div>
<br/>
<br/>

<div class="father">
    <div class="son">
        <img src="../../lib/img/mm1.png">
    </div>
</div>

最終顯示的效果以下圖所示:前端

在本例中,son1與son的惟一區別是son1的position設置爲static.father元素的寬度設置爲200pximg元素是一個128px寬度的圖片,則此時絕對定位元素寬度表現爲"包裹性",其寬度也就是裏面圖片的寬度128px。java

因爲絕對定位元素寬度表現爲"包裹性",所以,下面的CSS寫法就是多餘的:web

.wrap{
    display: inline-block;// 沒有必要
    position: absolute;
}

2.2 高度塌陷

基於上圖,父元素div的高度並無被子元素撐開(粉色區域),這種效果能夠稱爲"高度塌陷"。致使高度塌陷的緣由是由於浮動元素脫離了正常的文檔流,則div.father認爲其沒有子元素,因此產生了高度塌陷。segmentfault

若是在.father元素增長子元素,以下:瀏覽器

<!--HTML代碼-->
<div class="father">
    <div class="son">
        <img src="../../lib/img/mm1.png">
    </div>
    美女1,美女2,美女3,美女4,美女5
</div>

則在瀏覽器中的效果以下:微信

從圖中明顯看出文字被圖片遮蓋了,這一點和float不一樣。由於,float元素自己仍處於文檔流中,文字會環繞着float元素,不會被遮蔽,而設置了absolute的圖片元素出現了層級關係,已經脫離了正常的文檔流了,從父元素的視點看,圖片已經徹底消失不見了,所以從最左邊開始顯示文字,而absolute的層級高,因此圖片遮蓋了文字。app

2.3 塊狀化

塊狀化的意思是,一旦元素position的屬性爲absolute或者fixed,則其display計算值就是block或者table。能夠複製如下代碼到瀏覽器控制檯中:

var span = document.createElement('span')
document.body.appendChild(span)
console.log('1.' + window.getComputedStyle(span).display)
// 設置元素絕對定位
span.style.position = 'absolute'
console.log('2.' + window.getComputedStyle(span).display)
document.getElementById("aa").style.display = "block"

則在瀏覽器控制檯中的結果以下:

1.inline
2.block

2.4 小結

對於上面對absolute的介紹,對比float屬性,是否是應該理解他們是兄弟關係呢?若是你非得不這樣認爲能夠,只要你明白absolute的特性便可。絕大多數前端開發人員應該都懂,可是若是本文只是介紹上面的知識點,就太對不起你們的期待了!下面將要介紹absolute的流體與相對特性纔是本文的重點。

3. absolute流體與相對特性

3.1 absolute的相對特性

在介紹absolute的相對特性以前,先拋出如下問題: 若是一個元素的定位屬性設置成了:position: absolute後,沒有設置left/top/right/bottom,而且其祖先元素所有都是非定位元素,請問它將在哪裏顯示?

包括我本身,在深刻了解absolute的特性以前,認爲該元素是在瀏覽器窗口的左上方顯示,其實這是對absolute絕對定位屬性錯誤的認識。所以,不少人在使用absolute定位屬性的時候,一定先要設置父元素position: relative,同時設置絕對定位元素的left/top/right/bottom,甚至還要設置絕對定位元素層級z-index實際上,該元素仍是在當前的位置。咱們拿下面的這個例子驗證:

<!--HTML代碼-->
<div class="father">
    <div class="pa box"></div>
</div>
/* CSS代碼 */
.father{
    border: 2px solid deeppink;
    width: 100px;
    height: 100px;
}
.pa{
    position: absolute;
}
.box{
    background-color: #cdcdcd;
    width: 50px;
    height: 50px;
}

以下圖所示,.box元素仍是在當前的位置顯示,而不是在瀏覽器窗口的左上方顯示:

在京東商城首頁,有這樣的一個效果:

image-20180502200432543

而後咱們打開調試窗口,查看html和css代碼以下:

image-20180502200712645

這裏css代碼中的top:0;left:0徹底是多餘的代碼,能夠省略不寫。由於,不設置left/top/right/bottom的絕對定位元素仍是在當前的位置,只是脫離了正常的文檔流了。

實際上,absolute是一個相對比較獨立的CSS屬性,它的樣式和行爲表現不依賴其餘的CSS屬性就能夠完成。所以,若是元素設置了定位屬性爲absolute絕對定位,而且沒有設置left/top/right/bottom,那麼能夠將這種定位屬性稱爲「無依賴絕對定位」,其本質就是"相對定位",特色僅僅是脫離文檔流,不佔據任何CSS流的尺寸空間了。

無依賴絕對定位在實際開發中很是有用,下面舉幾個比較經常使用的例子。

1)各種圖標定位

咱們以慕課網首頁上的課程列表舉例:

WX20180502-205632@2x

<div>
    <div class="box"></div>
    <i>Hot</i>
</div>

核心CSS代碼以下所示:

WX20180502-205758@2x

徹底不須要藉助top/right/bottom/leftposition: relative的幫助就能夠搞定小圖標的佈局啦。相比使用position:relativeright/top的佈局方式,這種佈局方式的優勢是:

  • 維護成本低。若是後面想刪除這個圖片,只須要將圖標對應的html和css代碼刪除掉就能夠了,不會影響其餘的元素
  • 健壯性高。若是圖片變大或者文字變長,咱們不須要修改小圖標的css代碼,仍然定位效果良好。

再舉一個在實際開發中用的比較多的一個例子,以下圖所示,在一段文字的前面有一個圖標:

這種佈局方式一樣能夠藉助無依賴定位的實現,而且代碼簡單高效,代碼以下所示:

<div class="email-wrapper">
    <i class="icon-email"></i>
    <span class="icon-msg">請輸入您的郵箱:</span>
</div>
.email-wrapper{
    display: inline-block;
    height: 20px;
    padding-left: 20px;
    /*font-size: 0;*/
}
.icon-email{
    position: absolute;
    margin-left: -20px;
    width: 20px;
    height: 20px;
    background: url("../../lib/img/email.png") center center no-repeat;
    background-size: contain;
}
.icon-msg{
    display: inline-block;
    line-height: 20px;
    vertical-align: top;
}

2)校驗提示錯誤

在實際開發中,咱們有不少表單校驗,當校驗不經過的時候,會有一些錯誤提示給用戶,以下圖所示:

一般,錯誤提示能夠放到input框的下面,可是當出現錯誤提示的時候,下面的內容會總體下移,當錯誤提示消失的時候,下面的內容又會總體上移,用戶體驗很差。還有一種作法是放到input框的右側顯示,可是在默認狀態下部容器設置了水平居中, 寬度不大,若是再出現錯誤提示信息,就會出現容器的寬度不夠的問題。此時,咱們一樣能夠藉助:"無依賴定位",直接給錯誤提示信息增長一個CSS類,以下所示:

.msg-error{
    position: absolute;
    margin-left: 10px;
}

不管將input框的寬度變大或者變小,提示信息都會跟着input框。相比使用position:relativeright/top的佈局方式,這種方法代碼量更少、容錯性更高、維護成本更低。

關於無依賴絕對定位的應用還有不少,這裏就不一一介紹了,有興趣的同窗能夠參看張鑫旭老師的《CSS世界》。

3.2 absolute的流體特性

只有absolute遇到left/top/right/bottom屬性的時候,absolute元素才真正變成絕對定位元素。若是用戶給absolute至少指定了left/right中的一個,則水平方向的相對特性丟失,垂直方向上繼續保持相對特性;若是用戶給absolute至少指定了top/bottom中的一個,則保持水平方向上的相對特性,垂直方向上的相對特性丟失。例如:

<div class='box'></div>
.box{
    position: absolute;
    right: 0;
}

此時,元素水平方向相對特性丟失,具備了絕對定位特性,而垂直方向的定位依然保持了相對特性。

以上面的這個例子舉例,當只有left或者right屬性的時候,因爲包裹性,此時div的寬度是0。可是,若是同時設置left:0;right:0的時候,寬度表現爲"格式化寬度",寬度自適應於.box包含快的content-box,換句話說,若是包含快的conent-box寬度發生變化,則.box的寬度也會跟着一塊兒變。舉個例子:

<div class='box'></div>
.box{
    position: absolute;
    right: 0;
    left: 0;
    top: 0;
    bottom: 0;
}

若是.box的包含塊是根元素,則上面的代碼可讓.box元素正好徹底覆蓋瀏覽器的可視窗口,同時,若是改變瀏覽器窗口的大小,.box的大小會隨着瀏覽器的大小自動變化。所以,對於設置了對立定位屬性的絕對定位屬性,不管設置padding仍是margin,其佔據的空間一直不變,變化的就是content-box,這就是典型的流體表現特性。流體特性的具體用法在後面會介紹到。

4. absolute與其餘屬性

CSS中的不少屬性須要和其餘的屬性一塊兒使用的時候會發生意向不到的效果。下面將介紹absolute與其餘CSS一塊兒使用產生的效果。

4.1 absolute與text-align

利用text-align能夠控制絕對定位元素的位置,實現主窗口右側的"返回頂部"以及"反饋"等佈局的效果。效果圖以下:

WX20180502-210045@2x

核心代碼以下:

<!--HTML代碼-->
<div class="alignright">
    <span class="follow">
        <img src="../../lib/img/message.png">
        <img src="../../lib/img/top.png">
    </span>
</div>
/* CSS代碼 */
.alignright{
    overflow: hidden;
    text-align: right;
}
.alignright:before{
    content: "\2002"
}
.follow{
    position: fixed;
    bottom: 100px;
    z-index: 1;
}
.follow img{
    display: block;
    margin: 10px;
    width: 20px;
    height: 20px;
    background-size: contain;
}

在本例中,利用:before僞元素,在其前面插入一個空格(2002),而後設置text-aligin: right,則空格對齊主結構的右側邊緣,後面的固定定位元素(同絕對定位元素)因爲"無依賴定位"特性,左邊緣正好就是主結構的右邊緣,天然就跑到主結構的外面顯示了。這種佈局在實際開發中用處很是大,好比說下圖中某寶的樓層導航效果均可以使用這種方式實現。

4.2 absolute與clip

在實際開發過程當中,不少時候咱們爲了更好的SEO和無障礙識別,都會將頁面中的一些元素隱藏,例如隱藏下面代碼中的本網站名字這幾個字:

/* CSS代碼 */
<a href="#" class="logo">
    <h1>本網站名字</h1>
</a>

爲了隱藏上面的文字,有如下幾種方案能夠供咱們選擇:

  • 使用display:none或者visibility:hidden。缺點:屏幕閱讀設備會忽略這些文字;
  • 使用text-align縮進。缺點:若是縮進過大到屏幕以外,屏幕閱讀設備也是不會讀取的;
  • 使用color: transparent。原生IE8瀏覽器器並不支持,而且仍是可以選中文本。

藉助absolute和clip(關於clip用法不熟悉的同窗能夠本身百度下,很簡單,注:clip只對絕對定位和固定定位的元素生效)這兩個屬性,可以同時知足視覺上隱藏和屏幕閱讀設備可以讀取的要求,核心代碼以下:

/* CSS代碼 */
h1{
    position: absolute;
    clip: rect(0 0 0 0);
}

4.3 absolute之margin:auto居中

在實際工做開發中,可能咱們用的最多的是下面的方式來實現元素的水平垂直居中效果,核心代碼以下:

/* CSS代碼 */
.box{
    width: 20px;
    height: 20px;
    position: absolute;
    left: 50%;
    right: 50%;
    margin-left: -10px;
    margin-right: -10px;
}

此方法有一個不足之處就是須要提早知道元素的尺寸,不然沒法控制margin負值的大小。

若是不知道元素的尺寸,可使用transform: translate(-50%, -50%)代替margin負值,然而這種方法存在必定的兼容性問題,IE9(-ms-), IE10+以及其餘現代瀏覽器才支持,在必定的場景下會致使微信閃退的問題。

在介紹下另一種方法前,咱們首先熟悉下margin: auto的填充規則:

  • 若是一側定值,一側auto,則auto爲剩餘空間大小;
  • 若是兩側都是auto,則平分剩餘空間。

所以,利用絕對定位absolute元素的流體特性和margin: auto的自動分配特性可以實現水平垂直居中的效果,核心代碼以下:

/* CSS代碼 */
.box{
    width: 20px;
    height: 20px;
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
}

顯示效果以下:

WX20180502-212501@2x

這種方法兼用性好,而且須要提早知道元素的尺寸,減小了依賴,後期維護改動的地方少,何樂而不爲呢?

5. 結語

關於absolute的介紹就到這裏了,平時咱們應該多思考,多總結,纔會有新的體會。計劃下一篇文章介紹relative定位,最新文章都會第一時間更新在個人公衆號<前端Talkking>裏面,歡迎關注。

以上就是本文的所有內容,感謝閱讀,若是有表述不正確的地方,歡迎留言指正!

6.參考

  • 張鑫旭 《CSS世界》

碰見了,不妨關注下個人微信公衆號「前端Talkking」

圖片描述

相關文章
相關標籤/搜索