你可能不知道的絕對定位
分享一個關於絕對定位的實戰開發經驗。
在普遍的認知下,絕對定位好像都是伴隨着偏移屬性(left
/right
/top
/bottom
)一起出現的,相信大家都寫過這樣的CSS
,如下
el{
position: absolute;
left: 0;
top: 0;
}
其實,有些情況下是可以不需要偏移量的,不僅實現上更加簡潔,適應性也更強,甚至還能實現加上偏移量反而實現不了的佈局,一起看看吧,相信會有不一樣的體會
一、絕對定位的特性
談到絕對定位佈局,大家可能會馬上就會想到這些特性:
-
不佔用空間
-
脫離文檔流
第一條沒什麼問題,確實不會佔用空間。現在來看第二條,**真的完全脫離文檔流了嗎?**假設有這樣一個佈局
<p>
歡迎關注前端偵探
</p>
然後生成一個僞元素,設置成絕對定位
p::after{
content: 'A';
position: absolute;
color: red;
}
在不設置任何偏移的情況下,可以看到,絕對定位元素始終跟隨在文本後面,也就是說,現在仍然處於文檔流中,如下
如果僅設置一個方向,比如left
p{
position: relative;
}
p::after{
content: 'A';
position: absolute;
color: red;
left: 0;
}
那麼,在水平方向上,絕對定位元素始終位於最左邊,而垂直方向上,仍然保持着跟隨文檔的特性,只是單方向的
如果兩個方向上都設置了,這也是我們最常見的寫法
p::after{
content: 'A';
position: absolute;
color: red;
left: 0;
top:0
}
那麼,這個元素位置就完全固定了,真正的脫離了文檔流
綜上所述,絕對定位元素,只有在設置了偏移時纔會脫離文檔流,如果只設置了一個方向上的,那麼在另外一個方向上仍然保留着文檔流特性,或者這麼說,絕對定位元素仍然保持在原來的位置,並且不佔空間,除非設置了偏移纔會真正固定定位
瞭解了這些,下面來看幾個實際案例
二、左上角的標籤
大家可能經常會碰到這樣的 “角標” 效果
現在簡單實現一下,假設HTML
是這樣的
<div class="item">
<img class="cover" src="xxx">
</div>
角標可以通過僞元素生成
.item::before{
content: '推薦';
position: absolute;
font-size: 12px;
line-height: 16px;
padding: 2px 4px;
background: #FDB324;
color: #fff;
}
注意,這裏用到的是::before
,而不是::after
,原因在於::before
在元素內容之前,本身就位於左上角,如果是::after
,默認位置就在img
的下方,在設置position: absolute
的情況下,由於不佔空間,所以也不影響其他元素,效果如下
因此,像這種場景下,設置偏移量和父級定位可以說都是多餘的
/*以下是多餘的*/
.item{
position: relative;
}
.item::before{
left: 0;
top: 0;
}
如果你的項目中也有這樣的佈局,趕緊優化一下吧,當然僅限於 “左上角” 的標籤,如果是其他方位的,按傳統實現即可
完整 demo 可以訪問以下任意鏈接:
-
CSS absolute tag (juejin.cn)[1]
-
CSS absolute tag (codepen.io)[2]
-
CSS absolute tag (runjs.work)[3]
三、文本重疊
有時候在做文本特效時,不可避免需要重疊文本,比如文本外描邊效果
大家可能都知道,文本描邊其實是居中描邊的
.text{
-webkit-text-stroke: 6px rgb(51, 51, 51);
}
這樣會帶來一個問題,當描邊慢慢變大時,會覆蓋文字顏色
爲了解決這個問題,我們需要用到兩層文本,在底下放描邊,上面放文本顏色,示意如下
而這裏兩層重疊的文本就需要用到絕對定位了,假設HTML
是這樣的
<p class="text" data-title="前端偵探">前端偵探</p>
這裏加另一個data-title
屬性,用來生成僞元素,關鍵實現如下
.text::before{
content: attr(data-title);
position: absolute;
}
只需要將::before
設置絕對定位即可,注意是::before
,無需任何其他偏移屬性,文本就默認重疊了,而且由於是絕對定位,層級也自動變高
從這裏也可以看出,在絕對定位中,::before
要比::after
要好用的多!
關於文本修飾效果可以參考以前這篇文章:CSS 和 SVG 實現文字漸變、描邊、投影 [4]
完整 demo 可以訪問以下任意鏈接:
-
CSS text stroke (juejin.cn)[5]
-
CSS text stroke (codepen.io)[6]
-
CSS text stroke (runjs.work)[7]
四、多個元素水平垂直堆疊居中
再來看一個這樣的例子,有多個尺寸不定的元素或者圖片,需要堆疊居中,示意如下
最簡單的方式就是,父容器設置flex
居中特性,然後子元素直接設置絕對定位,關鍵實現如下
.wrap{
display: flex;
justify-content: center;
align-items: center;
}
.item{
position: absolute;
}
原因在於,本身元素是居中的,設置絕對定位後,僅僅不佔空間而已,所以後面的元素會堆疊上來而不擠壓,特別適合圖片堆疊展示的效果
完整 demo 可以訪問以下任意鏈接:
-
CSS absolute center (juejin.cn)[8]
-
CSS absolute center (codepen.io)[9]
-
CSS absolute center (runjs.work)[10]
五、自定義水平方向點擊範圍
還記得之前這篇文章嗎?CSS 實現樹狀結構目錄 [11]
裏面有個小細節也用到了絕對定位,非常巧妙,下面簡單回顧一下:
假設HTML
是這樣的
<details>
<details>
<summary>
<span class="tree-item">文件夾1-1</span>
</summary>
<details>
<summary>
<span class="tree-item">文件夾1-1-2</span>
</summary>
</details>
<details>
<summary>
<span class="tree-item">文件夾1-1-3</span>
</summary>
<details>
<summary>
<span class="tree-item">文件夾1-1-3-1</span>
</summary>
</details>
<details>
<summary>
<span class="tree-item">文件夾1-1-3-2</span>
</summary>
</details>
</details>
</details>
</details>
樹形結構有一個明顯的縮進層級關係,這裏是通過內邊距實現的
details{
padding-left: 10px
}
有個問題是,由於是逐層嵌套結構,導致 層級越深,點擊範圍越小,就像這樣
那麼,如何做成通欄都可以點擊呢?
這時,我們可以創建一個僞元素,並設置絕對定位,但是只需要設置水平方向上的偏移量,這樣在水平方向上位置就是固定的(相對於外層父級),而垂直方向上,仍然處於默認位置,也就是跟隨容器本身,關鍵實現如下
.tree{
/*最外層父級需要設置相對定位*/
position: relative;
}
.tree-item::before{
content: '';
position: absolute;
left: 10px;
right: 10px;/*水平方向的尺寸依賴於父級.tree*/
height: 38px;
background: #EEF2FF;
border-radius: 8px;
z-index: -1;
opacity: 0;
transition: .2s;
}
.tree-item:hover::before{
opacity: 1;
}
效果是這樣的
這樣就非常完美了,而且除了這種方式,好像找不到其他更好的解決方案了,有其他解決方案歡迎留言討論
完整 demo 可以訪問以下任意鏈接:
-
CSS tree (juejin.cn)[12]
-
CSS tree (codepen.io)[13]
-
CSS tree (runjs.work)[14]
六、最後總結一下
舉了這麼多例子,其實無非就是想強調一下,在使用絕對定位時並不一定需要left
或者top
這樣的偏移量,不僅代碼更加精簡,有時還能達到意想不到的效果,下面總結一下
-
絕對佈局的特性是不佔空間,但不一定完全脫離文檔流,只有在設置了偏移時纔會脫離文檔流
-
如果只設置了一個方向上的偏移量,那麼在另外一個方向上仍然保留着文檔流特性
-
在絕對定位中,
::before
要比::after
要好用的多,因爲::before
默認就是初始位置,可以很輕易的實現重疊效果
然後就是實戰了,根據上面這些案例,相信大家對絕對定位一定有了新的認識,多多使用吧~ 最後,如果覺得還不錯,對你有幫助的話,歡迎點贊、收藏、轉發❤❤❤
參考資料
[1]
CSS absolute tag (juejin.cn): https://code.juejin.cn/pen/7203544411974664224
[2]
CSS absolute tag (codepen.io): https://codepen.io/xboxyan/pen/wvEWRoJ
[3]
CSS absolute tag (runjs.work): https://runjs.work/projects/ce00c1830e6e47a9
[4]
CSS 和 SVG 實現文字漸變、描邊、投影: https://juejin.cn/post/7010944239609577508
[5]
CSS text stroke (juejin.cn): https://code.juejin.cn/pen/7203553341917298725
[6]
CSS text stroke (codepen.io): https://codepen.io/xboxyan/pen/rNZLoKP
[7]
CSS text stroke (runjs.work): https://runjs.work/projects/39c51954b6494e88
[8]
CSS absolute center (juejin.cn): https://code.juejin.cn/pen/7203558150899925050
[9]
CSS absolute center (codepen.io): https://codepen.io/xboxyan/pen/yLxJGwQ
[10]
CSS absolute center (runjs.work): https://runjs.work/projects/5a558fc986ae4fb1
[11]
CSS 實現樹狀結構目錄: https://juejin.cn/post/7095580369537204238
[12]
CSS tree (juejin.cn): https://code.juejin.cn/pen/7085639478659776542
[13]
CSS tree (codepen.io): https://codepen.io/xboxyan/pen/ExoRQNX
[14]
CSS tree (runjs.work): https://runjs.work/projects/949c2f2eacb94ff7
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/NdPPfn_W7NQZiYF5C5AeGw