CSS進階內容—浮動和定位詳解
我們在學習了CSS的基本知識和盒子之後,就該瞭解一下網頁的整體構成了
當然如果沒有學習之前的知識,可以到我的主頁中檢視之前的文章:秋落雨微涼 - 部落格園
CSS的三種佈局流派
網頁佈局的本質就是用CSS控制盒子的擺放來形成頁面
CSS提供了三種流派來控制盒子:
- 普通流
- 浮動
- 定位
所謂普通流就是我們前面所學習的內容:
- 標籤按照規定好的預設方式排序
- 塊級元素獨佔一行
- 行級元素順序排列,遇到父元素邊緣換行
接下來讓我們走進浮動和定位的世界
浮動
首先我們為什麼需要浮動呢?
- 我們使用浮動當然是因為一些要求我們的標準流無法完成
- 我們使用浮動最常見的應用場景就是將多個塊級元素div等並排放置
- (縱向排列標準流,橫向排列找浮動)
初見浮動
那麼我們來介紹一下浮動:
- 浮動的目的是建立浮動框,使浮動框移動至相應位置
- 浮動會緊貼著大盒子本身或是其他浮動盒子邊緣
- float:left/right 用來控制盒子浮動在左側還是右側
我們給出簡單的程式碼示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>浮動</title>
<style>
div {
height: 100px;
width: 200px;
background-color: palevioletred;
/* 我們加入一個邊框,以便於更好區分兩個div */
border: 1px black solid;
/* 這裡表示開啟浮動,且向左浮動 */
float: left;
}
</style>
</head>
<body>
<div></div>
<div></div>
</body>
</html>
浮動特性
我們再來講解一下浮動的特性:
- 浮動特性會脫離標準流
- 脫離標準流的位置,並且盒子不再保留原本的位置
- 當body中有兩個div,一個div帶有浮動,一個div不帶有浮動,那麼兩個盒子會處於同一位置
- 但帶浮動的盒子會在上面,不帶浮動的盒子在下面
我們給出程式碼示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>浮動特性</title>
<!-- 我們為兩個div提供不同屬性 -->
<style>
.floats {
height: 100px;
width: 200px;
background-color: palegoldenrod;
float: left;
}
.normals {
height: 300px;
width: 200px;
background-color: red;
}
</style>
</head>
<body>
<div class="floats"></div>
<div class="normals"></div>
</body>
</html>
- 所有在同一父類的浮動元素都在一排顯示且對上對齊,並且緊貼在一起(若當前頁面不能完全顯示,則另起一行)
- 浮動元素具有行內塊元素的特性(有寬高,同一行,當不具備寬高時長度與內容一致)
浮動常用方法
浮動元素經常與標準流父級搭配使用:
- 我們先採用標準流父級控制縱向框架
- 再用浮動元素的子盒子控制這一框架內的佈局
簡單案例
我們通過一個簡單案例展示浮動和標準流搭配產生的佈局效果:
- 案例:我們通過一個大盒子裝有兩個小盒子,使兩個小盒子左浮動並排排序(中間沒有間隙)
圖片展示效果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>案例</title>
<style>
/* 我們先設定大盒子的屬性 */
.father {
width: 1200px;
height: 460px;
background-color: pink;
margin: 0 auto;
}
/* 然後設定左浮動盒子 */
.left {
width: 230px;
height: 460px;
background-color: purple;
float: left;
}
.right {
width: 970px;
height: 460px;
background-color: skyblue;
float: left;
}
</style>
</head>
<body>
<!-- 首先我們需要一個標準流的大盒子來控制整體縱向位置 -->
<div class="father">
<!-- 然後我們用兩個浮動來控制內部的位置 -->
<div class="left">left</div>
<div class="right">right</div>
</div>
</body>
</html>
- 案例:我們通過一個大盒子裝有四個小盒子,使四個小盒子左浮動並排排序(中間有間隙)
圖片展示效果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>案例</title>
<style>
/* 我們需要做初始化設定,去除基本margin和padding,去掉li的前置style*/
* {
padding: 0;
margin: 0;
}
li {
list-style: none;
}
/* 首先設定大盒子 */
.box {
width: 1226px;
height: 285px;
background-color: pink;
margin: 0 auto;
}
/* 然後我們設定小盒子 */
.box li {
width: 296px;
height: 285px;
background-color: purple;
float: left;
/* 因為盒子之間有縫隙,我們用margin控制 */
margin-right: 14px;
}
.box .lis {
/* 因為四個盒子只有三個縫隙,但上文標註了四個縫隙,所以我們需要去除掉最後一個縫隙,否則最後一個盒子將會被擠出大盒子 */
margin-right: 0;
}
</style>
</head>
<body>
<ul class="box">
<li>1</li>
<li>2</li>
<li>3</li>
<li class="lis">4</li>
</ul>
</body>
</html>
- 案例:我們結合案例1和案例2來組合成案例3
圖片效果展示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>案例3</title>
<!-- 該案例結合了上面兩種情況,我在這裡不做出詳細程式碼了 -->
<!-- 如果有興趣可以自己嘗試完成一下 -->
</head>
<body>
<!-- 先來實現案例1的操作 -->
<!-- 首先是一個大盒子 -->
<div class="box">
<!-- 大盒子裡分為左右兩個小盒子 -->
<div class="left"></div>
<!-- 在右邊的盒子裡實現案例2的操作 -->
<div class="right">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
</ul>
</div>
</div>
</body>
</html>
注意點
浮動佈局的三個注意點:
- 浮動和標準流父親搭配
- 一個元素浮動了,理論上其他兄弟元素也應該浮動
- 浮動的盒子只會影響後面的標準流盒子(即一個盒子浮動後,對前面標準流盒子不做影響,但後面的標準流盒子會壓住浮動盒子,所以只對後面標準流盒子做影響)
浮動清除
首先我們介紹一下為什麼要清除浮動:
- 因為內容不同可能導致父類盒子高度不確定,只能由子盒子來撐開父親
- 但是父類盒子不給高度,內部元素又都是浮動狀態的話,父類盒子高度為0,就會導致後面排版錯誤
下面給出程式碼示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 當我們存在浮動盒子且沒有高度時,box的高度為0 -->
<style>
.box {
width: 1226px;
background-color: pink;
margin: 0 auto;
}
.ermao,.daomao {
width: 296px;
height: 285px;
background-color: purple;
float: left;
margin-right: 14px;
}
/* 當我們的box沒有高度時,下面再出現其他標準流盒子,就會直接覆蓋到box上導致排版錯誤 */
.footer {
height: 100px;
background-color: black;
}
</style>
</head>
<body>
<div class="box">
<div class="damao"></div>
<div class="ermao"></div>
<div class="ermao"></div>
</div>
<div class="footer"></div>
</body>
</html>
清除浮動的本質:
- 為了清除浮動所帶來的影響
- 當我們清除浮動之後,父類盒子會根據子類盒子來控制高度
- 主要採用clear:left/right/both來清除其float性質
清除浮動方法:
-
額外標籤法
-
在浮動末尾加上clear:both;屬性
-
優點:通俗易懂
-
缺點:新增無意義標籤,結構性差
-
我們給出程式碼展示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 1226px;
background-color: pink;
margin: 0 auto;
}
.damao,.ermao {
width: 296px;
height: 285px;
background-color: purple;
float: left;
margin-right: 14px;
}
/* 在這裡寫下clear屬性 */
.clear {
clear: both;
}
.footer {
height: 100px;
background-color: black;
}
</style>
</head>
<body>
<div class="box">
<div class="damao"></div>
<div class="ermao"></div>
<div class="ermao"></div>
<!-- 在box結束末尾插入clear屬性 -->
<!-- 且這裡必須使用塊級元素 -->
<div class="clear"></div>
</div>
<div class="footer"></div>
</body>
</html>
- 父級新增overflow
- 給父類新增overflow:hidden即可
- 優點:程式碼簡便
- 缺點:無法顯示溢位部分
我們給出程式碼示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 1226px;
background-color: pink;
margin: 0 auto;
/* 直接給出overflow屬性即可 */
overflow: hidden;
}
.damao,.ermao {
width: 296px;
height: 285px;
background-color: purple;
float: left;
margin-right: 14px;
}
.footer {
height: 100px;
background-color: black;
}
</style>
</head>
<body>
<div class="box">
<div class="damao"></div>
<div class="ermao"></div>
<div class="ermao"></div>
</div>
<div class="footer"></div>
</body>
</html>
-
:after偽元素法
- 我們目前不需要掌握確切程式碼意思,這種情況相當於在最後建立一個盒子並實現clear方法
.clearfix { *zoom: 1; } .clearfix:after { content: ""; display: block; height: 0; clear: both; visibility: hidden; }
- 然後給父類的class裡新增clearfix即可
我們下面給出程式碼示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.clearfix {
*zoom: 1;
}
.clearfix:after {
content: "";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.box {
width: 1226px;
background-color: pink;
margin: 0 auto;
}
.damao,.ermao {
width: 296px;
height: 285px;
background-color: purple;
float: left;
margin-right: 14px;
}
.footer {
height: 100px;
background-color: black;
}
</style>
</head>
<body>
<div class="box clearfix">
<div class="damao"></div>
<div class="ermao"></div>
<div class="ermao"></div>
</div>
<div class="footer"></div>
</body>
</html>
-
雙偽元素法:
- 我們目前不需要掌握確切程式碼意思,這種情況相當於在開始和最後建立一個盒子並實現clear方法
.clearfix { *zoom: 1; } .clearfix:after { clear: both; } .clearfix:after,.clearfix:before { content: ""; display: table; }
- 然後給父類的class裡新增clearfix即可
我們下面給出程式碼示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.clearfix {
*zoom: 1;
}
.clearfix:after {
clear: both;
}
.clearfix:after,.clearfix:before {
content: "";
display: table;
}
.box {
width: 1226px;
background-color: pink;
margin: 0 auto;
}
.damao,.ermao {
width: 296px;
height: 285px;
background-color: purple;
float: left;
margin-right: 14px;
}
.footer {
height: 100px;
background-color: black;
}
</style>
</head>
<body>
<div class="box clearfix">
<div class="damao"></div>
<div class="ermao"></div>
<div class="ermao"></div>
</div>
<div class="footer"></div>
</body>
</html>
定位
首先我們為什麼需要定位呢?
- 同理,因為一些要求我們之前學習的標準流和浮動無法完成
- 定位主要是為了讓盒子自由移動並壓住盒子或固定於某一位置
定位組成
定位 = 定位模式 + 邊偏移
- 定位模式:指定一個元素在文件的定位方法
- 定位模式分為四種:
- static 靜態定位
- relative 相對定位
- absolute 絕對定位
- fixed 固定定位
- 邊偏移:決定元素的最終位置
- 邊偏移也分為四個方向:
- top,bottom,left,right
定位模式
定位模式分為四種:static relative absolute fixed
接下來讓我們一一瞭解:
- static靜態定位
靜態定位是元素的預設定位方法,無定位的意思
語法:
選擇器{ position:static;}
- 靜態定位就是按照標準流特性擺放位置,沒有位偏移
- 靜態定位很少使用
- relative 相對定位
相對定位是元素在移動位置時,是相對於原本的位置來說的
語法:
選擇器{ position:relative;}
- 它是相對於自己原本的位置進行移動
- 它在移動之後,在標準流中仍舊佔有原本的位置(即移動之後,原本位置仍舊保留,其他標準流無法佔用該位置)
- 它在移動之後,在其他位置時,屬於覆蓋在其他盒子之上
我們給出程式碼測試:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 接下來我們讓box1定位移動,使其覆蓋在box2上面 -->
<style>
.box1 {
width: 100px;
height: 100px;
background-color: pink;
/* 設定為relative屬性,並且採用top和left進行移動 */
position: relative;
top: 50px;
left: 50px;
}
.box2 {
width: 100px;
height: 100px;
background-color: black;
}
</style>
</head>
<body>
<div class="box1"></div>
<div class="box2"></div>
</body>
</html>
- absolute 絕對定位
絕對定位是元素在移動位置的時候,相對於它的祖先元素來說的
語法:
選擇器{positon:absolute;}
- 若無祖先元素或祖先元素無定位,則以瀏覽器為準進行定位
- 若祖先元素有定位(相對定位,絕對定位都可以),則以祖先元素為定位(有定位的前提下就近原則)
- 絕對定位的標準流位置不保留,其他標準流可以佔有絕對定位的原本位置
我們下面給出程式碼示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 首先我們測試無父元素,或者父元素沒有定位的狀況 */
.nofather {
height: 200px;
width: 200px;
background-color: black;
/* 這種情況下會以瀏覽器左上角為標準 */
position: absolute;
top: 100px;
left: 100px;
}
/* 然後我們測試有定位的孩子(若父親沒有定位,爺爺有定位,則以爺爺為準,依次類推) */
.son {
height: 100px;
width: 100px;
background-color: pink;
/* 這種情況下會以瀏覽器左上角為標準 */
position: absolute;
top: 50px;
left: 50px;
}
/* 我們建立另一個標準流,我們會發現它會覆蓋在原本nofather的位置上 */
.anthor {
height: 200px;
width: 200px;
background-color: skyblue;
}
</style>
</head>
<body>
<div class="nofather">
<div class="son"></div>
</div>
<div class="anthor"></div>
</body>
</html>
- fix固定定位
固定定位是元素固定於瀏覽器可視區的位置,主要應用於:在瀏覽器頁面滾動時元素位置不發生改變
語法:
選擇器{position:fix;}
- 以瀏覽器的可視視窗為參照點移動元素
- 和父元素沒有任何關係
- 不隨滾動條滾動
- 固定定位不佔有原有位置
fixed小技巧:
我們希望使fix內容緊貼版心右側固定不變
那麼我們就可以使fix的位置left在瀏覽器寬的的一半,然後設定margin-left為版心寬度的一半
我們給出程式碼示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 首先我們設定一個版心box */
.box {
width: 800px;
height: 1400px;
background-color: pink;
margin: 0 auto;
}
/* 然後我們設定一個fixed附屬框,為fix屬性 */
.fixed {
width: 50px;
height: 150px;
background-color: black;
/* 首先設定fix屬性 */
position: fixed;
/* 然後我們設定left為頁面一半,設定margin為版心一半 */
left: 50%;
margin-left: 400px;
}
</style>
</head>
<body>
<div class="fixed"></div>
<div class="box"></div>
</body>
</html>
- 粘性定位(sticky)
粘性定位可以認為使相對定位和固定定位的混合
語法:
選擇器{position:sticky;}
- 以瀏覽器的可視視窗為參照點移動元素(固定定位特點)
- 粘性定位佔有原先的位置(相對定位特點)
- 需要有top,left,right,bottom中其中一個控制滯停位置才可以生效
- 注意:有的相容性較差,不能使用
我們下面給出程式碼示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 首先設定box,讓我們的頁面有可拉動的空間 */
.box {
height: 3000px;
}
/* 然後我們以導航欄為例,當它位於頁面最上端時(top=0),導航欄不再跟著頁面滑動而滑動 */
.nav {
width: 200px;
height: 100px;
background-color: aqua;
margin: 100px auto;
/* 設定為粘性 */
position: sticky;
/* 設定滯停位置 */
top: 0;
}
</style>
</head>
<body>
<div class="nav">導航欄</div>
<div class="box"></div>
</body>
</html>
子絕父相
子絕父相:
- 父級為了限制子級,必須採用相對定位
- 自己為了放置於任意位置且不干擾其他盒子,必須採用絕對定位
我們給出一個案例來解釋子絕父相:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>案例</title>
<!-- 我們採用之前的案例,希望在這個案例的右上角加入一個新的小圖示 -->
<style>
* {
padding: 0;
margin: 0;
}
/* 首先我們要給父類加上定位,這裡採用相對定位且不發生位置變化 */
.box {
position: relative;
height: 415px;
width: 298px;
background-color: rgba(255, 255, 255, 0);
margin: 100px auto;
}
.box img {
width: 100%;
}
/* 然後我們將圖片以絕對定位的方法插入並設定位置 */
.good {
width: 10px;
position: absolute;
/* 因為父親有相對定位,所以我們只需要相對父類設定位置即可 */
top: 10px;
right: 20px;
}
.review {
font-family: 微軟雅黑;
font-size: 14px;
height: 70px;
padding: 0 28px;
margin-top: 30px;
}
.appraise {
font-family: 微軟雅黑;
font-size: 12px;
color: #b0b0b0;
padding: 0 28px;
margin-top: 28px;
}
.info {
font-size: 14px;
padding: 0 28px;
margin-top: 15px;
}
.info em {
font-style: normal;
color: #ebe4e0;
margin: 0 6px 0 15px;
}
.info .price {
color: #ff6700;
}
</style>
</head>
<body>
<div class="box">
<!-- 這裡插入我們新插入的小花圖案 -->
<img class="good" src="好評.png" alt="好評">
<!-- 首先我們放入照片 -->
<img src="../../lesson2/Demo/案例照片/1.png" alt="圖片">
<!-- 放入第一行文字 -->
<p class="review">快遞牛,整體不錯,藍芽都可以秒連</p>
<!-- 放入第二行文字 -->
<p class="appraise">來自1923134的評價</p>
<!-- 最後一行文字 -->
<p class="info"><span class="name">Redmi AirDots真無線藍...</span><em>|</em><span class="price">99.9元</span></p>
</div>
</body>
</html>
定位疊放次序
在使用定位佈局時,可能會引起盒子重疊的情況,我們需要z-index來設定疊放權重
語法:
選擇器{z-index:n;}
- 數值可以是正整數,負整數和0,預設為auto,值越大,權重越大
- 如果屬性相同,則按照書寫順序,後來者居上
- 數字後面不能加單位
- 只要定位的盒子才有z-index屬性
我們下面給出程式碼示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 我們給出三個盒子,分別設定定位和z-index,可以清楚看出z-index效果 -->
<style>
div {
position: absolute;
width: 200px;
height: 200px;
}
.w1{
background-color: red;
z-index: 2;
}
.w2{
background-color: green;
left: 50px;
top: 50px;
z-index: 3;
}
.w3{
background-color: blue;
left: 100px;
top: 100px;
z-index: 1;
}
</style>
</head>
<body>
<div class="w1">w1</div>
<div class="w2">w2</div>
<div class="w3">w3</div>
</body>
</html>
絕對定位盒子居中方法
絕對定位盒子無法通過margin: 0 auto居中
需要採用小演算法:left:50% 和 margin-left:-自身50%
我們下面給出程式碼示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 我們需要採用小演算法:left:50% 和 margin-left:-自身50% -->
<style>
div {
/* 首先設定自身屬性 */
height: 100px;
width: 200px;
background-color: black;
/* 然後設定定位,且居中 */
position: absolute;
left: 50%;
margin-left: -100px;
}
</style>
</head>
<body>
<div></div>
</body>
</html>
定位特殊特性
下面我們給出一些定位特殊特性:
- 行內元素用絕對或固定定位時:
- 可以直接設定高寬
- 塊級元素用絕對或固定定位時:
- 若不設定高寬,元素大小預設等於內容大小
- 脫標的盒子不會觸發外邊距塌陷
- 浮動元素和定位元素均不會觸發外邊距合併問題
- 浮動元素僅壓住盒子,但不會壓住文字(用來完成圖文環繞)
- 絕對固定元素會將盒子和文字一併壓住(用來完全覆蓋)
結束語
好的,那麼關於浮動和定位的知識點基本彙總完畢,希望能給你帶來收穫。
接下來我會介紹一些CSS的佈局技巧和知識補充,希望能獲得你的一些鼓勵。