那些年忽略的CSS

碎碎念

CSS的學習入門很容易,只要1年甚至半年的時候,咱們就能根據設計圖迅速切出頁面,能熟練使用些CSS hack,這個階段咱們的成長很快,天天都能汲取新知識。這其實是CSS很是初級的階段,也是廣大頁面仔們(包括我本人😳)最爲浮躁,最自覺得是,最以爲CSS不過如此的階段。因此咱們要增長學習的深度,深刻掌握細節和原理,當咱們對CSS的底層表現有必定的理解與認識的時候,遇到一些看似奇怪的問題,能夠輕鬆搞定~css

佈局

咱們在研究佈局以前,首先須要瞭解幾個很重要的概念和屬性:html

文檔流

文檔流指的是元素排版佈局過程當中,元素會自動從左往右,從上往下的流式排列。並最終窗體自上而下分紅一行行,並在每行中從左至右的順序排放元素。HTML中所有元素都是盒模型,盒模型佔用必定的空間,依次排放在HTML中,造成了文檔流。css3

floatposition:absolute|fixed是脫離文檔流的。脫離文檔流是指,這個標籤脫離了文檔流的管理。不受文檔流的佈局約束了,而且更重要的一點是,當一個元素脫離文檔流後,這個標籤在原文檔流中所佔的空間也被清除掉了,依然在文檔流中的其餘元素將忽略該元素並填補其原先的空間。瀏覽器

塊級元素

  • 每一個塊級元素都是獨自佔一行,其後的元素也只能另起一行,並不能兩個元素共用一行。
  • 元素的高度、寬度、行高和頂底邊距都是能夠設置的。
  • 元素的寬度若是不設置的話,默認爲父元素的寬度
  • 常見的塊級元素:<div>、<p>、<h1>...<h6>、<ol>、<ul>、<dl>、<table>、<address>、<blockquote> 、<form>

行級元素

  • 能夠和其餘元素處於一行,不用必須另起一行。
  • 元素的高度、寬度及頂部和底部邊距不可設置。
  • 元素的寬度就是它包含的文字、圖片的寬度,不可改變。
  • 常見的行級元素:<span>、<a>、<strong>、<em>

行級元素與塊級元素的轉換

  • 能夠在css樣式中用display:inline將塊級元素設爲行級元素
  • 一樣,也能夠用display:block將行級元素設爲塊級元素

display

是CSS中最重要的用於控制佈局的屬性,每一個元素都有一個默認的值,這與元素的類型有關。對於大多數元素它們的默認值一般是block(塊級元素)或inline(行內元素)。app

display:nonevisibility屬性不同。display:none的元素不會佔據它原本應該顯示的空間,可是設置成visibility: hidden;還會佔據空間。ide

外邊距摺疊

若是兩個相鄰元素都在其上設置外邊距,而且兩個外邊距接觸,則兩個外邊距中的較大者保留,較小的一個消失佈局

定位(position)

  • static:默認值。元素框正常生成。塊級元素生成一個矩形框,做爲文檔流的一部分;行內元素則會建立一個或多個行框,置於其父元素中。學習

  • relative:元素框相對於以前正常文檔流中的位置發生偏移,而且原先的位置仍然被佔據。發生偏移的時候,可能會覆蓋其餘元素。flex

這是一個設置了 position: relative; 的div
這是一個設置了position:relative; top:-20px; left:20px; width: 500px;的div
  • absolute:元素框再也不佔有文檔流位置,而且相對於包含塊進行偏移(所謂的包含塊就是最近一級外層元素position不爲static的元素),找不到符合條件的父(祖先)節點,則相對瀏覽器窗口進行定位;沒有設置TRBL,則默認浮動,默認浮動在父級節點的content-box區。
  • fixed:屬性的值爲fixed的元素會相對於視窗來定位,即使頁面滾動,它仍是會停留在相同的位置。一個固定定位元素不會保留它本來在頁面應有的空隙(即脫離文檔流),可是移動設備兼容性很差。
  • sticky:(這是css3新增的屬性值)粘性定位,官方的介紹比較簡單。其實,它就至關於relative和fixed混合。最初會被看成是relative,相對於原來的位置進行偏移;一旦超過必定閾值以後,會被當成fixed定位,相對於視口進行定位。

浮動(float)

最初,設計浮動時,其實並非爲了佈局的,而是爲了實現文字環繞的特效。相似於ps中的圖層同樣,浮動的元素會在浮動層上面進行排布,而在原先文檔流中的元素位置,會被以某種方式進行刪除,可是仍是會影響佈局,因此要記得清除浮動。spa

浮動爲何會被使用在佈局中呢?由於設置浮動後的元素會造成BFC(使得內部的元素不會被外部所幹擾),而且元素的寬度也再也不自適應父元素寬度,而是適應自身內容。這樣就能夠,輕鬆地實現多欄佈局的效果。浮動一般用於建立多個列布局,而且因爲它有良好的瀏覽器兼容性,已經被使用了至關一段時間。

flex佈局

彈性佈局:用來爲盒狀模型提供最大的靈活性,採用 Flex 佈局的元素,稱爲 Flex 容器(flex container)。它的全部子元素自動成爲容器成員,稱爲 Flex 項目(flex item)。

容器默認存在兩根軸:水平的主軸(main axis)和垂直的交叉軸(cross axis)。主軸的開始位置(與邊框的交叉點)叫作main start,結束位置叫作main end;交叉軸的開始位置叫作cross start,結束位置叫作cross end。

項目(flex item)默認沿主軸排列。單個item佔據的主軸空間叫作main size,佔據的交叉軸空間叫作cross size。

container(容器)的屬性

flex-direction

屬性決定主軸的方向(即item的排列方向)

  • row(默認值):主軸爲水平方向,起點在左端。
  • row-reverse:主軸爲水平方向,起點在右端。
  • column:主軸爲垂直方向,起點在上沿。
  • column-reverse:主軸爲垂直方向,起點在下沿。

flex-wrap

默認狀況下,項目(item)都排在一條線(又稱"軸線")上。flex-wrap屬性定義,若是一條軸線排不下,如何換行。

  • nowrap(默認):不換行。

  • wrap:換行,第一行在上方。

  • wrap-reverse:換行,第一行在下方。

flex-flow

flex-flow屬性是flex-direction屬性和flex-wrap屬性的簡寫形式,默認值爲row nowrap

justify-content

justify-content屬性定義了項目在主軸上的對齊方式。

.box {
  justify-content: flex-start | flex-end | center | space-between | space-around;
}
複製代碼
  • flex-start(默認值):左對齊
  • flex-end:右對齊
  • center: 居中
  • space-between:兩端對齊,項目之間的間隔都相等
  • space-around:每一個項目兩側的間隔相等。因此,項目之間的間隔比項目與邊框的間隔大一倍。

align-items

align-items屬性定義項目在交叉軸上如何對齊。

.box {
  align-items: flex-start | flex-end | center | baseline | stretch;
}
複製代碼

具體的對齊方式與交叉軸的方向有關,下面假設交叉軸從上到下。

  • flex-start:交叉軸的起點對齊。
  • flex-end:交叉軸的終點對齊。
  • center:交叉軸的中點對齊。
  • baseline: 項目的第一行文字的基線對齊。
  • stretch(默認值):若是項目未設置高度或設爲auto,將佔滿整個容器的高度。

align-content

align-content屬性定義了多根軸線的對齊方式。若是項目只有一根軸線,該屬性不起做用

.box {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
複製代碼
  • flex-start:元素位於容器的開頭。各行向彈性盒容器的起始位置堆疊。彈性盒容器中第一行的側軸起始邊界緊靠住該彈性盒容器的側軸起始邊界,以後的每一行都緊靠住前面一行。
  • flex-end:元素位於容器的結尾。各行向彈性盒容器的結束位置堆疊。彈性盒容器中最後一行的側軸起結束界緊靠住該彈性盒容器的側軸結束邊界,以後的每一行都緊靠住前面一行。
  • center:元素位於容器的中心。各行向彈性盒容器的中間位置堆疊。各行兩兩緊靠住同時在彈性盒容器中居中對齊,保持彈性盒容器的側軸起始內容邊界和第一行之間的距離與該容器的側軸結束內容邊界與第最後一行之間的距離相等。(若是剩下的空間是負數,則各行會向兩個方向溢出的相等距離。)
  • space-between:元素位於各行之間留有空白的容器內。各行在彈性盒容器中平均分佈。若是剩餘的空間是負數或彈性盒容器中只有一行,該值等效於'flex-start'。在其它狀況下,第一行的側軸起始邊界緊靠住彈性盒容器的側軸起始內容邊界,最後一行的側軸結束邊界緊靠住彈性盒容器的側軸結束內容邊界,剩餘的行則按必定方式在彈性盒窗口中排列,以保持兩兩之間的空間相等。
  • space-around:元素位於各行以前、之間、以後都留有空白的容器內。各行在彈性盒容器中平均分佈,兩端保留子元素與子元素之間間距大小的一半。若是剩餘的空間是負數或彈性盒容器中只有一行,該值等效於'center'。在其它狀況下,各行會按必定方式在彈性盒容器中排列,以保持兩兩之間的空間相等,同時第一行前面及最後一行後面的空間是其餘空間的一半。
  • stretch(默認值):元素被拉伸以適應容器。各行將會伸展以佔用剩餘的空間。若是剩餘的空間是負數,該值等效於'flex-start'。在其它狀況下,剩餘空間被全部行平分,以擴大它們的側軸尺寸。

item(項目)的屬性

order

order屬性定義項目的排列順序。數值越小,排列越靠前,默認爲0。

flex-grow

flex-grow屬性定義項目的放大比例,默認爲0,即若是存在剩餘空間,也不放大 若是全部項目的flex-grow屬性都爲1,則它們將等分剩餘空間(若是有的話)。若是一個項目的flex-grow屬性爲2,其餘項目都爲1,則前者佔據的剩餘空間將比其餘項多一倍。

flex-shrink

flex-shrink屬性定義了項目的縮小比例,默認爲1,即若是空間不足,該項目將縮小。 若是全部項目的flex-shrink屬性都爲1,當空間不足時,都將等比例縮小。若是一個項目的flex-shrink屬性爲0,其餘項目都爲1,則空間不足時,前者不縮小。負值對該屬性無效

flex-basis

flex-basis屬性用於設置或檢索彈性盒伸縮基準值。定義了在分配多餘空間以前,項目佔據的主軸空間(main size)。瀏覽器根據這個屬性,計算主軸是否有多餘空間。它的默認值爲auto,即項目的原本大小。

它能夠設爲一個長度單位或者一個百分比,規定靈活項目的初始長度。

div:nth-of-type(2) {
    flex-basis: 80px;
}
複製代碼

flex

flex屬性是flex-grow, flex-shrinkflex-basis的簡寫,默認值爲0 1 auto。後兩個屬性可選。 該屬性有兩個快捷值:auto(1 1 auto) 和 none (0 0 auto)。

建議優先使用這個屬性,而不是單獨寫三個分離的屬性,由於瀏覽器會推算相關值。

align-self

align-self屬性容許單個項目有與其餘項目不同的對齊方式,可覆蓋align-items屬性。默認值爲auto,表示繼承父元素的align-items屬性,若是沒有父元素,則等同於stretch

該屬性可能取6個值,除了auto,其餘都與align-items屬性徹底一致。

  • auto:默認值。元素繼承了它的父容器的 align-items 屬性。若是沒有父容器則爲 "stretch"。
  • stretch:元素被拉伸以適應容器。若是指定側軸大小的屬性值爲'auto',則其值會使項目的邊距盒的尺寸儘量接近所在行的尺寸,但同時會遵守'min/max-width/height'屬性的限制。
  • center:元素位於容器的中心。彈性盒子元素在該行的側軸(縱軸)上居中放置。(若是該行的尺寸小於彈性盒子元素的尺寸,則會向兩個方向溢出相同的長度)。
  • flex-start:元素位於容器的開頭。彈性盒子元素的側軸(縱軸)起始位置的邊界緊靠住該行的側軸起始邊界。
  • flex-end:元素位於容器的結尾。彈性盒子元素的側軸(縱軸)起始位置的邊界緊靠住該行的側軸結束邊界。
  • baseline:元素位於容器的基線上。如彈性盒子元素的行內軸與側軸爲同一條,則該值與'flex-start'等效。其它狀況下,該值將參與基線對齊。

佈局技巧

單列布局

常見的這兩種單列布局的特色都是定寬水平居中的,設置width或max-width和margin:auto便可;

二列&三列布局

二列布局的特徵是側邊欄固定寬度,主欄自適應寬度。

三列布局的特徵是左右兩側固定寬度,中間列自適應寬度。

1.float + margin

將兩個側邊欄分別向左向右浮動,經過設置中間的主欄的margin爲它們留出空間,造成三列布局

.left{
    float: left;
    width: 200px;
}
.right{
    float: right;
    width: 200px;
}
.main{
    margin-left: 220px; /*預留出定寬兩欄的空間*/
    margin-right: 220px;
}
複製代碼

只設置一個浮動便可獲得兩列布局

2.position + margin

經過將兩個側邊欄的position設置爲absolute,而後將左邊欄的left設置爲0,右邊欄的right設置爲0,主欄設置margin爲邊欄留出空間,便可獲得三列布局。

.left{
    position: absolute;
    left: 0;
    width: 200px;
}
.right{
    position: absolute;
    right: 0;
    width: 200px;
}
.main{
    margin-left: 220px;
    margin-right: 220px;
}
複製代碼

一樣,將定位元素改成一個能夠獲得兩列布局。

聖盃佈局

  • 三者都設置向左浮動。
  • 設置main寬度爲100%,設置兩側欄的寬度。
  • 設置負邊距,left設置負左邊距爲100%,right設置負左邊距爲負的自身寬度。
  • 設置main的padding值給左右兩個子面板留出空間。
  • 設置兩個子面板爲相對定位,左邊欄的left值爲負的自身寬度,右邊欄的right值爲負的自身寬度。
<div class="container">         
    <div class="main"></div>        
    <div class="left"></div>        
    <div class="right"></div>  
</div>
複製代碼
.main{
    float: left;       
    width: 100%;   
}
.left{     
    float: left;        
    width: 200px;        
    margin-left: -100%;               
    position: relative;  
    left: -200px; 
}
.right{
    float: left;        
    width: 300px;        
    margin-left: -300px; 
    position: relative; 
    right: -300px;  
}
.container {        
    padding: 0 300px 0 200px;   
}
複製代碼

二列的實現方法:

若是是左邊帶有側欄的二列布局,則去掉right,不設置主面板的padding-right值。

雙飛翼佈局

雙飛翼佈局和聖盃佈局的思想有些類似,都利用了浮動和負邊距,但雙飛翼佈局在主欄外加了一層div並設置margin用來容納側欄,兩側欄的負邊距都是相對於外層div而言,main的margin值變化便不會影響兩個側欄,這樣就省略了將側欄拉到主欄那一行後進行的relative定位(由於雙飛翼佈局留白就在父元素的內容區,而聖盃佈局的留白在父元素內容區以外)。

<div class="wrapper">
      <div class="main"></div>
</div>
<div class="left"></div>        
<div class="right"></div>
複製代碼
.wrapper {        
    float: left;       
    width: 100%;
}  
.main {    
    margin: 0 300px 0 200px;
}
.left {       
    float: left;        
    width: 200px;        
    margin-left: -100%;   
}   
.right {        
    float: left;        
    width: 300px;        
    margin-left: -300px; 
 }
複製代碼
  • 聖盃採用的是padding,而雙飛翼採用的margin,解決了聖盃佈局main的最小寬度不能小於左側欄的缺點。 雙飛翼佈局不用設置相對佈局,以及對應的left和right值。簡單提及來就是「雙飛翼佈局比聖盃佈局多建立了一個div,但不用相對佈局了」。
  • 若是引入相對佈局,能夠實現三欄佈局的各類組合,例如對右側欄設置position: relative; left: 200px;,能夠實現left+right+main的佈局。

二列的實現方法:

若是是左邊帶有側欄的二欄佈局,則去掉右側欄,不要設置main-wrap的margin-right值,其餘操做相同。反之亦然。

flex佈局

Flex 是 Flexible Box 的縮寫,意爲「彈性佈局」,用來爲盒狀模型提供最大的靈活性。除了在PC端兼容性較差,沒有太大的缺陷,多用於移動端佈局。

.layout {
    display: flex;
}
.main {
    flex: 1;
}
.aside {
    width: 200px;
}
複製代碼

經常使用居中方法

margin: auto;

這是一個設置了 width: 600px; margin: 0 auto; 的div

這是你們很常見的居中方式,元素會佔據你所指定的寬度,而後剩餘的寬度會一分爲二成爲左右外邊距。不過問題是,當瀏覽器窗口比元素的寬度還要窄時,瀏覽器會顯示水平滾動條。

在這種狀況下使用 max-width 替代 width 可使瀏覽器更好地處理小窗口的狀況。這點在移動設備上顯得尤其重要~

這是一個設置了 max-width: 600px; margin: 0 auto; 的div

調整窗口大小看一下二者的區別吧 居中在佈局中很常見,咱們假設DOM文檔結構以下,子元素要在父元素中居中:

<div class="parent">
    <div class="child"></div>
</div>
複製代碼

水平居中

  • 子元素爲行內元素:對父元素設置text-align:center;
  • 子元素爲定寬塊狀元素: 設置左右margin值爲auto;
  • 子元素爲不定寬塊狀元素: 設置子元素爲display:inline,而後在父元素上設置text-align:center;
  • 通用方案: flex佈局,對父元素設置display:flex;justify-content:center;

垂直居中

垂直居中對於子元素是單行內聯文本、多行內聯文本以及塊狀元素採用的方案是不一樣的。

  • 父元素必定,子元素爲單行內聯文本:設置父元素的height等於行高line-height
  • 父元素必定,子元素爲多行內聯文本:設置父元素的display:table-cell或inline-block,再設置vertical-align:middle;
  • 塊狀元素:設置子元素position:absolute 並設置top、bottom爲0,父元素要設置定位爲static之外的值,margin:auto;
  • 通用方案: flex佈局,給父元素設置{display:flex; align-items:center;}。
相關文章
相關標籤/搜索