淺談position
定位(position)允許您從正常的檔案流布局中取出元素,并使它們具有不同的行為,例如放在另一個元素的上面,或者始終保持在瀏覽器視窗內的同一位置—— MDN
一、檔案流
什么是檔案流?
"檔案流"是在對布局進行任何更改之前,在頁面上顯示"塊"和"行內"元素的方式,通常是從上至下,從左到右的形式,
這個"流"本質上是一系列的事物,它們都在你的布局中一起作業,并且互相了解, 一旦某部分脫離了"流",它就會獨立地作業
還記得我們提到了盒模型(塊級元素和行級元素),這些單個的元素是如何組合到一起的呢
正常的布局流(在布局介紹文章中提到)是將元素放置在瀏覽器視口內的系統,默認情況下:
- 塊級元素在視口中垂直布局——每個都將顯示在上一個元素下面的新行上,并且它們的外邊距將分隔開它們,
- 行內元素表現不一樣——它們不會出現在新行上;相反,它們互相之間以及任何相鄰(或被包裹)的文本內容位于同一行上,只要在父塊級元素的寬度內有空間可以這樣做,如果沒有空間,那么溢流的文本或元素將向下移動到新行,
如果兩個相鄰元素都在其上設定外邊距,并且兩個外邊距接觸,則兩個外邊距中的較大者保留,較小的一個消失——這叫外邊距折疊(margin塌陷), 我們之前也提到過,
讓我們來看一個簡單的例子來決議這一切:
.box{
border: 2px solid #1790FF;
padding: 20px;
width: 400px;
height: 300px;
}
h2, h3, p{
border: 1px solid blue;
}
span, a{
background: rgb(185, 116, 116);
}
<div class="box">
<h2>二級標題</h2>
<h3>副標題</h3>
<p>我是段落1</p>
<p>我是段落2,我包含了有意思的標簽<span>我是span標簽</span>,除了span標簽還有它——<a href="https://www.baidu.com">我是a標簽</a>,你看他們都不會導致新起一行</p>
</div>

在不影響他們布局方式的情況下,檔案流就是默認的規則,從上至下,從左到右,
二、定位(position)
定位的整個想法是允許我們覆寫上面描述的基本檔案流行為,以產生有趣的效果,
有許多不同型別的定位,您可以對HTML元素生效,要使某個元素上的特定型別的定位,我們使用position屬性,
2.1 靜態定位(static)
靜態定位是每個元素獲取的默認值——它只是意味著“將元素放入它在檔案布局流中的正常位置 ——這里沒有什么特別的,
為了演示這一點,還是剛才的例子,我們給h2標簽添加靜態定位
<h2 class="positioned"> ... </h2>
現在,將以下規則添加到CSS的底部:
.positioned {
position: static;
background: #E6F7FF;
}

除了背景色,根本沒有差別~
2.2 相對定位(relative)
相對定位是我們將要看的第一個位置型別, 它與靜態定位非常相似,占據在正常的檔案流中,除了你仍然可以修改它的最終位置,包括讓它與頁面上的其他元素重疊, 讓我們將上一例子中的position: static; 替換成position: relative;

沒有發生變化,這是因為relative,需要配合top, bottom, left, right 來精確指定要將定位元素移動到的位置,例如:
.box {
position: relative;
border: 2px solid #1790FF;
padding: 20px;
width: 400px;
height: 300px;
background: #f5f5f5;
}
h2, h3, p {
border: 1px solid blue;
}
span, a {
background: rgb(185, 116, 116);
}
.positioned {
position: relative;
top: 30px;
left: 40px;
background: #E6F7FF;
}
.positioned::after{
// 此為模擬樣式
content: '';
position: absolute;
top: -30px;
left: -40px;
width: 100%;
height: 100%;
border: 1px dashed #ccc;
}
<div class="box">
<h2 class="positioned">二級標題</h2>
<h3>副標題</h3>
<p>我是段落1</p>
<p>我是段落2,我包含了有意思的標簽<span>我是span標簽</span>,除了span標簽還有它——<a href="https://www.baidu.com">我是a標簽</a>,你看他們都不會導致新起一行
</p>
</div>

發現:
- top和left屬性分別起了作用,且參照物是元素原來的位置,即相對于自己在標準檔案流中的位置進行移動的;
- 其他元素仍然以為二級標題在原位置(看模擬的虛線),也就是說相對定位并沒有脫離標準檔案流;
結論:
使用position: relative,不會讓元素脫離檔案流,目標元素會基于自己原本的位置進行定位
2.3 絕對定位(absolute)
絕對定位帶來了非常不同的結果,讓我們嘗試改變代碼中的位置宣告如下:
.box {
position: relative;
border: 2px solid #1790FF;
padding: 20px;
width: 400px;
height: 300px;
background: #f5f5f5;
}
h2, h3, p {
border: 1px solid blue;
}
span, a {
background: rgb(185, 116, 116);
}
.positioned {
position: absolute;
top: 30px;
left: 40px;
background: #E6F7FF;
}
<div class="box">
<h2 class="positioned">二級標題</h2>
<h3>副標題</h3>
<p>我是段落1</p>
<p>我是段落2,我包含了有意思的標簽<span>我是span標簽</span>,除了span標簽還有它——<a href="https://www.baidu.com">我是a標簽</a>,你看他們都不會導致新起一行
</p>
</div>

發現:
- 絕對定位的元素不再存在于正常檔案布局流中,相反,它坐在它自己的層獨立于一切;
- 注意元素的位置已經改變——這是因為top,bottom,left和right以不同的方式在絕對定位;
結論:
position:absolute(表示絕對定位),這條陳述句的作用將元素從檔案流中拖出來,然后使用left、right、top、bottom屬性相對于其最接近的一個具有定位屬性的父包含塊進行絕對定位,如果不存在這樣的包含塊,則相對于body元素,即相對于瀏覽器視窗,
2.4 固定定位(fixed)
這與絕對定位的作業方式完全相同,只有一個主要區別:絕對定位固定元素是相對于 元素或其最近的定位祖先,而固定定位固定元素則是相對于瀏覽器視口本身, 這意味著您可以創建固定的有用的UI專案,如持久導航選單,
*{
margin: 0;
}
.box {
position: relative;
margin: 0 auto;
border: 2px solid #1790FF;
padding-top: 40px;
width: 400px;
height: 1500px;
background: #f5f5f5;
}
.head{
position: fixed;
top: 0;
left: 0;
width: 100%;
line-height: 40px;
color: #fff;
background: #1790FF;
}
<div class="box">
<div class="head">我是固定導航</div>
我是內容
</div>

發現:
- 與absolute定位型別類似,但它的相對移動的坐標是視圖(螢屏內的網頁視窗)本身;
- 不會受檔案流動影響;
2.5 粘性定位(sticky)
*{
margin: 0;
}
.box {
position: relative;
margin: 0 auto;
border: 2px solid #1790FF;
padding-top: 40px;
width: 400px;
height: 1500px;
background: #f5f5f5;
}
.head{
position: sticky;
top: 0;
left: 0;
width: 100%;
line-height: 40px;
color: #fff;
background: #1790FF;
}
<div class="box">
<div class="head">我是固定導航</div>
我是內容
</div>

發現:
- 固定導航開始沒有脫離檔案流,當滿足top:0,left:0的規則時,脫離了檔案流
結論:
sticky允許被定位的元素表現得像相對定位一樣,直到它滾動到某個閾值點(例如,從視口頂部起1??0像素)為止,此后它就變得固定了,例如,它可用于使導航欄隨頁面滾動直到特定點,然后粘貼在頁面頂部,
三、z-index與定位
我們在前文已經意識到了,一旦使用定位,就可能使元素重疊,有沒有什么方法,可以控制哪一個元素在頂層(不被遮蓋)呢?
我們在定位背景關系中只有一個定位的元素,它出現在頂部,因為定位的元素勝過未定位的元素, 當我們有不止一個的時候呢?
我們先看下面一段代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box{
width: 300px;
border: 1px solid red;
}
.div{
/* position: absolute; */
width: 100px;
height: 100px;
}
.div:nth-child(1){
background: chartreuse;
}
.div:nth-child(2){
background: rgb(92, 153, 135);
}
.div:nth-child(3){
background: rgb(194, 142, 84);
}
.div:nth-child(4){
background: rgb(56, 41, 97);
}
</style>
</head>
<body>
<div class="box">
<div class="div"></div>
<div class="div"></div>
<div class="div"></div>
<div class="div"></div>
</div>
</body>
</html>
四個元素從上至下排列,如果這樣呢?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box{
position: relative;
width: 300px;
margin: 50px;
}
.div{
position: absolute;
width: 100px;
height: 100px;
}
.div:nth-child(1){
top: 0;
left: 0;
background: chartreuse;
}
.div:nth-child(2){
background: rgb(92, 153, 135);
top: 20px;
left: 20px;
}
.div:nth-child(3){
top: 40px;
left: 40px;
background: rgb(194, 142, 84);
}
.div:nth-child(4){
top: 60px;
left: 60px;
background: rgb(56, 41, 97);
}
</style>
</head>
<body>
<div class="box">
<div class="div">1</div>
<div class="div">2</div>
<div class="div">3</div>
<div class="div">4</div>
</div>
</body>
</html>

我們通過調整z-index,可以讓元素1、2、3、4的層疊順序交換
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box{
position: relative;
width: 300px;
margin: 50px;
}
.div{
position: absolute;
width: 100px;
height: 100px;
}
.div:nth-child(1){
z-index: 4;
top: 0;
left: 0;
background: chartreuse;
}
.div:nth-child(2){
z-index: 3;
background: rgb(92, 153, 135);
top: 20px;
left: 20px;
}
.div:nth-child(3){
z-index: 2;
top: 40px;
left: 40px;
background: rgb(194, 142, 84);
}
.div:nth-child(4){
z-index: 1;
top: 60px;
left: 60px;
background: rgb(56, 41, 97);
}
</style>
</head>
<body>
<div class="box">
<div class="div">1</div>
<div class="div">2</div>
<div class="div">3</div>
<div class="div">4</div>
</div>
</body>
</html>

注意,這是z-index的效果,更多樣式需要大家自己去探索哦~
寫在最后
本文是《CSS基礎系列》第三篇文章
如果對你有所幫助不妨給本專案的github 點個 star,這是對我最大的鼓勵!
關于我
- 花名:余光
- WX:j565017805
- 沉迷 JS,水平有限,虛心學習中
其他沉淀
- Github: Js 版 LeetCode 題解
- 前端進階筆記
- CSDN 博客匯總
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/262939.html
標籤:其他
下一篇:[css] 如何實作換膚功能?
