CSS進階(13)—— position:absolute如此高深,我當真不懂(中)

上一篇文章中,咱們探討了絕對定位的包含塊以及「無依賴絕對定位」的特性,本章咱們來聊聊absolute的流體特性以及那些和absolute關係甚好的CSS屬性。css

1.absolute的流體特性

在前面一文中,咱們測試了不少「無依賴絕對定位」的特殊表現,事實上在平時開發的時候咱們使用absolute都用的都是他的「絕對定位」特性,這也是absolute被設計出來的本職工做。爲了作好本身的本職工做,absolute還須要left,top,right,bottom四個屬性的配合,一般,咱們會根據閱讀順序(從左到右,從上到下)的須要,設置absolute元素的left和top值,來達到元素定位的效果,那麼,若是僅設置一個方向上的值,會發生什麼呢?這裏咱們不深刻探討這種情形,你只須要知道元素在被設置的方向上保持「絕對定位」的特性,而在另外一個(水平或垂直)方向上保持相對定位特性便可。 html

本節要深刻探討的是absolute的流體特性。說到流體特性,咱們應該能很快想到div之類的普通塊級元素,實際上,絕對定位元素也具備相似的流體特性,並且在某些狀況下比普通塊級元素更強大!固然,absolute要實現自身的流體特性是有條件的,給元素直接設置style="position:absolute;margin:auto;"外邊距的auto屬性是不會有任何計算值的。那麼,absolute元素才能擁有流體特性呢?這個條件就是「對立方向同時發生定位」的時候。 瀏覽器

left,top,right,bottom是具備定位元素的專用CSS(注意不僅是絕對定位),其中left和right屬於水平對立定位方向,而top和bottom屬於垂直對立定位方向。當一個絕對定位元素,其對立定位方向屬性同時具備值得時候,那麼該元素在該對立方向上具備流體特性,固然若是你樂意的話,絕對定位元素能夠同時在水平和垂直方向上都具備流體特性。流體特性最顯著的特色就是自動鋪滿流體方向上的空間,就像物理世界的水會鋪滿燒杯同樣。下面咱們來測試一下該特性的具體表現。 markdown

<!-- 絕對定位的流體特性 -->
<div style="position:relative;height: 100px;background: yellow;margin: 20px;">
    <div style="position: absolute;background: #f34413;left: 0;right: 0">我是水平流</div>
</div>
<div style="position:relative;height: 100px;background: yellow;margin: 20px;">
    <div style="position: absolute;background: #f34413;top: 0;bottom: 0">我是垂直流</div>
</div>
<div style="position:relative;height: 100px;background: yellow;margin: 20px;">
    <div style="position: absolute;background: #f34413;left: 10px;right:10px;top: 10px;bottom: 10px">我是水平垂直流</div>
</div>
複製代碼

因爲markdown編輯器支持標籤語言,所以咱們能夠直接預覽最終效果以下(小提示:你能夠經過瀏覽器直接檢查下面的元素看到CSS樣式) 編輯器

我是水平流
我是垂直流
我是水平垂直流

若是隻有left屬性沒有right屬性,absolute則表現爲「包裹性」。在垂直方向上的表現同理。 佈局

<div style="position:relative;height: 100px;background: yellow;margin: 20px;">
    <div style="position: absolute;background: #f34413;left: 0;">包裹性</div>
</div>
複製代碼

因爲markdown編輯器支持標籤語言,所以咱們能夠直接預覽最終效果以下(小提示:你能夠經過瀏覽器直接檢查下面的元素看到CSS樣式) post

包裹性

下面咱們要實現一個元素徹底覆蓋瀏覽器可視窗口的效果,有不少種方法能夠實現這個效果,下面咱們只關注用absolute如何實現這種效果。 測試

<style> .box1{ position: absolute; top: 0; right: 0; bottom: 0; left: 0; } .box2{ position: absolute; left:0; top:0; width:100%; height:100%; } </style>
複製代碼

上面這兩種方法均可以實現元素鋪滿整個屏幕的效果(在包含塊是HTML的狀況下),可是他們的實現原理卻徹底不一樣,後者也就是設定了寬高的那個元素,實際上已經徹底失去了流動性,並且當前元素的寬高已經被準確計算了,此時你還想要添加內邊距或外邊距便會形成「寬高溢出」的表現,而用第一種方法實現則徹底不會出現這種狀況。 flex

2.利用absolute實現水平垂直居中

咱們能夠利用absolute的流體特性實現一種經常使用的佈局——水平垂直居中。咱們都知道,塊級元素自己具備流體特性,在margin一章中咱們也詳細介紹了margin:auto的自適應計算屬性。當元素具備流體特性,如div在水平方向上具備流體特性,此時設置margin:auto,該元素的外邊距就會在水平方向上自動等分紅兩份,使得元素自己在父容器中顯示爲水平居中效果。所以,margin的auto屬性用在具備垂直水平都具備流體特性的absolute元素上時,就能讓元素實現自適應居中!這種居中方式是目前爲止最好的水平垂直居中解決方案,來看下面的演示。 網站

<!-- absolute流體特性 -->
<div class="father">
    <div class="son"></div>
</div>
<style type="text/css"> .father{ width: 400px; height: 400px; background: yellow; position: relative; } .son{ width: 200px; height: 100px; background: green; position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; } </style>
複製代碼

因爲markdown編輯器支持標籤語言,所以咱們能夠直接預覽最終效果以下(小提示:你能夠經過瀏覽器直接檢查下面的元素看到CSS樣式)

事實上absolute還有一種作法也能夠實現元素的水平垂直居中,這種作法須要藉助transform配合,咱們先來看一下演示。

<!-- 利用transfor實現 -->
<div class="father">
    <div class="son"></div>
</div>
<style type="text/css"> .father{ width: 400px; height: 400px; background: yellow; position: relative; } .son{ width: 200px; height: 100px; background: green; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); } </style>
複製代碼

因爲最終展現的結果是同樣的,這裏就不放圖片了,看起來下面的這種作法也很是優秀,但其實仍是有一些問題的。以前我在探討元素的垂直居中的時候就發現了這種方法的一些「缺點」。首先,他沒有利用元素自適應佈局的特色,也就是元素徹底脫離了文檔流,這可能對CSS強迫症愛好者來講有些不爽。固然這只是一個小缺點,此類佈局最大的問題就是要考慮absolute的包裹性!我剛纔已經提到了absolute元素若是隻有left屬性沒有right屬性,absolute則表現爲「包裹性」。在垂直方向上的表現同理。所以在本例中,該元素表現出了包裹性,包裹性包括包裹和自適應兩大特性,這個我也說了好多遍了,因爲設置了left:50%,所以son元素的自適應最大寬度不得超過50%,也就是明明還有可適應的空間,他卻自動換行了。咱們能夠在son中填充一些文字看一下效果。

要解決這個問題很簡單,只要給absolute元素加上white-space:norwap強制文字不換行便可,但這樣也會有問題,就是文字內容會超出父容器,所以我的建議棄用這種垂直居中的佈局方式。

3.absolute與text-align

衆所周知,text-align從字面上理解是指文本的對齊方式,所以控制的是內聯元素的表現,而absolute具備塊狀化元素的特性,所以這兩個屬性能夠說是八杆子打不着的關係。然而在下面這段代碼中,text-align屬性彷佛對absolute元素產生了影響。

<!-- absolute與text-align -->
 <div style="text-align: center;">
    <span style="position: absolute;">hello</span>
 </div>
複製代碼

上圖中,absolute元素彷佛受到text-align的影響處於容器中偏右的位置,那麼text-align真的能夠影響塊元素嗎?答案是否認的。在本例中,text-align影響的依舊是內聯元素,只是這個內聯元素是你看不到「幽靈空白節點」。因爲span標籤原來是個內聯元素,所以在該元素前面生成了一個幽靈空白節點,這個節點默認是個內聯元素,受到了text-align:center的感化,跑到了div的中間,雖然不佔位置,但佔據了一個看不見的空間,而這個看不見的空間對後面的「無依賴絕對定位」元素產生了影響,這個absolute元素就乖乖的跟在後邊了。所以本例中,absolute元素並非直接和text-align發生關係!

4.absolute和overflow

overflow對absolute元素的裁切規則的官方描述是:絕對定位元素不老是被父級overflow屬性裁剪,尤爲當overflow在絕對定位元素及其包含塊之間的時候。

翻譯一下上面這句話:若是overflow不是定位元素,同時絕對定位元素和overflow容器之間也沒有定位元素,則overflow沒法對absolute元素進行裁切。事實上你根本記不住這句話,因此你得經常使用,慢慢記到腦子裏。下面我會用一些實例來強化一下你的印象,從0%到1%吧,剩下99%靠你本身了,我寫博客也是爲了加深印象,這個系列的內容不少都只要留個潛意識便可,之後遇到問題知道去哪裏查閱就ok了。

下面四個例子能夠幫助你快速記憶absolute何時會被overflow裁切。

<!-- absolute與overflow -->
<!-- html做爲定位元素 -->
<div class="box">
    <img src="./小和尚.jpg" /> 	
</div>
<!-- overflow父元素是定位元素,跟html作定位元素同理 -->
<div style="position: relative;">
    <div class="box">
        <img src="./小和尚.jpg" /> 	
    </div>
</div>
<!-- overflow元素自己是定位元素 -->
<div class="box" style="position: relative;">
    <img src="./小和尚.jpg" /> 	
</div>
<!-- overflow元素與絕對定位元素之間有定位元素 -->
<div class="box" style="position: relative;">
    <div style="position: relative;">
        <img src="./小和尚.jpg" />
    </div> 	
</div>
 <style> .box{ width: 80px; height: 120px; overflow: hidden; background: yellow; margin: 10px; } img{ position: absolute; width: 100px; height: 100px; } </style>
複製代碼

除了hidden"裁切"屬性,overflow還有auto和scroll屬性,這兩個屬性在遇到絕對定位的時候選擇直接無視,即便絕對定位元素寬高大於overflow元素,也不會出現滾動條。

<!-- absolute與滾動條 -->
 <div class="box">
    <img style="position: absolute;" src="./小和尚.jpg" />
 </div>
 <style> .box{ width: 300px; height: 200px; overflow: auto; background: yellow; } </style>
複製代碼

雖然絕對定位元素不能影響元素出現滾動條,但普通元素能夠,在box元素中填充足夠內容後,咱們來看下滾動條和absolute元素的真實關係。

<!-- absolute與滾動條 -->
 <div class="box">
     <img style="position: absolute;opacity: 0.2" src="./小和尚.jpg" />
     <p>文字內容文字內容文字內容文字內容文字內容文字內容文字內容</p>
     <p>文字內容文字內容文字內容文字內容文字內容文字內容文字內容</p>
     <p>文字內容文字內容文字內容文字內容文字內容文字內容文字內容</p>
     <p>文字內容文字內容文字內容文字內容文字內容文字內容文字內容</p>
     <p>文字內容文字內容文字內容文字內容文字內容文字內容文字內容</p>
</div>
<style> .box{ width: 300px; height: 200px; overflow: auto; background: yellow; } </style>
複製代碼

能夠看到,滾動條滾動的過程當中,absolute元素紋絲不動,利用這個特色咱們能夠用來實現元素固定到頂部的效果,且該元素不會隨着滾動條滾動。本人測試了一下該原理實現的效果並非很好,且鑑於小白維護代碼的時候會莫名其妙給標籤加個relative的屬性,不便於不明白此「奇怪特性」的人維護CSS,所以只要知道有這個特性便可,不須要太過深刻。

5.absolute與clip:初次見面,請多指教

CSS世界中有些屬性必須和其餘屬性一塊兒使用纔有效,如以前講過的「文字超出部分省略號顯示」效果。clip裁切屬性想要起做用,元素必須是絕對定位(absolute)或固定定位(fixed)。clip語法以下:

clip:rect(top right bottom left) 或 rect(top,right,bottom,left)

該屬性有兩個注意點,搭配起來看會很是蛋疼:1.top和bottom的值都相對於頁面垂直流的top,也就是說,是在元素的top裁切到bottom,left和right同理,是相對於頁面水平流的left。2.該屬性不支持百分比。

做者很是喜歡稱overflow:hidden爲"裁切"屬性,我我的更傾向於「隱藏」,由於hidden並非真的裁切了元素,在overflow一章咱們詳細探討過若是顯示overflow:hidden部分的內容。本章要探討的clip屬性更具有「裁切」的特性,因爲其必須搭配absolute/fixed才能使用,所以不少人甚至都沒有用過這個屬性,事實上這個屬性咱們不只須要瞭解,在某些方面他還很是有用。

1)fixed固定定位裁切

對於普通元素或者絕對定位元素,想要對其裁剪,咱們可使用relative搭配overflow:hidden的方式,然而fixed定位的包含塊是根元素,這時候咱們想要用overflow:hidden的方式必需要給根元素申明,這樣用起來就比較蛋疼了,由於一般狀況下咱們但願根元素的寬高能自適應。此時就須要用到clip屬性了。

<!-- clip裁切fixed元素 -->
<div class="box">
    <img src="./小和尚.jpg">
</div>
<style> .box{ position: fixed; clip: rect(30px 200px 200px 20px) } </style>
複製代碼

因爲clip裁切的計算是相對於頁面的「左上角」的,且不支持百分比計算,所以這個裁切屬性用起來不是很是方便,只能在某些特定寬高肯定的元素裏有一些做用,瞭解一下便可。

2)最佳可訪問隱藏屬性

所謂「可訪問性隱藏」指的是雖然內容肉眼看不見,可是其輔助功能卻可以識別,舉個例子,咱們須要用到一個logo圖標,爲了更好的SEO以及無障礙識別,咱們通常會使用h1標籤寫上網站的名稱,代碼以下

<a href="/" class="logo">
    <h1>CSS世界</h1>
</a>
複製代碼

此時咱們須要隱藏CSS世界的文字,一般有如下幾種作法

  • 用display:none或者visibility:hidden隱藏,屏幕閱讀設備會直接忽略文字。
  • text-indene:-9999,因爲文字縮進過大,屏幕閱讀設備也不會讀取文字。
  • color:transparent,文本框依舊在html中,可被用戶選擇到,須要取消瀏覽器的默認事件,操做麻煩。
  • clip裁剪隱藏,既知足視覺上的隱藏,屏幕閱讀設備也支持的較好。

鑑於clip裁切是「最佳可訪問隱藏」,我推薦在common.css中放入以下class類表示隱藏。

.clip{
   position:absolute;
   clip:rect(0,0,0,0)
}
複製代碼

該屬性隨取隨用,且無依賴絕對定位的兼容性很是好,不會影響正常佈局。利用clip裁切不會影響元素自己的特性,咱們能夠利用他完成表單元素的修改,並保留表單元素的默認操做,如focus,submit等操做,具體這裏不過多展開。

本章主要介紹了絕對定位的流體特性以及和絕對定位相關的CSS屬性,然而跟絕對定位最親密的relative屬性尚未介紹,鑑於relative和fixed的特殊性,這兩個絕對定位好基友咱們放到下一章介紹,感興趣的點個關注吧~

不忘初心,方得始終

喜歡博主的童鞋能夠掃描二維碼加博主好友~ 也能夠掃中間二維碼入駐博主的粉絲羣(708637831)~固然你也能夠掃描二維碼打賞並直接包養帥氣的博主一枚。

相關文章
相關標籤/搜索