深入理解CSS網頁佈局-理論篇

来源:http://www.cnblogs.com/hlwyfeng/archive/2016/02/27/5222391.html
-Advertisement-
Play Games

在CSS網頁開發佈局中,需要對浮動和定位有深刻的理解才能在開發中游刃有餘。基於此,在博客園中做了本篇總結,這些總結來自實踐經驗和閱讀一些書籍後的理解總結。主要內容為浮動,清除浮動,定位。


在CSS網頁開發佈局中,需要對浮動和定位有深刻的理解才能在開發中游刃有餘。

基於此,在博客園中做了本篇總結,這些總結來自實踐經驗和閱讀一些書籍後的理解總結,主要內容為浮動,清除浮動,定位。

(可點擊屏幕左邊的目錄查閱)

一. float屬性深入理解

首先簡單佈局一下,代碼如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>css Test</title>
<style type="text/css">

#bigBox {
    border: 2px solid Gray;
    width: 500px;
    height: 400px;
    margin: 100px auto;
}

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
}


</style>
</head>
<body>

<div id="bigBox">
    <div id="box1">1</div>
    <div id="box2">2</div>
    <div id="box3">3</div>
</div>

</body>
</html>

效果圖:

圖p1

1. 脫離文檔流

脫離文檔流,即在元素原來的位置中脫離出來,可以理解為漂浮起來,但是要註意一些細節。

細節一

若浮動元素後面有不浮動的元素,那麼其後面不浮動的元素會把浮動元素視為消失,然後頂到它的位置中。

我們來測試一下:對第二個div(id=box2)設置浮動,觀察第三個div的位置

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;

    float:left;/*測試內容*/
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
}

效果圖:

圖p2

我們可以看到第三個div頂到浮動div原來的位置上去了,這裡的float:left 設置為right,也同樣,即第二個div消失了,後面的頂上去。

效果圖:

 圖p3

 

細節二

我們不能理解為設置float之後,這個元素就完全漂浮在沒有設置float元素的上面,雖然在細節一中的效果圖中看是漂浮在上面(2在3的上面)。這個細節就是浮動只對後面的元素造成影響(所謂影響,就是後面的元素把它視為消失),對於排在它前面的同級塊元素,不會對其位置造成影響。(即如果前面的同級塊元素沒有設置浮動,那麼它也不會漂浮到這個元素的上面)。細節一的p1例子已經驗證了這一特性(2還是在1的下麵)。

那麼,對於排在前面的同級內聯元素呢?對於同級內聯元素,設置了float屬性的元素與前面的內聯元素屬於同一層面,而且優先順序高於前面的同級內聯元素,這裡的優先順序指位置優先順序,比如float:left,那麼前面的內聯元素如果原來占據最左邊,那麼它由於優先順序低於浮動元素,所以它就會讓位與浮動元素,排在浮動元素的右邊。

我們來看一下測試代碼(重點查看註釋的測試內容):

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
    display: inline-block; /*測試內容*/
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;

    float:left;  /*測試內容*/
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
}

效果圖:

圖p4

分析:對於1(這裡用數字代表相應的div,上下同)來說,由於排在浮動的2的前面,所以它無論是否為塊元素,都和2屬於同一層面,再由於它不是塊元素,所以它的位置優先順序別低於2,由於2的float:left,向左浮動,所以它靠最左,1被擠到它的右邊。對於3來說,2由於是浮動,所以視為消失了,但是由於3是塊元素,所以獨占一行,於是就有了上面的效果。

 

細節三

 文字永遠會被擠出。我們把1,2設置浮動,把3註釋,然後添加p標簽。查看一下情況:

<div id="bigBox">
    <div id="box1">1</div>
    <div id="box2">2</div>
    <!-- <div id="box3">3</div> -->
    <p>HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! 10個HelloWorld!</p>
</div>

圖p5

實際上,並不是P元素和1,2浮動元素併列排在了一起,在細節一二中,我們知道p元素一定是頂到1的位置中的,但是由於文字永遠是被擠出來的,所以他們被擠到2的左邊,此時實現了一個文字環繞效果。我們可以給P元素添加背景色來查看一下實際:

p {
    background-color: red;
}

 圖p6

 

2. 沒有固定尺寸的父級元素無法自適應浮動的子元素(所有子元素都為浮動)

同樣的,父元素屬於文檔流,如果子元素中有設置浮動的,那麼也視為消失,所以父元素不會包裹它,如果全部子元素都為浮動,那麼相當於這個父元素裡面沒有子元素,此時的表現和子元素為空一樣。

我們先來看一下,在沒有浮動元素的文檔流中的情況:

代碼:

body {
    margin: 0 300px;
}

#bigBox {
    border: 2px solid Gray;
/*    width: 500px;
    height: 400px;*//*測試內容:這裡要設置去掉寬高*/
    margin: 100px auto;
}

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
}
<body>

<div id="bigBox">
    <div id="box1">1</div>
    <div id="box2">2</div>
    <div id="box3">3</div>
</div>

</body>

效果圖:

圖p7

這裡的div(id=bigBox,1,2,3的父級元素)沒有設置寬高,所以自動支撐起了子元素的寬高,由於1,2,3都是塊元素,所以獨占一行,寬度自動適應為body的寬度,所以如效果圖所示,這是沒有設置浮動的情況。

我們把2設置為浮動,查看一下效果:

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
    float: left; /*測試內容*/
}

效果圖:

圖p8

父元素還是可以適應,不過視2為消失。

下麵我們把全部子元素都設置為浮動,查看一下效果:

body {
    margin: 0 300px;
}

#bigBox {
    border: 2px solid Gray;
/*    width: 500px;
    height: 400px;*/
    margin: 100px auto;
}

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
    float: left; /*測試內容*/
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
    float: left; /*測試內容*/
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
    float:left; /*測試內容*/
}

圖p9

 

我們把1,2,3去掉,查看沒有子元素的父元素的效果圖,然後對比一下:

<body>

<div id="bigBox">
  <!--   <div id="box1">1</div>
    <div id="box2">2</div>
    <div id="box3">3</div> -->
</div>

</body>
</html>

圖p10

結果和p9是一樣的,也就是p9中父元素把1,2,3視為消失了。

 

二. 清除浮動

1. 清除浮動方法(非父元素受影響)

方法一:設置clear屬性,這個屬性設置在受影響的元素(非父級)上

clear屬性值有left,right,both,一般情況下對使用both清除浮動,我們來看一下:

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
    float: left; /*測試內容*/
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
    clear:both; /*測試內容*/
}

圖p11

請對比p2,可以這樣形象理解,把原來2的消失變成了可見,然後就排在它的後面。

 

方法二:額外添加一個空元素,並設置clear屬性

<div id="bigBox">
    <div id="box1">1</div>
    <div id="box2">2</div>
    <div id="clear"></div> <!-- 測試內容 -->
    <div id="box3">3</div>
</div>
#clear {
    clear: both;
}

同樣可以達到預期效果:

 圖p12

 

2. 清除浮動方法(父元素受影響)

圖p7中我們看到父元素把子元素1,2,3視為消失,所以無法自適應子元素的寬度,為了消除子元素浮動對父元素的影響,這裡有三個方法可以解決問題,我們來測試分析一下。

先把父元素受影響的代碼和效果圖貼出來:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>css Test</title>
<style type="text/css">

body {
    margin: 0 300px;
}

#bigBox {
    border: 2px solid Gray;
/*    width: 500px;
    height: 400px;*/
    margin: 100px auto;
    /*clear: both;*/
}

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
    float: left; /*測試內容*/
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
    float: left; /*測試內容*/
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
    float: left; /*測試內容*/
}

#clear {
    clear: both;
}

</style>
</head>
<body>

<div id="bigBox">
    <div id="box1">1</div>
    <div id="box2">2</div>
    <div id="box3">3</div>
</div>

</body>
</html>
View Code

圖p13

 

方法一:在父元素裡面添加一個空的子元素,放在最後面,並設置clear屬性

<div id="bigBox">
    <div id="box1">1</div>
    <div id="box2">2</div>
    <div id="box3">3</div>
    <!-- 這是一個清除浮動的空標簽 -->
    <div id="clear"></div>
</div>

效果圖:

圖p14

分析:原理很簡單,空div設置了clear屬性,所以它不受前面1,2,3的影響,所以它就會排在1,2,3的後面,造成了空div與頂部之間有了一定的距離,這個距離就拉大了父元素的尺寸,所以從表現上看,就像是清除了浮動,達到我們想要的效果。

此方法的弊端就是添加了額外的無意義的標簽。

 

方法二:在父元素上設置overflow:hidden;

#bigBox {
    border: 2px solid Gray;
/*    width: 500px;
    height: 400px;*/
    margin: 100px auto;
    overflow:hidden; /*測試內容*/
}

效果圖:

 圖p15

 

深入理解overflow屬性

overflow的屬性值有:visible(預設值),hidden,scroll,auto,inherit

常用的是hidden屬性,除了visible之外,不算inherit(繼承)在內的其他三個屬性值,如果設置了,那麼該元素就會與浮動元素在同一個層面。我們可以看到文章開頭的圖p2中,2浮動在3的上面,因為它們不在同一個層面,如果對3設置overflow:hidden;(三個屬性都可),那麼他們就屬於同一個層面,此時3雖然受浮動的影響,但是由於同一個層面的關係,所以它排在了2的後面,我們來測試一下。

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
    float: left; /*測試內容*/
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
    overflow: hidden;/*測試內容*/
}

效果圖:

圖p16

我們比較圖p2和p16,就可以看出overflow的這一特性。

回到我們討論的父元素上面,父元素設置overflow屬性,所以它就與所有浮動的子元素在同一層面上,所以就支撐了起來。不過它的弊端就是overflow的三個屬性會對子元素超出父元素的部分不顯示出來,可能造成信息缺失。

 

特別註意

在ie6及以下版本中(怪異模式),overflow的設置還是不起作用,這裡就要用到ie特有的一個屬性zoom來解決,只要設置zoom:1,即原來的大小即可,代碼如下:

#bigBox {
    border: 2px solid Gray;
/*    width: 500px;
    height: 400px;*/
    margin: 100px auto;
    overflow: hidden;
    zoom:1;/*添加這個屬性,可相容ie6*/
}

 

方法三:使用自定義偽類,設置清除屬性

這是最實用和推薦的方法,一般把這個偽類的名稱設置為 -XXX-clearFix,比如新浪微博就是用 -weibo-clearFix,在使用的過程中,我們習慣性的使用偽對象after的方法,在clearFix後面添加一些清除浮動的屬性。

.-test-clearFix:after {
    clear: both;
    display: block;
    visibility: hidden; /*設置不可見*/
    height: 0;
    line-height: 0;
    content: ""; /*after偽對象必須的屬性,可以設置內容為空*/
}

.-test-clearFix {}

在父級div裡面添加這個類即可:

<div id="bigBox" class="-test-clearFix">
    <div id="box1">1</div>
    <div id="box2">2</div>
    <div id="box3">3</div>
</div>

效果圖:

圖p17

 

三. 相對定位和絕對定位

1. 相對定位

特點一

相對自身偏移。

相對定位比較好理解,它相對於自身進行了定位,所設置的偏移屬性的參照物為本身原來的位置。

特點二

元素原來的位置不脫離文檔流,占據了位置。

對於特點一、二,我們來測試一下:

#bigBox {
    border: 2px solid Gray;
    width: 500px;
    height: 400px;
    margin: 100px auto; 
}

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
    float: left;
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;

    float: left;
    position: relative;/*測試內容*/
    top: -140px;
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;

    float: left;
}

圖p18

2占據了原來的位置,所以3不會靠左移動。

 

2.絕對定位:absolute

特點一

脫離文檔流

絕對定位和float屬性有相似之處,設置了這個屬性的元素會脫離文檔流,脫離文檔流後的表現和float一樣,但是它無法清除浮動也不占據位置。

#bigBox {
    border: 2px solid Gray;
/*    width: 500px;
    height: 400px;*/
    margin: 100px auto;
    position: relative; /*測試內容*/
}

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
    position: absolute;/*測試內容*/
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
    position: absolute; /*測試內容*/
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
    position: absolute; /*測試內容*/
}

效果圖:

圖p19

圖中可以看出1,2,3進行了絕對定位,並且重疊在了一起。其重疊特性為下麵的特點二。

 

特點二

排再文檔流後面的絕對定位元素顯示的優先順序高於前面的絕對定位元素。

為了區分,我們來給出一定的位移,觀察前後優先順序:

#bigBox {
    border: 2px solid Gray;
/*    width: 500px;
    height: 400px;*/
    margin: 100px auto;
    position: relative; /*測試內容*/
}

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
    position: absolute;/*測試內容*/
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
    position: absolute; /*測試內容*/
    left: 50px;
    top:40px;
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
    position: absolute; /*測試內容*/
    left: 80px;
    top: 20px;
}

圖p20

圖中可以看出優先順序 3>2>1

 

特點三

絕對定位,其父級元素如果沒有設置定位屬性,則以更高級別的有設置定位屬性的作為參照物進行定位,如果父級元素都沒有定位屬性,則以body作為參照。

(代碼參考"特點一"中的代碼#bigBox裡面,設置了relative屬性,裡面的1,2,3以該父級元素進行絕對定位)

 

3. 絕對定位:fixed

這個定位屬性是最簡單的,其特點是脫離文檔流,不占據位置,然後固定在屏幕,不會對文檔流造成影響。這裡就不進行代碼驗證。

 

深入理解了這些屬性,就可以在實際工作中靈活應用,後續會總結一些佈局實戰。本文若有不妥之處,歡迎批評指正。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 分享自己寫的一個簡化版LOG輸出巨集 extern int verbose; #define DBG(...) XLOG(4, "DBG", lxx_va_args) #define INFO(...) XLOG(3, "INF", lxx_va_args) #define WRN(...) XLOG
  • 今天是我註冊博客園並開通博客的第一天,一直以來,潛水在博客園學習了很多技術,拷貝了很多大神的代碼,不算個鐵粉,怎麼著也是博客園的固定游客,工作5年了,學到了很多技術知識,交到了很多同事朋友,嘗到了很多人情冷暖,結了婚,生了娃,買了房,有了車,人生算是幸福美滿,跟老婆兩個人在同一家公司,拿著夠養活自己
  • .Net 大型分散式基礎服務架構橫向演變概述,包含分散式任務調度,分散式配置中心,分散式消息隊列,分散式緩存平臺,分散式服務中心,分散式資料庫中間件平臺等基礎服務的演變說明。
  • 我們用抽象構建框架,用實現擴展細節的註意事項而已:單一職責原則告訴我們實現類要職責單一;里氏替換原則告訴我們不要破壞繼承體系;依賴倒置原則告訴我們要面向介面編程;介面隔離原則告訴我們在設計介面的時候要精簡單一;迪米特法則告訴我們要降低耦合。而開閉原則是總綱,他告訴我們要對擴展開放,對修改關閉。
  • 重要程度:★★★☆☆ 一、什麼是模板方法模式 使用了JAVA的繼承機制,在抽象類中定義一個模板方法,該方法引用了若幹個抽象方法(由子類實現)或具體方法(子類可以覆蓋重寫); 二、補充說明 其實就是JAVA的繼承以及抽象方法、重寫覆蓋的使用; 一般把模板方法定義成final避免被子類修改 三、角色 抽
  • 定義:一個對象應該對其他對象保持最少的瞭解。 問題由來:類與類之間的關係越密切,耦合度越大,當一個類發生改變時,對另一個類的影響也越大。 解決方案:儘量降低類與類之間的耦合。
  • 重要程度:★★★☆☆ 一、什麼是責任鏈模式 為請求創建了一個接收者對象的鏈,每個接收者都包含對另一個接收者的引用,當某個接受者不能處理該請求時,會將該請求轉給下一個接受者處理; 二、補充說明 請求發送者與請求接受者解耦 應用例子:struts的攔截器,servlet的過濾器 三、角色 抽象請求處理者
  • •低層模塊儘量都要有抽象類或介面,或者兩者都有。 •變數的聲明類型儘量是抽象類或介面。 •使用繼承時遵循里氏替換原則。
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...