CSS查漏補缺

塊級格式上下文(Block formatting context)

  1. 普通流(Normal Flow)javascript

    在普通流中,元素按照其在 HTML 中的前後位置至上而下佈局,在這個過程當中,行內元素水平排列,直到當行被佔滿而後換行,塊級元素則會被渲染爲完整的一個新行, 除非另外指定,不然全部元素默認都是普通流定位,也能夠說,普通流中元素的位置由該元素在 HTML 文檔中的位置決定。
  2. 浮動 (Floats)css

    在浮動佈局中,元素首先按照普通流的位置出現,而後根據浮動的方向儘量的向左邊或右邊偏移,其效果與印刷排版中的文本環繞類似。
  3. 絕對定位 (Absolute Positioning)html

    在絕對定位佈局中,元素會總體脫離普通流,所以絕對定位元素不會對其兄弟元素形成影響(若是看了上文的童鞋,會發現這點與浮動元素會影響兄弟元素是不一樣的),而元素具體的位置由絕對定位的座標決定。

BFC 正是屬於普通流的,所以它對兄弟元素也不會形成什麼影響。java

什麼是BFC?

塊格式化上下文(block formatting context) 是頁面 CSS 視覺渲染的一部分。它是用於決定塊盒子的佈局及浮動相互影響的一個區域。 --MDN 塊格式上下文segmentfault

個人理解是,BFC是一個環境,在這個環境中的元素不會影響到其餘環境中的佈局,也就是說,處於不一樣BFC中的元素是不會互相干擾的。瀏覽器

BFC的觸發條件

  • 根元素或其它包含它的元素ide

  • 浮動元素,float除none之外的值佈局

  • 絕對定位元素 (元素的 position 爲 absolute 或 fixed)學習

  • display爲如下其中之一的值:inline-block,table-cell,table-captionflex

  • overflow 的值不爲 visible的元素

  • 彈性盒子 flex boxes (元素的 display: flex 或 inline-flex)

其中,最多見的就是overflow:hidden、float:left/right、position:absolute。也就是說,每次看到這些屬性的時候,就表明了該元素以及建立了一個BFC了。

BFC的特性

  1. 內部的盒會在垂直方向一個接一個排列(能夠看做BFC中有一個的常規流);

  2. 處於同一個BFC中的元素相互影響,可能會發生margin collapse;

  3. 每一個元素的margin box的左邊,與容器塊border box的左邊相接觸(對於從左往右的格式化,不然相反)。即便存在浮動也是如此;

  4. BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素,反之亦然;

  5. 計算BFC的高度時,考慮BFC所包含的全部元素,連浮動元素也參與計算;

  6. 浮動盒區域不疊加到BFC上;

BFC有什麼用?

  1. 阻止外邊距摺疊

    兩個相連的塊級元素在垂直上的外邊距會發生疊加,有些把這種狀況看做是bug,但我以爲多是出於段落排版的考慮,爲了令行間距一致纔有的這一特性。咱們先來看看例子:

    <p>first</p>
    <p>second</p>
    *{margin: 0px;padding: 0px}
    p {
        color: red;
        background: #eee;
        width: 100px;
        height: 100px;
        line-height: 100px;
        text-align: center;
        margin: 10px;
        border: solid 1px red;
    }

    外邊距摺疊狀況

    從上面能夠看出,咱們給兩個p元素都設置margin,但中間的間距卻發生了摺疊。而後舉個BFC的例子:

    .ele{
        overflow: hidden;
        border: solid 1px red;
    }
    <div class="ele">
        <p>first</p>
    </div>
    <div class="ele">
        <p>second</p>
    </div>

    防止外邊距摺疊

    從上面能夠看出,咱們爲每一個div元素設置overflow的值爲hidden,產生一個塊級格式上下文,由於外邊距不會相互重疊。

  2. BFC能夠包含浮動的元素

    //html
    <div class = "box">
        <div class= "floatL">float</div>
        <div class= "floatL">float</div>
    </div>
    
    <br style="clear:both">
    <div class = "box BFC">
        <div class= "floatL">float</div>
        <div class= "floatL">float</div>
    </div>
    *{margin: 0px;padding: 0px}
    .floatL{
        float: left;
        width: 100px;
        height: 100px;
        background-color: red;
        text-align: center;
        line-height: 100px;
    }
    .box{
        border: 1px solid red;
        width: 300px;
        margin: 100px;
        padding: 20px;
    }
    .BFC{
        overflow: hidden;
        *zoom: 1;
    }

    bfc計算高度

    從運行結果能夠看出,若是塊級元素裏面包含着浮動元素會發生高度塌陷,可是將它變成一個BFC後,BFC在計算高度時會自動將浮動元素計算在內。

  3. BFC能夠阻止元素被浮動元素覆蓋

    <div class="box1">box1</div>
    <div class="box2">box2</div>
    *{margin: 0px; padding: 0px}
    
    .box1{
        width: 100px;
        height: 100px;
        line-height: 100px;
        text-align: center;
        background-color: rgba(0, 0, 255, 0.5);
        border: 1px solid #000;
        float: left;
    }
    .box2{
        width: 200px;
        height: 200px;
        line-height: 100px;
        text-align: center;
        background-color: rgba(255, 0, 0, 0.5);
        border: 1px solid #000;
        /* overflow: hidden; */
        /* *zoom: 1; */
    }

    浮動元素重疊

    從上面看出,當元素浮動後,會與後面的塊級元素產生相互覆蓋。那怎麼解決這個問題,只要爲後面的元素建立一個BFC。添加overflow屬性到box2上。

    overflow: hidden;
    *zoom: 1;

    bfc

    這樣子阻止了浮動元素重疊的問題。

BFC與hasLayout

除了使用 overflow: hidden 觸發 BFC 外,還使用了一個 *zomm: 1 的屬性,這是 IEhack ,由於 IE6-7 並不支持 W3C 的 BFC ,而是使用私有屬性 hasLayout 。從表現上來講,hasLayout 跟 BFC 很類似,只是 hasLayout 自身存在不少問題,致使了 IE6-7 中一系列的 bug 。觸發 hasLayout 的條件與觸發 BFC 有些類似,推薦爲元素設置 IE 特有的 CSS 屬性 zoom: 1 觸發 hasLayoutzoom 用於設置或檢索元素的縮放比例,值爲「1」即便用元素的實際尺寸,使用 zoom: 1 既能夠觸發 hasLayout 又不會對元素形成其餘影響,相對來講會更爲方便。

拓展閱讀:

Block formatting context(塊級格式化上下文)

學習塊格式化上下文

BFC與hasLayout

清除浮動

經典的清除浮動:

//利用僞元素清除浮動
.clearfix:after {
     content:"."; 
     display:block; 
     height:0; 
     visibility:hidden; 
     clear:both; 
}
.clearfix { 
    *zoom:1; 
}

拓展閱讀:
那些年一塊兒清除過的浮動

認識聖盃佈局和雙飛翼佈局

各類各樣的佈局,無非就是用了浮動 float,負邊距,相對定位,經過這三者的巧妙組合跟拼湊來實現的。用好這些,佈局就會很簡單。

還沒學會佈局時,就聽到有聖盃佈局和雙飛翼佈局,這佈局都有這麼風騷的名字,就以爲很酷,事實也如此,瞭解了聖盃佈局和雙飛翼佈局,才發現挺深奧的。

傳統的佈局中,當咱們須要改變兩欄的互換,就會很麻煩。由於還要涉及到 HTML 代碼的修改,不能徹底從 CSS 上更改,這叫 HTML 和 CSS 的耦合。而聖盃佈局跟雙飛翼佈局就是可以不考慮主體的位置,可以只經過 CSS 代碼就改變相應的佈局,這也是優勢之一。

聖盃佈局

試試這樣的HTML結構:

<div class="header">header</div>
<div class="container">
    <div class="main">main</div>
    <div class="sub">sub</div>
    <div class="extra">extra</div>
</div>
<div class="footer">footer</div>

給它加上CSS樣式:

body{ margin: 0; padding: 0; font-size: 1.5em; font-weight: bold; min-width: 500px;}
.header,.footer{ text-align: center;}
.header{ height: 50px; background-color: #76ffff;}
.footer{ height: 50px; background-color: #ff7676;}
.main{ background-color: #666;}
.sub{ background-color: #44fa44;}
.extra{ background-color: #3dbdff;}
/*start*/
.main{
    width: 100%;
    float: left;
}
.sub{
    width: 100px;
    float: left;
    margin-left: -100%;
}
.extra{
    width: 200px;
    float: left;
    margin-left: -200px;
}
.container{
    overflow: hidden;
}

結果以下:
011542497982872.png

會發現,main的位置不正確,因此再給container加上 padding: 0 200px 0 100px;

011544456578941.png

雖然 main 的位置正確了,但是 sub 和 extra 位置優勢不對,因此咱們再用上相對定位,爲 subextra 加上以下代碼:

.sub{
    position: relative;;
    left: -100px;
}
.extra{
    position: relative;
    right: -200px;
}

效果就出來了,
011547019548969.png

噢耶,這就是聖盃佈局。若是在聖盃佈局的基礎上,給它一個多餘的標籤,把 mian 包起來,這就是雙飛翼佈局。

雙飛翼佈局

HTML結構:

<div class="header">header</div>
<div class="container">
    <div class="main">
        <div class="main-wrap">main</div>
    </div>
    <div class="sub">sub</div>
    <div class="extra">extra</div>
</div>
<div class="footer">footer</div>

CSS結構:

body{ margin: 0; padding: 0; font-size: 1.5em; font-weight: bold; min-width: 500px;}
.header,.footer{ text-align: center;}
.header{ height: 50px; background-color: #76ffff;}
.footer{ height: 50px; background-color: #ff7676;}
.main{ background-color: #666;}
.sub{ background-color: #44fa44;}
.extra{ background-color: #3dbdff;}
/*start*/
.main{
    width: 100%;
    height: 100px;
    float: left;
}
.sub{
    width: 100px;
    height: 100px;
    float: left;
    margin-left: -100%;
}
.extra{
    width: 200px;
    height: 100px;
    float: left;
    margin-left: -200px;
}
.main-wrap{
    margin: 0 200px 0 100px;
}
.container{
    height: 100px;
    overflow: hidden;
    *zoom: 1;
}

能夠看到,只要爲包住 main-wrap 設置 margin,連相對定位都沒用到,效果就出來了。
011558067042018.png

若是把三欄佈局比做一隻大鳥,能夠把main當作是鳥的身體,sub和extra則是鳥的翅膀。這個佈局的實現思路是,先把最重要的身體部分放好,而後再將翅膀移動到適當的地方。所以請允許我給這個佈局實現取名爲雙飛翼佈局(Flying Swing Layout).
就如上圖中的鳥有各類姿式同樣,利用雙飛翼佈局,咱們也能夠實現各類佈局。這裏有個嘗試頁面,利用雙飛翼,實現了一套柵格化佈局系統。

優勢:

  • 實現了內容與佈局的分離,這是漸進式加強佈局的思想,從內容出發,不考慮佈局。

  • main部分是自適應寬度的,很容易在定寬佈局和流體佈局中切換。

  • 任何一欄均可以是最高欄,不會出問題。

  • 須要的hack很是少(就一個針對ie6的清除浮動hack:_zoom: 1;)
    在瀏覽器上的兼容性很是好,IE5.5以上都支持。

缺點:

  • main須要一個額外的包裹層。

normalize.css和reset.css

normalize 的理念則是儘可能保留瀏覽器的默認樣式,不進行太多的重置。

reset 的目的,是將全部的瀏覽器的自帶樣式重置掉,這樣更易於保持各瀏覽器渲染的一致性。

/* reset */
html,body,h1,h2,h3,h4,h5,h6,div,dl,dt,dd,ul,ol,li,p,blockquote,pre,hr,figure,table,caption,th,td,form,fieldset,legend,input,button,textarea,menu{margin:0;padding:0;}
header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:block;}
table{border-collapse:collapse;border-spacing:0;}
caption,th{text-align:left;font-weight:normal;}
html,body,fieldset,img,iframe,abbr{border:0;}
i,cite,em,var,address,dfn{font-style:normal;}
[hidefocus],summary{outline:0;}
li{list-style:none;}
h1,h2,h3,h4,h5,h6,small{font-size:100%;}
sup,sub{font-size:83%;}
pre,code,kbd,samp{font-family:inherit;}
q:before,q:after{content:none;}
textarea{overflow:auto;resize:none;}
label,summary{cursor:default;}
a,button{cursor:pointer;}
h1,h2,h3,h4,h5,h6,em,strong,b{font-weight:bold;}
del,ins,u,s,a,a:hover{text-decoration:none;}
body,textarea,input,button,select,keygen,legend{font:12px/1.14 arial,\5b8b\4f53;color:#333;outline:0;}
body{background:#fff;}
a,a:hover{color:#333;}

以上reset來自NEC的css reset。

拓展閱讀:
Normalize.css 和 Reset CSS 有什麼本質區別?

IE條件註釋

IE條件註釋是一種特殊的HTML註釋,這種註釋只有IE5.0及以上版本才能理解。好比普通的HTML註釋是:

<!--This is a comment-->
  而只有IE可讀的IE條件註釋是:
<!--[if IE]> <![endif]-->
  「非IE條件註釋」:
<!--[if !IE]>--> non-IE HTML Code <!--<![endif]-->
  「非特定版本IE條件註釋」(不多用到):
<!--[if ! lt IE 7]>
<![IGNORE[--><![IGNORE[]]>
Code for browsers that match the if condition
<!--<![endif]-->

簡而言之,除了「Windows上的IE」以外的全部瀏覽器都會認爲條件註釋只是一段普通的HTML註釋。你不能在CSS代碼中使用條件註釋。IE條件註釋是頗有用的對IE隱藏或者展示特定代碼的方法,比起在CSS中用詭異的_/製造bug,利用IE條件註釋來寫CSS 「hacks」是更合理的方法。通俗點,條件註釋就是一些if判斷,但這些判斷不是在腳本里執行的,而是直接在html代碼裏執行的。

  1. 條件註釋的基本結構和HTML的註釋(<!– –>)是同樣的。所以IE之外的瀏覽器將會把它們看做是普通的註釋而徹底忽略它們。

  2. IE將會根據if條件來判斷是否如解析普通的頁面內容同樣解析條件註釋裏的內容。

  3. 條件註釋使用的是HTML的註釋結構,所以他們只能使用在HTML文件裏,而不能在CSS文件中使用。

從語法上看這是至關合法的普通HTML註釋。任何瀏覽器都會認爲<!–和–>之間的部分是註釋從而忽略它。可是IE也會看到其中[if IE]>,從而開始解釋接下來的代碼直到遇到<![endif]。因此,下面這些代碼不會顯示在任何其餘瀏覽器中面。

經過「比較操做符」能夠更靈活地對IE版本進行控制,用法是在IE前面加上「比較操做符」。合法的操做符以下:

  • lte:就是Less than or equal to的簡寫,也就是小於或等於的意思。

  • lt :就是Less than的簡寫,也就是小於的意思。

  • gte:就是Greater than or equal to的簡寫,也就是大於或等於的意思。

  • gt :就是Greater than的簡寫,也就是大於的意思。

  • ! :就是不等於的意思,跟javascript裏的不等於判斷符相同

<!–[if gt IE 5.5]> / 若是IE版本大於5.5 /
<!–[if lte IE 6]> / 若是IE版本小於等於6 /
<!–[if !IE]> / 若是瀏覽器不是IE /

經常使用的IE條件註釋

<!--[if !IE]>除IE外均可識別<![endif]-->
<!--[if IE]> 全部的IE可識別 <![endif]-->
<!--[if IE 5.0]> 只有IE5.0能夠識別 <![endif]-->
<!--[if IE 5]> 僅IE5.0與IE5.5能夠識別 <![endif]-->
<!--[if gt IE 5.0]> IE5.0以及IE5.0以上版本均可以識別 <![endif]-->
<!--[if IE 6]> 僅IE6可識別 <![endif]-->
<!--[if lt IE 6]> IE6以及IE6如下版本可識別 <![endif]-->
<!--[if gte IE 6]> IE6以及IE6以上版本可識別 <![endif]-->
<!--[if IE 7]> 僅IE7可識別 <![endif]-->
<!--[if lt IE 7]> IE7以及IE7如下版本可識別 <![endif]-->
<!--[if gte IE 7]> IE7以及IE7以上版本可識別 <![endif]-->

水平垂直居中的各類方案

行內元素的水平居中

要實現行內元素的水平居中,只需把行內元素包裹在塊級父層元(<div>、<li>、<p>等)中,而且在父層元素CSS設置以下:

.container{
  text-align: center;
}

demo
居中2.png

塊狀元素的水平居中

要實現塊狀元素(display:block)的水平居中,咱們只須要將它的左右外邊距margin-left和margin-right設置爲auto,便可實現塊狀元素的居中,要水平居中的塊狀元素CSS設置以下:

.container{
    margin: 0 auto;
}

demo
居中1.png

已知高度寬度元素的水平垂直居中

1. 利用絕對定位與負邊距實現。

利用絕對定位,將元素的top和left屬性都設爲50%,再利用margin邊距,將元素回拉它自己高寬的一半,實現垂直居中。核心CSS代碼以下:

.container{
    position: relative;
}
.center{
    position: absolute;
    left: 50%;
    top: 50%;
    margin: -50px 0 0 -50px;
}

demo

2. 利用絕對定位和margin

.container{
  position: relative;
}
.center{
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
}

demo

居中3.png

未知高度和寬度元素的水平垂直居中

1. 被居中的元素是inline或者inline-block元素

能夠巧妙的將父級容器設置爲display:table-cell,配合text-align:centervertical-align:middle便可以實現水平垂直居中。

.container{
  width: 600px;
  height: 600px;
  background: #eee;
  display: table-cell;
  text-align: center;
  vertical-align: middle;
}
.center{
  background: blue; 
}

demo

2. 利用CSS3的transform的屬性

利用C3的transform,能夠輕鬆的在未知元素的高寬的狀況下實現元素的垂直居中。

.container{
  width: 100%;
  height: 400px;
  background: #eee;
  position: relative;
}
.center{
  background: blue;
  position:absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

demo

3. flex佈局

使用flex佈局,無需絕對定位等改變佈局的操做,能夠輕鬆實現元素的水平垂直居中。

.container{
  width: 100%;
  height: 400px;
  background: #eee;
  /* flex 佈局解決水平居中 */
  display: flex;
  justify-content: center;
  align-items: center;
}
.center{
  width: 100px;
  height: 100px;
  background: blue;
  text-align: center;
}

demo
居中4.png

notes:CSS3的transform和flex有兼容性問題。ie11+才支持flexbox佈局。
相關文章
相關標籤/搜索