我不知道的CSS - Position
本文轉(zhuǎn)載自微信公眾號(hào)「自然醒的筆記本」,作者寫(xiě)文章的自然醒 。轉(zhuǎn)載本文請(qǐng)聯(lián)系自然醒的筆記本公眾號(hào)。
熟悉我的小伙伴可能知道,我最近回長(zhǎng)沙工作了,由于之前大部分時(shí)間在做工具,Node.js 的開(kāi)發(fā)比較多。but,現(xiàn)在又重新開(kāi)始寫(xiě)了一些業(yè)務(wù)代碼,發(fā)現(xiàn) CSS 有很多博大精深的東西,所以,今天的文章復(fù)習(xí)一下 CSS 定位相關(guān)的東西。
定位的類型
在最新的 CSS 規(guī)范中,定位的元素一共分為四種類型:
- relative:相對(duì)定位元素
- absolute:絕對(duì)定位元素
- fixed:固定定位元素
- sticky:粘性定位元素
如果元素沒(méi)有設(shè)置 position 屬性,默認(rèn)為 static ,其所有定位相關(guān)的屬性(top/bottom/left/right/z-index)就會(huì)失效。
在不修改 position 屬性的情況下,冒然給它設(shè)置 top、left等屬性,會(huì)發(fā)現(xiàn)它巋然不動(dòng)。
相對(duì)定位
相對(duì)定位是指元素在原來(lái)的位置上,進(jìn)行一定的偏移,具體偏移到哪里,還是得看 top/bottom/left/right 這四個(gè)屬性的值。
下面給一個(gè)元素設(shè)置為相對(duì)定位(position: relative;),然后讓元素距離頂部和左邊都為 30px。
- <style>
- div {
- width: 200px;
- height: 200px;
- background: steelblue;
- }
- .relative {
- position: relative;
- top: 30px;
- left: 30px;
- }
- </style>
- <body>
- <div class="relative"></div>
- <body/>
下面的圖片就是元素沒(méi)有加上 .releativ和加上 .releative 的區(qū)別。
元素在絕對(duì)定位的時(shí)候,其初始位置會(huì)被保留下來(lái),也就是原來(lái)的位置上會(huì)留白。
- div {
- display: inline-block;
- width: 200px;
- height: 200px;
- }
- .box1 {
- background: red;
- }
- .box2 {
- background: yellow;
- }
- .box3 {
- background: blue;
- }
- .relative {
- position: relative;
- top: 30px;
- left: 30px;
- }
先為元素定義好樣式,在三個(gè)元素都沒(méi)有進(jìn)行偏移時(shí),如下所示:
- <body>
- <div class="box1"></div>
- <div class="box2"></div>
- <div class="box3"></div>
- <body/>
如果給第二個(gè)元素加上相對(duì)定位,第二個(gè)元素就會(huì)向右邊和下邊進(jìn)行偏移,同時(shí)在原始的位置會(huì)空出來(lái)一塊。
- <body>
- <div class="box1"></div>
- <div class="box2 relative"></div>
- <div class="box3"></div>
- <body/>
絕對(duì)定位
絕對(duì)定位不會(huì)相對(duì)于原來(lái)的位置定位,而是會(huì)向上查找,找到一個(gè)非 static 的祖先元素進(jìn)行定位,如果一直到 body 都沒(méi)有非 static 的元素,則會(huì)相對(duì)于 body 來(lái)進(jìn)行定位。
- <style>
- body { /* 清理body默認(rèn)樣式 */
- margin: 0;
- padding: 0;
- }
- .box {
- margin: 30px;
- display: inline-block;
- width: 300px;
- height: 300px;
- }
- .box1 {
- position: relative;
- border: 3px solid red;
- }
- .box2 {
- border: 3px solid yellow;
- }
- .box3 {
- border: 3px solid blue;
- }
- .absolute {
- /*
- position: absolute;
- top: 30px;
- left: 30px;
- */
- width: 100px;
- height: 100px;
- background-color: aquamarine;
- }
- </style>
- <body>
- <div class="box box1">
- <div class="box box2">
- <div class="box box3">
- <div class="absolute"></div>
- </div>
- </div>
- </div>
- </body>
在未給最內(nèi)部的 div 設(shè)置 position 屬性時(shí),它是緊挨著 div.box3 的邊框的。下面我們給內(nèi)部的 div 加上 position: absolute; ,讓其進(jìn)行絕對(duì)定位。
- .absolute {
- position: absolute;
- top: 30px;
- left: 30px;
- width: 100px;
- height: 100px;
- background-color: aquamarine;
- }
由于外面三層的 div.box 都是默認(rèn)的 static 狀態(tài),所以絕對(duì)定位的元素會(huì)相對(duì)于 body 進(jìn)行定位,距離 body 的頂部和左邊 30px。
現(xiàn)在,給 div.box2 加上一個(gè)相對(duì)定位,此時(shí)的絕對(duì)定位元素就會(huì)相對(duì)于 div.box2 來(lái)進(jìn)行定位。
- .box2 {
- position: relative;
- border: 3px solid yellow;
- }
絕對(duì)定位除了定位的元素不同,它的初始位置也不會(huì)被保留,相當(dāng)于脫離了文檔流。這里我們可以用之前相對(duì)定位的案例,布局三個(gè) div,讓中間的 div 進(jìn)行絕對(duì)定位。
- <style>
- div {
- display: inline-block;
- width: 200px;
- height: 200px;
- }
- .box1 {
- background: red;
- }
- .box2 {
- background: yellow;
- }
- .box3 {
- background: blue;
- }
- .absolute {
- position: absolute;
- top: 30px;
- left: 30px;
- }
- </style>
- <body>
- <div class="box1"></div>
- <div class="box2 absolute"></div>
- <div class="box3"></div>
- </body>
可以看到,中間的 div 會(huì)相對(duì)于 body 進(jìn)行定位,同時(shí),它原來(lái)的位置也不會(huì)被保留。
固定定位
理解了相對(duì)定位和絕對(duì)定位,固定定位就比較好理解了。固定定位會(huì)相對(duì)于視窗進(jìn)行定位,而且和絕對(duì)定位一樣也會(huì)脫離文檔流。這里寫(xiě)一個(gè)簡(jiǎn)單的例子:
- <style>
- .box {
- width: 200px;
- height: 200px;
- border: 1px solid red;
- margin: 100px;
- }
- .fixed {
- position: fixed;
- top: 30px;
- left: 30px;
- width: 100px;
- height: 100px;
- background-color: cadetblue;
- }
- </style>
- <body>
- <div class="box">
- <div class="fixed"></div>
- </div>
- </body>
粘性定位
前面的內(nèi)容都是復(fù)習(xí),這個(gè)粘性定位確實(shí)是最近剛剛接觸的??,沒(méi)辦法 CSS 太菜了。
粘性定位可以理解為相對(duì)定位和固定定位的縫合,會(huì)出現(xiàn)這個(gè)屬性主要是現(xiàn)在很多 H5 頁(yè)面都會(huì)有這種在頂部固定的導(dǎo)航欄,看來(lái) W3C 也是能看到我們普通開(kāi)發(fā)者的需求的。
- .sticky {
- position: sticky;
- top: 0;
- margin-top: 50px;
- }
當(dāng)我們給一個(gè)元素設(shè)置為粘性定位時(shí),如果設(shè)置了 top: 0;,粘性定位的元素在它距離視窗頂部大于 0 的時(shí)候,會(huì)按照默認(rèn)布局來(lái),也就是和相對(duì)定位表現(xiàn)一致。一旦其距離頂部的距離等于 0,這元素會(huì)固定在窗口的這個(gè)地方,此時(shí)的表現(xiàn)和固定布局表現(xiàn)一致。
具體的效果如下:
有了這個(gè)屬性就可以少些很多 JavaScript 代碼了,通過(guò)幾行 CSS 就能實(shí)現(xiàn)一起需要引入一個(gè)插件才能實(shí)現(xiàn)的功能。原來(lái)現(xiàn)在的 CSS 已經(jīng)這么厲害了。
最近更新公眾號(hào)的頻率明顯下降,而且內(nèi)容也越來(lái)越水了,之前寫(xiě)的 Go 筆記也沒(méi)什么深入的內(nèi)容。最近因?yàn)閾Q城市、換工作,然后也一時(shí)不知道寫(xiě)什么,導(dǎo)致質(zhì)量有明顯的下降,后面會(huì)慢慢恢復(fù)周更,然后會(huì)多寫(xiě)一點(diǎn)前端框架和工程化方面的東西,共勉。