【學習筆記】CSS 基礎

初識 CSS

  • CSS 全稱爲 cascading style sheet 層疊樣式表,它的主要做用是爲 HTML 標籤添加各類各樣的樣式和修飾效果

HTML 頁面引入 CSS 的方式

  • 行間樣式:直接寫在 HTML 標籤裏的 style 屬性
  • 頁面級 CSS:在 head 標籤裏面添加一個 style 標籤
<style type=」text/css」></style>
複製代碼
  • 外聯 CSS 文件:在外建立一個 .css 後綴的文件,在 head 標籤裏面加上個 link 標籤
    • link 標籤裏的 href 屬性上寫上 CSS 文件地址,最好用相對地址的形式link 加載不會阻塞 HTML 的加載,HTML 和 css 屬於異步加載
    • 注意:link 標籤引入和 style 標籤修改樣式之間並無什麼優先級,誰寫在前面誰就先執行,寫在後面的 CSS 樣式會覆蓋掉前面的 CSS 樣式。有時link 寫在上面可是 link 還沒加載進來因此先運行了後面的 style,這種問題多是網速致使的並非兩者自己擁有優先級的問題
      <link rel="stylesheet" href="">
      複製代碼
  • import 方式引入(已經棄用):在 head 標籤裏面寫個 style 標籤,在第一行寫上 @import url(); url 裏寫 CSS 文件的地址,可加引號也可不加引號,這種引入方式有幾種缺點致使它如今被廢棄使用
    • 必須寫在第一行,如有多個則一塊兒寫在最前面
    • IE6 的環境下只能使用最多 31 次,這個數字聽說是阿里的開發人員一點一點測試出來的(待考究)
    • 程序讀到 import 時會忽略掉 import,等 HTML 裏的全部內容包括圖片在內的全部資源全都加載完後才加載 import 的 CSS 文件,即 import 引入的 CSS 文件和 HTML 的加載是同步進行的
  • link 和 import 的區別
    • link 是 XHTML 標籤,除了加載 CSS 外還可定義 RSS 等其餘事務;@import 屬於 CSS 範疇,只能加載 CSS
    • link 引用 CSS 時在頁面載入時同時加載;@import 須要頁面網頁徹底載入之後加載
    • link 是 XHTML 標籤,無兼容問題;@import 是在 CSS2.1 提出的,低版本的瀏覽器不支持
    • link 支持使用 JS 控制 DOM 去改變樣式;而 @import 不支持
    • link 的樣式權重高於 @import 的權重

CSS 選擇器

  • CSS 選擇器的做用是讓咱們能找到想要修改樣式的元素,而後爲其修改樣式php

  • id 選擇器
    該 id 是惟一標識,一個元素只能有一個 id,一個 id 也只能給一個元素。而後在 CSS 文件中,經過 #id {} 的方式選擇到添加 id 的那個元素css

  • class 類選擇器
    在元素的屬性中寫上 class 屬性,該屬性是爲這個元素添加一個類名,每個元素可有多個類名,同一個類名也可賦給不少個元素,在 CSS 文件中,經過 .class {} 的方式來選擇出添加了類名的元素html

  • 標籤選擇器
    div {},只要是 div 的標籤就會被選擇出來css3

  • 通配符選擇器
    * {},全部的標籤都會被選擇出來加上樣式,body 標籤頁包含在內web

  • 父子選擇器(派生選擇器)chrome

    • 如 div p {},給 div 下的 p 加樣式 這時的 p 的權重值是加和的結果,id 和 class 也是可使用父子選擇器
    • 在實際開發中因要注意瀏覽器尋找元素時的耗能,通常父子選擇器不超過 4 層,如:div p strong em span,解讀順序是從選擇器的右邊到左邊讀取路徑鏈越短效率越高,層級通常最好不超過四層,這是爲何呢?
      • 如果從左往右尋找,每找到一個父級標籤都要把它下面全部標籤都遍歷一遍,看看有沒有下一個標籤,上面那個選擇器示例中瀏覽器會先找到 div 標籤,而後把 div 下面全部的子元素都遍歷一遍後找到 strong 這個標籤,而後再把 strong 標籤下的全部元素遍歷一遍找到 em 這個標籤,以此類推,十分消耗性能且速度很是慢
      • 若從右往左,那瀏覽器只須要先找到 span 標籤,而後從 span 這個節點向上尋找,只要找到 em 就能夠中止尋找,以此類推,沒必要遍歷全部節點且需遍歷的點很是的少,這樣的好處顯而易見,速度很是快並且不耗性能
  • 直接子元素選擇器
    如 div > strong瀏覽器

    // 正確
      <div>
      <strong></strong>
      </div>
    
      // 錯誤
      <div> <em> <strong></strong> </em> </div>
    複製代碼
  • 並列選擇器
    可以使用相似 div.select {} 來選擇,這種方式是隻有 div 和 .select 同時做用在一個標籤上時纔會被選出來,書寫時標籤名放在前面,其餘的放在後面markdown

    <div class=」select」></div>
    複製代碼
  • 分組選擇器
    如 div, p, em, strong {} 這樣的寫法,能夠把這些標籤都選擇出來加上一樣的樣式,中間是用逗號鏈接的app

  • 僞類選擇器異步

    • 用於當已有元素處於某個狀態時爲其添加對應的樣式,這個狀態是根據用戶行爲而動態變化的,如當用戶懸停在指定的元素時,能夠經過 :hover 來描述這個元素的狀態
    • 雖然它和普通的 CSS 類類似,能夠爲已有的元素添加樣式,但它只有處於 DOM 樹沒法描述的狀態下才能爲元素添加樣式,因此將其稱爲僞類
    • 常見的僞類
      • :link,設置 a 標籤在未被訪問前的 CSS 樣式
      • :visited,設置 a 標籤在其連接地址已被訪問過的 CSS 樣式
      • :hover,設置元素在其鼠標懸停時的 CSS 樣式
      • :active,設置元素在被用戶激活(在鼠標點擊與釋放間發生的事件)時的 CSS 樣式

僞類.png

  • 僞元素選擇器
    • 用於建立一些不在文檔樹中的元素併爲其添加樣式,如可經過 :before 來在一個元素前增長一些文本併爲這些文本添加樣式
    • 雖然用戶可看到這些文本,可是這些文本實際上不在文檔樹中(某些僞類或僞元素仍然處於試驗階段,在使用前建議先在 Can I Use 等網站查一查其瀏覽器兼容性,處於試驗階段的僞類或僞元素會在標題中標註)

僞元素.png

  • 屬性選擇器
    屬性選擇器搭配較自由,既可根據屬性來選也可根據屬性值來選,還可根據部分屬性值來選,具體規則以下

屬性選擇器.png

注意
一、通常不給標籤加 id,而是經過添加 class 類名來選擇的,由於 id 表明惟一標示,通常用 id 來作標記,後臺的 php 會根據提取出來 id 換成他們的標記,所以可能會致使選擇器選擇不出來想要的標籤
二、寫類名時必定要注意語義化,要符合語義化標準,要用英文單詞去命名,而不是用看不懂的abc之類的類名

選擇器的權重及優先級

  • 權重值
    • !important:無窮大,在數學中【無窮大+1】依然是無窮大,但在 CSS 選擇器的權重值裏【無窮大+1 > 無窮大】
    • 行間(內聯)樣式:1000
    • id:100
    • class、屬性、僞類:10
    • 標籤、僞元素:1
    • 通配符:0
  • 優先級
    • 元素聲明的樣式權重高於瀏覽器的默認樣式
    • 瀏覽器默認樣式的權重高於繼承父級元素的樣式
    • !important > 內聯 > ID 選擇器 > 類選擇器(屬性、僞類) > 標籤選擇器(僞元素) > 通配符

選擇器的執行效率

  • 選擇器的執行效率(由高到低):id(#myid) > 類(.myclassname) > 標籤(div, h1, p) > 相鄰(h1 + p) > 子元素(ul > li) > 後代(li a) > 通配符(*) > 屬性(a[rel="external"]) > 僞類(a: hover, li: nth-child)
  • CSS 選擇器對性能的影響源於瀏覽器匹配選擇器和文檔元素所消耗的時間,因此優化選擇器的原則是應儘可能避免使用消耗更多匹配時間的選擇器

單位

  • 絕對單位,如:px、in、pt、cm、mm
    • px:pixels(像素)的縮寫,用於屏幕顯示器上。傳統上一個像素對應屏幕上的一個點,而對於高清屏則更多。任何現代顯示屏都是由成千上萬的像素組成,所以可使用像素來定義長度。CSS 將光柵圖像如照片等的顯示方式定義爲默認每一個圖像大小爲 1px,一個 「600x400」 解析度的照片的長寬分別爲 「600px」 和 「400px」,因此照片自己像素並不會與顯示裝置像素(可能很是小)一致,而是與單位 px 一致,如此就能夠將圖像完整的與網頁其餘元素排列起來
  • 相對單位,如:%、em、rem、vw、vh、vmin、vmax
    • %:子元素的百分比相對的數值是父級裏對應屬性的值,如父級的高度是 100px,子級的 50% 就是 50px
    • em:須有個參照值,該參照值不是固定的,而是不一樣屬性有不一樣的參照值
      • font-size:em 的計算方式是相對於父元素的字體大小,1em 等於父元素設置的字體大小,若父元素沒有設置字體大小則繼續往上查找,若都沒有設置大小則使用瀏覽器默認的字體大小
      • 其餘屬性(border、width、height、padding、margin、line-height):em 的計算方式是參照該元素的字體大小,1em 等於該元素設置的字體大小,同理若該元素沒有設置則一直向上查找,若都沒有設置則使用瀏覽器默認的字體大小
    • rem:rem 的參照物是固定的,相對根元素 html 的 font-size 來計算,rem 的 r 就是 root,CSS3新加屬性,有些瀏覽器不兼容,哪怕在移動端安卓 4.3 如下也是不兼容,不過長遠來講這也是必備的
    • vw/vh/vmin/vmax
      • 基於視窗大小(瀏覽器用來顯示內容的區域大小)來計算的
      • 網頁中不少時候須要用到滿屏或屏幕大小的一半等,尤爲是移動端,屏幕大小各式各樣,這四個就很適合
      • vw:基於視窗的寬度計算,1vw 等於視窗寬度的百分之一
      • vh:基於視窗的高度計算,1vh 等於視窗高度的百分之一
      • vmin:基於 vw 和 vh 中的最小值來計算,1vmin 等於最小值的百分之一
      • vmin:基於 vw 和 vh 中的最小值來計算,1vmin 等於最小值的百分之一

chrome 瀏覽器的最小字體是 12px,就算設置爲 10px 也會渲染成 12px

盒模型

概念

  • 當對一個文檔進行佈局(layout)時,瀏覽器的渲染引擎會根據標準之一的 CSS 基礎框盒模型(CSS basic box model),將每一個元素都描述爲一個個矩形的盒子(box),這些盒子經過一個模型來描述其佔用空間,CSS 決定這些盒子的大小、位置以及屬性(例如顏色、背 景、邊框尺寸...)
  • 一個盒子由 4 個部分組成:外邊距(margin)、邊框(border)、內邊距(padding)、內容區(content)
    • content 不是由屬性構成,由咱們寫的內容和 width、height 屬性構成
    • margin 它設置是這個元素距離外面靠近它的元素或瀏覽器邊框的距離,這是一個複合屬性:margin-top、margin-right、margin-bottom、margin-left 組成,也可分開寫設置每一個屬性的屬性值,該複合值有 4 種寫法
      • 4個值:按照上、右、下、左的順序
      • 3個值:按照上、左右、下的順序
      • 2個值:按照上下、左右的順序
      • 1個值:四個方向是同個值
    • padding 也是複合屬性(參考 margin)

注意:body 元素有個默認的 8px 的 margin,同時還發現標籤默認也有一些 margin。由於這些樣式可能對佈局形成影響,通常須要去掉這些默認樣式:在開發中通常使用 *{} 通配符選擇器來初始化樣式,由於通配符的優先級最低,後面若想要加樣式,隨便一個樣式設定都會高於通配符選擇器,但若沒有設置的話瀏覽器就會將默認樣式爲設置的初始化樣式

盒模型.png

盒子計算

  • CSS 的盒子模型有兩種:標準的 W3C 盒子模型模型、怪異(IE)盒子模型
  • 標準的 W3C 盒子模型模型
    • 在 W3C 標準下定義元素的 width 值即爲盒模型中的 content 的寬度值,height 值即爲盒模型中的 content 的高度值,所以標準盒模型下:
      width = content 的寬度
      height = content 的高度
      盒子實際佔位寬度 = width(內容寬度) + margin-left + border-left + padding-left + padding-right + border-right + margin-right
      盒子實際佔位高度 = height(內容高度) + margin-top + border-top + padding-top + padding-bottom + border-bottom + margin-bottom
      複製代碼

標準盒子模型.png

  • 怪異盒子模型
    • 而 IE 怪異盒模型(IE8 如下),width 的寬度並非 content 的寬度,而是 border-left + padding-left + content 的寬度值 + padding-right + border-right,height 同理
      width = border-left + padding-left + content 的寬度值 + padding-right + border-right
      height = border-left + padding-left + content 的寬度值 + padding-right + border-right
      盒子實際佔位寬度 = margin-left + content + margin-right
      盒子實際佔位高度 = margin-top + content + margin-top
      複製代碼

怪異盒子模型.png

盒模型的轉換方式

  • 現代瀏覽器默認使用 W3C 的標準盒模型,但有時可能須要怪異盒模型,則可以使用 W3C 在 CSS3 中加入的 box- sizing
box-sizing: content-box // 標準盒模型,默認值
box-sizing: border-box // 怪異盒模型
複製代碼

注意:
一、只有 firefox 瀏覽器支持 padding-box 屬性值
二、IE 瀏覽器在 getComputedStyle 獲得 width/height 是按照標準模式計算的,而不論 box-sizing 的取值

格式化上下文

  • 默認狀況下盒子按照元素在 HTML 中的前後位置從左至右自上而下一個接着一個排列擺放
  • 不一樣的盒子使用的是不一樣的格式化上下文(formatting context)來佈局,每一個格式化上下文都擁有一套不一樣的渲染規則,它決定了其子元素將如何定以及和其餘元素的關係和相互做用

BFC

  • 塊級格式化上下文(Block Format Context)
  • 在 W3C 規範中對 BFC 的定義
    • 浮動元素、絕對定位元素、非塊級盒子的塊級容器(如 inline-block、table-cells 和 table-captions)、overflow 值不爲 visiable 的塊級盒子,都會爲他們的內容建立新的 BFC(塊級格式上下文)
    • 在 BFC 中,盒子從頂端開始垂直地一個接一個地排列,兩個盒子之間的垂直的間隙是由他們的 margin 值決定,兩個相鄰的塊級盒子的垂直 margin 會產生合併
    • 在 BFC 中每一個盒子的左外邊緣 margin-left 會觸碰到容器的左邊緣border-left,相反則觸碰到右邊緣
  • MDN 對 BFC 的定義:塊格式化上下文(Block Formatting Context,BFC)是 Web 頁面可視化 CSS 渲染的一部分,是佈局過程當中生成塊級盒子的區域,也是浮動元素與其餘元素的交互限定區域
  • 簡而言之,BFC 是一塊獨立的渲染區域,讓處於 BFC 內部的元素與外部的元素互相隔離,該區域內全部元素的佈局不會影響到區域外元素的佈局。它決定了其子元素 將如何定位以及和其餘元素的關係和相互做用,這個渲染區域只對塊級元素起做用
  • BFC 渲染規則
    • 塊級盒會在垂直方向一個接一個地放置,每一個盒子水平佔滿整個容器空間
    • 塊級盒的垂直方向距離由上下 margin 決定,同屬於一個 BFC 中的兩個或兩個以上塊級盒相接的 margin 會發生重疊,都爲正值則取最值、一正一負則取相加後的值、都爲負則取絕對值大的那個,不一樣 BFC 垂直方向 margin 不合並
    • 計算 BFC 的高度時浮動元素也參與計算
  • 觸發 BFC
    • 根元素(html 元素)或包含根元素的元素
    • 浮動元素(float 的屬性不爲 none)
    • 絕對定位元素(position 爲 absolute 或 fixed)
    • overflow 值不爲 visible 的塊元素(hidden、auto、scroll)
    • 行內塊元素(元素的 display 爲 inline-block)
    • 表格單元格(元素的 display爲 table-cell,HTML 表格單元格默認爲該值)
    • 表格標題(元素的 display 爲 table-caption,HTML 表格標題默認爲該值)
    • 彈性盒子元素(display 爲 flex 或 inline-flex)
    • 網格元素(display 爲 grid 或 inline-grid)
    • display 值爲 flow-root 的元素
    • contain 值爲 layout、content或 strict 的元素

塊格式化上下文

  • BFC 的做用
    • margin 合併現象
      如兩個 div,分別給它們加上 margin-bottom 和 margin-top 爲 10 px 的樣式,這兩個 div 上下之間的距離並非相加的 20px,而是隻有 10px!

      <div class=」top」>top</div>
      <div class=」bottom」>bottom</div>
      複製代碼

      解決:給每一個 div 分別加上一個父級包裹層,而後給父級包裹層都加上 overflow:hidden; 經過父級 div 來觸發 BFC 就能夠解決 margin 合併的問題

      <div class=」wrapper」>
          <div class=」top」>top</div>
      </div>
      <div class=」wrapper」> <div class=」bottom」>bottom</div> </div>
      複製代碼
    • margin 塌陷現象
      當給如示例中的結構的兩個 div 分別設置 margin-top 時,這個 bug 就會出現了

      <div class=」wrapper」>
       <div class=」content」></div>
      </div>
      .wrapper {
         width: 100px;
         height: 100px;
         margin-top: 100px;
         margin-left: 100px;
         background-color:yellow;
      }
      .content {
         width: 50px;
         height: 50px;
         margin-top: 50px;
         margin-left: 50px;
         background-color: red;
      }
      複製代碼

      這段代碼的原意是想要一個 100100 大小的父級 div,裏面有一個 5050 大小的子級 div,讓這個 div 在父級 div 的右下角,同時父 div 距離瀏覽器的邊框有 100px 的距離

      margin塌陷_1.png
      實際的結果是子級 div 的 margin-top 的效果並非距離父級 div 50px,而是子級的 div 距離瀏覽器邊框的距離是 50px,因爲自己父級 div 有一個 margin-top 的值,因此就致使了子級的 margin-top 的效果並無顯現出來,再改變一會兒級 div 的 margin-top 的值爲 200px,子級 div 不只沒有距離父級 div 有一段距離,反而帶動了父級 div 一塊兒向下移動了!這就是 margin 塌陷現象 margin塌陷_2.png

      解決:
      一、利用 border 來觸發 BFC 的效果:margin 塌陷問題很容易讓人聯想到子 div 之因此沒有相對父級移動是由於看不到父級的邊界,只能看到瀏覽器的邊界,給父級加一個子級能看到的邊界這個問題是否是就解決了?因此在父級 div.wrapper 裏添加個屬性:border-top: 1px solid red; 果真 content 和 wrapper 解除了綁定,子級 div 能看到父級的邊界,可是這樣就會改變父級 div 的樣式,不符合開發要求,所以這種方法雖然能夠解決問題可是是徹底沒法使用的
      二、利用 overflow 來觸發 BFC 的效果:如今在父級 div.wrapper 裏面加一條屬性:overflow: hidden; 這條屬性的意思是溢出隱藏,在外觀沒有改變的同時,子 div 和父 div 解除了綁定,能正常移動了!通常採用這種方式來解決 margin 塌陷的問題。

      注意:雖然這種的方式能夠採用,但也不是沒有缺點。一旦用 JS 代碼改變了子級 div 的位置,就會有可能致使子級一部份內容由於溢出被隱藏的風險

    • 兩欄佈局,防止文字環繞等
      以下代碼

      <div class='div1'></div>
      <div class='div2'></div>
      .div1 {
          float:left;
          height:400px;
          width:200px;
          border:2px solid red;
      }
      .div2 {
        height:400px;
        border:5px solid green;
      }
      複製代碼

      兩欄佈局_1.png

      觸發 BFC

      .div1 {
          float:left;
          height:400px;
          width:200px;
          border:2px solid red;
      }
      .div2 {
          height:400px;
          border:5px solid green;
          display:flex;
      }
      複製代碼

      兩欄佈局_2.png

  • BFC 與 hasLayout
    • *zomm: 1 的屬性,這是 IEhack ,由於 IE6-7 並不支持 W3C 的 BFC ,而是使用私有屬性 hasLayout 。
    • 從表現上來講 hasLayout 跟 BFC 很類似,只是 hasLayout 自身存在不少問題,致使了 IE6-7 中一系列的 bug
    • 觸發 hasLayout 的條件與觸發 BFC 有些類似,推薦爲元素設置 IE 特有的 CSS 屬性 zoom: 1 觸發 hasLayout
    • zoom 用於設置或檢索元素的縮放比例,值爲「1」即便用元素的實際尺寸,使用 zoom: 1 既能夠觸發 hasLayout 又不會對元素形成其餘影響,相對來講會更爲方便
    • 須要注意既然 hasLayout 有着跟 BFC 類似的功能,那在實際開發中就要爲須要觸發 BFC 的元素同時觸發 hasLayout ,這樣 BFC 和 hasLayout 具備的一些特殊性質能夠在現代瀏覽器和 IE 中同時產生,避免一個元素在不一樣瀏覽器間的表現由於 BFC 或 hasLayout 出現差別
    • 事實上在實際開發中不少莫名其妙的問題其實都是所以而產生的。固然一樣地,若是一個元素沒有觸發 BFC 也要儘可能保證它沒有觸發 hasLayout

image.png

深刻理解BFC

IFC

  • 行內格式化上下文中(Inline Formatting Context)
  • 相對於塊格式化上下文,盒子一個接一個地水平排列,起點是包含塊的頂部,視覺上它將內容與其它行內級元素排列爲一行,直到該行被佔滿而後換行
  • 水平方向上的 margin、border 和 padding 在盒子之間獲得保留
  • 盒子在垂直方向上能夠以不一樣的方式對齊:頂部或底部對齊,或根據其中文字的基線對齊
  • 行內級盒分爲行內盒(inline boxes)和原子行內級盒(atomic inline-level boxes),前者由非置換元素且 display 值爲 inline 的元素生成;後者由行內級置換元素或 display 值爲 inline-block、inline-table、inline-flex、inline-grid 的元素生成,典型的可替換元素有 <img>、 <object>、 <video> 和 表單元素,如 <textarea>、 <input>
    • 對於非替換元素,如 a,span 等標籤能夠設置水平方向上的 margin 可是沒法設置垂直方向的 margin,至於 border 和 padding,垂直方向能夠設置可是當 border-top 和 padding-top 到達頁面頂部後就再也不增長了
    • 對於替換元素如 input、img 等標籤,能夠正常使用 margin、border、padding 的
  • IFC 渲染規則
    • IFC 中的行內級盒將會按照以下規則進行渲染(規則有點多,大概主要點就是行盒,折行機制,水平對齊方式,垂直高度及垂直對齊方式)
    • 盒子一個接一個水平擺放,當容器寬度不夠時就會換行
    • 在水平方向上這些盒的外邊距、邊框、內邊距所佔用的空間都會被計算,但行內盒的垂直的 border、padding、margin 都不會撐開行盒的高度
    • 在垂直方向上,這些盒可能會以不一樣形式來對齊,可經過 vertical-align 來設置,默認對齊爲 baseline
    • 每一行將生成一個行盒(line box),包括該行全部的盒子,行盒的寬度是由包含塊和存在的浮動來決定
    • 行盒通常左右邊都貼緊其包含塊,可是會由於浮動盒(float 元素)的存在而發生變化。浮動盒會位於包含塊邊緣與行盒邊緣之間,這樣行盒的可用寬度就小於包含塊的寬度
    • 當全部盒的總寬度小於行盒的寬度,那麼行盒中的水平方向排版由 text-align 屬性來決定
    • 當一個行內盒超過行盒的寬度時,它會被分割成多個盒,這些盒被分佈在多個行盒裏。若一個行內盒不能被分割(好比只包含單個字符,或 word-breaking 機制被禁用,或該行內框受 white-space 屬性值爲 nowrap 或 pre 的影響),那麼這個行內盒將溢出這個行盒
    • 當一個行內盒發生分割時,分割處的 margins、borders、 padding 不會有任何視覺效果(或其餘任何分裂,只要是有多個行盒)
    • 行盒的高度由內部元素中實際高度最高的元素計算出來。每一個行盒的高度因爲內容不同,因此高度也可能不同
    • 在一個行盒中,當包含的內部容器的高度小於行盒的高度時,內部容器的垂直位置可由本身的 vertical-align 屬性來肯定

注:在 IFC 的環境中是不能存在塊級元素的,若是將塊級元素插入到 IFC 中,那麼此 IFC 將會被破壞掉變成 BFC,而塊級元素前的元素或文本和塊級元素後的元素或文本將會各自自動產生一個匿名塊盒其包圍

定位

  • CSS 中元素的層次模型主要是由 position 屬性來決定的
  • position 的意思是定位,一樣該屬性的做用就是給元素施加定位
  • static:默認屬性,當沒有設置 position 屬性時元素默認的定位就是 static 定位,元素出如今正常的流中,此時 top, right, bottom, left 和 z-index 屬性無效
  • relative:相對定位,此時的『相對』是相對於其在正常文檔流的位置進行定位
    • 當 position 改爲 relative 後 left、top、right、bottom 進行的定位就會變成相對於自身的位置進行移動
    • relative 的參照物是元素自身
    • **當僅僅給元素設置 position:relative 並沒設置 left、right、top、bottom 屬性時,元素的定位是沒有發生任何改變的,由於這個特性,通常在開發中 relative 都是用做設置參照物的,一個 absolute 元素要相對於某個元素進行移動就給那個元素設置 relative **
  • absolute:絕對定位
    • 絕對定位,它會使元素脫離原本的位置再進行定位,它會使元素像立交橋同樣出現空間上的分層,當元素脫離原來的位置後其餘的元素就會「看不到」這個元素,同時 absolute 也能夠觸發 BFC
    • absolute 的參照物是距離它最近的有定位(除了 static)的父級,當每一個父級都沒有定位時元素會相對於瀏覽器邊框進行定位
    • 當使用絕對定位後可使用 left、right、top、bottom 這四個屬性分別設置當前元素距離左邊、右邊、上邊和下邊的距離,通常都是兩兩一對出現,其中 left 和 top 是一對,right 和 bottom 是一對
  • fixed:絕對定位
    • fixed 定位是相對於視口的定位,網頁上下左右兩邊不隨着滾輪滾動而改變位置的廣告欄,通常就是用 fixed
  • 粘性定位,特性近似於relative和fixed的合體,其在實際應用中的近似效果就是IOS通信錄滾動的時候的 『頂屁股』

    codepen.io/xiaomuzhu/p…

z-index

  • z-index 屬性用於指定已定位元素在垂直於頁面方向的排列順序,其屬性值有 2種:auto(默認值)和整數
    • z-index 屬性只對定位元素元素生效,即 position 屬性不爲 static 的元素
    • 除了默認值 auto, z-index 能夠設置爲任意整數,正數、0、負數
  • 通常狀況下,z-index 值進行比較有下面 2 條規則
    • 數值大的在上面,auto 數值上至關於 0
    • 數值相同的在 HTML 結構中排後面的在上面
  • z-index 默認值 auto 數值上等於 0,z-index: 0; 和默認的 z-index:auto; 是有區別的
    • 設置了 z-index 屬性爲整數值包括 0 的元素,自身會建立一個層疊上下文,而建立一個層疊上下文後其子元素的層疊順序就相對於父元素計算,不會與外部元素比較
  • 在進行 z-index 比較時要留意其祖先元素有沒有創建獨立的層疊上下文,z-index 只有在同個層疊上下文中比較纔有意義
  • 咱們能夠把視圖上的元素認爲是一摞書的層疊,而人眼是俯視的視⻆,設置 z-index 的位置就如同設置某一本書在這摞書中的位置
    頂部: 最接近觀察者 
    ...
    3210 層 默認層 
    -1 層
    -2 層
    -3 層 
    ...
    底層: 距離觀察者最遠
    複製代碼

層疊上下文和層疊順序

層疊上下文

  • 層疊上下文 stacking context 是 HTML 中一個三維的概念,在 CSS2.1 規範中每一個盒模型的位置是三維的,分別是平面畫布上的 X 軸、Y 軸以及表示層疊的 Z 軸。通常狀況下元素在頁面上沿 X 軸、Y 軸平鋪,察覺不到它們在 Z 軸上的層疊關係,而一旦元素髮生堆疊,這時就能發現某個元素可能覆蓋了另個元素或被另個元素覆蓋,HTML 元素依據其自身屬性按照優先級順序佔用層疊上下文的空間
  • 若一個元素含有層疊上下文(即它是層疊上下文元素),能夠理解爲這個元素在 Z 軸(表示的是用戶相對於面向(電腦屏幕的)視窗或網⻚的這條看不見的垂直線)上就「高人一等」,最終表現就是它離屏幕觀察者更近
  • 特性
    • 層疊上下文的層疊水平要比普通元素高
    • 層疊上下文能夠阻斷元素的混合模式
    • 層疊上下文能夠嵌套,內部層疊上下文及其全部子元素均受制於外部的層疊上下文
    • 每一個層疊上下文和兄弟元素獨立,即當進行層疊變化或渲染時只須要考慮後代元素
    • 每一個層疊上下文是自成體系的,當元素髮生層疊時整個元素被認爲是在父層疊上下文的層疊順序中
  • 如何產生?
    • HTML 中的根元素 自己就具備層疊上下文,稱爲「根層疊上下文」
    • 普通元素設置 position 屬性爲非 static 值並設置 z-index 屬性爲具體數值(非 auto),產生層疊上下文
    • 一個 z-index 值不爲 auto 的 flex 項目 (flex item),即:父元素 display: flex|inline-flex
    • opacity 屬性值小於 1 的元素(參考 the specification for opacity)
    • transform 屬性值不爲 none 的元素,
    • mix-blend-mode 屬性值不爲 normal 的元素
    • filter 值不爲 none 的元素
    • perspective 值不爲 none 的元素
    • isolation 屬性被設置爲 isolate 的元素
    • 在 will-change 中指定了任意 CSS 屬性,即使沒有直接指定這些屬性的,關於 will-change 能夠參見該文章:使用CSS3 will-change提升頁面滾動、動畫等渲染性能
    • -webkit-overflow-scrolling 屬性被設置 "touch"的元素

層疊水平/等級(stacking level)

  • 在同個層疊上下文中元素在 Z 軸上的顯示順序,普通元素的層疊水平優先由層疊上下文決定,所以層疊水平的比較只有在當前層疊上下文元素中才有意義
  • 在其餘普通元素中它描述定義的是這些普通元素在 Z 軸上的上下順序

層疊順序

  • 層疊順序 stacking order 表示元素髮生層疊時按照特定順序規則在 Z 軸上垂直顯示,所以前面所說的層疊上下文和層疊等級是一種概念,而層疊順序是一種規則
  • 在不考慮 CSS3 的狀況下當元素髮生層疊時,層疊順訊遵循下面的規則,這裏值得注意的是
    • 層疊上下文 background/border 指的是層疊上下文元素的背景和邊框,每一個層疊順序規則適用於一個完整的層疊上下文元素
    • 原圖沒有呈現 inline-block 的層疊順序,實際上 inline-block 和 inline 水平元素是同等 level 級別
    • z-index: 0 實際上和 z-index: auto 單純從層疊水平上看是能夠當作是同樣的,實際上二者在層疊上下文領域有着根本性的差別
  • 爲何內聯元素的層疊順序要比浮動元素和塊狀元素都高?
    • border/background 等通常爲裝飾屬性,浮動和塊狀元素通常用做佈局,而內聯元素通常都是頁面內容,網頁中最重要的固然是內容,所以必定要讓內容的層疊順序至關高,當發生層疊時重要的文字、圖片內容能夠優先暴露在屏幕上

層疊順序.png

總結

  • 首先先看要比較的兩個元素是否處於同一個層疊上下文中
  • 若是是誰的層疊等級大,誰在上面
  • 若是兩個元素不在同一層疊上下文中,請先比較他們所處的層疊上下文的層疊等級
  • 當兩個元素層疊等級相同、層疊順序相同時,在 DOM 結構中後面的元素層疊等級在前面元素之上

層疊上下文-張鑫旭

浮動

  • float 屬性可以讓元素像站隊同樣浮動起來,它會讓原本佔滿整行的元素只按照內容和設置大小來在父級裏面進行站隊排列,當這一行剩餘的空間不足以再放下個元素時元素就會自動換行,到下一行去進行浮動排列;當容器不夠大時雖然內容會超出容器範圍,可是超出以後仍然是按照相同隊形來進行站隊

  • 浮動起來的元素會像 absolute 的元素脫離文檔流,但不會脫離文字流,這是什麼意思呢?

    • 脫離文檔流的意思就是正常元素看不到它,不脫離文字流的意思則是 display 屬性是 inline 或 inline-block 的元素仍是能夠看到它的,文字自己是 inline 屬性的
    • float 屬性會自動將這個元素的 display 改爲 inline-block ,即不論給 display 加上什麼值,只要有 float 屬性,那這個元素就是 inline-block 屬性
  • float 屬性只有兩個值:left、right,默認狀態是 none

  • float 屬性的做用

    • 對元素進行佈局
    • 像 absolute 同樣,讓元素浮動起來,產生本身獨有的浮動流
  • 浮動流有兩個效果

    • 脫離標準的文檔流但不會脫離文字流 ,正常元素看不到它,但有文字屬性 inline 或文字自己能夠看到它
    • 在內部會把該元素變換成 inline-block 屬性的元素
  • 使用 float 屬性

    • 通常是使用網狀佈局時使用,當不知道容器裏面會盛放多少個子元素,但這些子元素又是按照同樣格式進行排列,設置浮動來進行流式佈局
      浮動_1.png
    • 實現像報紙那樣文字包圍在圖片四周的效果 浮動_2.png
  • 浮動元素會引發的問題

    • 父元素的高度沒法被撐開,影響與父元素同級的元素
    • 與浮動元素同級的非浮動元素會跟隨其後
    • 若非第一個元素浮動,則該元素以前的元素也須要浮動,不然會影響頁面顯示的結構
  • 清除浮動

  • 清除浮動主要是爲了解決因爲浮動元素脫離文檔流致使的元素重疊、父元素高度坍塌的問題,而這兩問題分別對應了須要清除浮動的兩種狀況:清除前面兄弟元素浮動閉合子元素浮動(解決父元素高度坍塌)

  • 清除前面兄弟元素浮動

    • 只需在不想受到浮動元素影響的元素上使用 clear: both 便可
    • 在 CSS2 之前 clear 的原理爲自動增長元素的上外邊距(margin-top)值,使之最後落在浮動元素的下面
    • 在 CSS2.1 中引入了一個清除區域(clearance):在元素外邊距之上增長額外間距,使之最後落在浮動元素的下面,因此若須要設置浮動元素與 clear 元素的間距,得設置浮動元素的 margin-bottom,而不是 clear 元素的 margin-top
  • 閉合子元素浮動

父元素高度坍塌問題:在計算頁面排版時,若沒設置父元素的高度,那麼該父元素的高度是由他的子元素高度撐開的,但若子元素是設置了浮動,脫離文檔流,那父元素計算高度時就會忽略該子元素,甚至當全部子元素都是浮動時就會出現父元素高度爲 0 的狀況

  • 解決辦法

    • 在父級裏內容區最後加個 p(div等)標籤,給該 p 標籤增長清除浮動的樣式
      1)實際上並非父級清除了浮動流,而是被 p 標籤撐開了,p.clear 能看到上面浮動的元素,wrapper 能看到不浮動的 p 標籤,所以把 p 標籤包裹進去了
      2)雖然該辦法比較直觀,但不是很優雅,由於增長了一個無用的空白標籤,比較冗餘且不方便後期維護(通常不太建議使用該辦法)
      <div class=」wrapper」>
        <div class=」content」>1</div>
        <div class=」content」>2</div>
        <div class=」content」>3</div>
        <div class=」content」>4</div>
        <p class=」clear」></p>
      </div>
      .clear {
          clear: both;
      }
      複製代碼
  • 添加僞元素

    • 爲父級元素添加一個 after 僞元素,讓這個僞元素專門實現清除浮動的功能
      .wrapper::after {
          content: "";
          clear: both;
          display: block; // 能清除浮動的元素,必須是塊級元素
      }
      複製代碼

      一、僞元素是一種不能單獨存在的元素,它必需要依附於其餘正式元素標籤上使用,單獨寫是沒有任何意義的,僞元素最經常使用的有兩個 afterbefore,當不想改變 html 結構又想要增添一些東西時,僞元素 after、before 就很是實用
      二、注意寫僞元素,即便內容是空的也要加上 content 這個屬性: content: " "
      三、既然是僞元素那天然也屬於元素,可改變僞元素的 display 爲 block,從而可改變寬高等塊級元素纔有的樣式

  • 觸發 BFC 的方式來清除浮動(觸發方式請見本文相關 BFC 部份內容)

  • 注意

    • IE6 / IE7 並無僞元素這種東西,但其獨有 hasLayout,只要觸發了 hasLayout 就和觸發 BFC 有差很少的做用,可以觸發這個東西的屬性有不少,其中最無害的屬於 zoom 屬性,只要寫上這個屬性 IE6 / IE7 也可清除浮動
    • 不過其餘瀏覽器並不需 zoom 屬性,該屬性只是爲了 IE6 / IE7 準備的,因此須要一點點 CSS hack,在 zoom 前加一個符號,**zoom: 1; 該符號只有 IE6 / IE7 可以識別,其餘的瀏覽器都不識別,屬性前面加上’_‘後就只有 IE6 能夠識別 _zoom: 1;
      .wrapper {
          zoom: 1; //視口同比例放大仍是縮小,1 就是不變
      }
      複製代碼

CSS3

簡介

CSS3 是 CSS2 的升級版本,3 只是版本號,它在 CSS2.1 的基礎上增長了不少強大的新功能,目前主流瀏覽器 chrome、safari、firefox、opera、甚至 360 都已經支持了 CSS3 大部分功能,IE10 之後也開始全面支持 CSS3

CSS3 前綴

  • 在編寫 CSS3 樣式時不一樣的瀏覽器可能須要不一樣的前綴,它表示該 CSS 屬性或規則還沒有成爲 W3C 標準的一部分,是瀏覽器的私有屬性,雖然目前較新版本的瀏覽器都是不須要前綴的,但爲了更好的向前兼容前綴仍是少不了的,標準寫法如表順序,再在後面添加無前綴的
    前綴 瀏覽器
    -webkit chrome/safari
    -moz firefox
    -ms IE
    -o opera

CSS3 功能

  • 提供了更增強大且精準的選擇器,提供多種背景填充方案,可實現漸變顏色,可改變元素的形狀、角度等,能夠加陰影效果,報紙佈局,彈性盒子,ie6 混雜模式的盒模型,新的計量單位,動畫效果等等...
  • 但 CSS3 的兼容性問題一樣也顯得格外重要,並非全部 CSS3 屬性都經過了 W3C 標準,須要全面的兼容性查閱手冊

詳細可閱讀 CSS3 教程

擴展

有哪些方式(CSS)能夠隱藏⻚面元素?

  • display: none,自身及全部的子元素都完全隱藏,好像不存在,既不佔據空間也不可交互
  • visibility: hidden,元素的大小不變,仍佔據空間,可理解爲透明,但不可交互。但子元素設置爲visibility:visible,則該子元素依然可見
  • overflow: none,規定了當內容元素溢出父容器時隱藏元素溢出的部分,使用滾動條來顯示或直接顯示超出部分,佔據空間且不可交互
  • z-index: -9999:原理是將層級放到底部,這樣就被其餘層級元素覆蓋,看起來隱藏了
  • opacity: 0:本質上是將元素的透明度將爲 0,看起來隱藏了,但依然佔據空間且可交互
  • transform: scale(0, 0):平面變換,將元素縮放爲0,佔據空間但不可交互
  • 還有一些靠絕對定位把元素移到可視區域外或用 clip-path 進行裁剪的操做等

水平間距問題

  • 在寫頁面時的導航時,通常須要將 display 屬性設置爲 inline-block,此時會致使在兩個導航元素間出現大約 8px 左右的空白間隙

    <div class="nav">
      <div class="nav-item"><a>導航</a></div>
      <div class="nav-item"><a>導航</a></div>
      <div class="nav-item"><a>導航</a></div>
    </div>
    .nav {
      background: 999;
    }
    .nav-item {
      display: inline-block;
      width: 100px;
      background: #ddd;
    }
    複製代碼
  • 緣由是由於編寫代碼時輸入空格、換行都會產生空白符,而瀏覽器是不會忽略空白符的且對於多個連續的空白符瀏覽器會自動將其合併成一個,故產生了所謂的間隙

    空白間隙.png

  • 解決方案

    • 代碼不換行。因爲換行空格致使產生換行符,所以可將上述例子中的列表 item 寫成一行,這樣空白符便消失,間隙就不復存在。但考慮到代碼可讀及維護性,通常不建議連成一行的寫法
      <div class="nav">
         <div class="nav-item">導航</div><div class="nav-item">導航</div><div class="nav-item">導航</div>
      </div>
      複製代碼
    • 設置 font-size
      一、首先要理解空白符歸根結底是個字符,所以可經過設置 font-size 屬性來控制產生的間隙的大小,若將 font-size 設置爲 0,文字字符是無法顯示的,一樣這個空白字符也沒了,間隙也就沒了
      二、經過設置父元素的 font-size 爲 0 來去掉這個間隙,而後重置子元素的 font-size,讓其恢復子元素文字字符,使用該方法時須要特別注意其子元素必定要重置 font-size,否則很容易掉進坑裏(文字顯示不出來)
      .nav {
          background: #999;
          font-size: 0; /* 空白字符大小爲0 */
      }
      .nav-item {
          display:inline-block;
          width: 100px;
          font-size: 16px; /* 重置 font-size 爲16px*/
          background: #ddd;
      }
      複製代碼
    • 原本覺得上面可以徹底解決問題,但經測試將父級標籤字符設置爲 0 在 Safari 瀏覽器依然出現間隔空白;既然設置字符大小爲 0 不行,那咱就將間隔消除了,將下面代碼替換上面的代碼,目前測試完美解決。一樣隨來而來的問題是 item 內的字符間隔也被設置了,須要將其內的字符間隔設爲默認
      .nav { letter-spacing: -5px; }
      .nav-item { letter-spacing: normal; }
      複製代碼

溢出打點

  • 當文字超過所規定的範圍後後面的所有文字就會變成 「…」 的形式來出現

  • 單行文字溢出打點,須要三個屬性來配合使用

    • overflow: hidden; 實現讓文字溢出容器的部分隱藏起來,方便後面的打點功能
    • text-overflow: ellipsis; 文字溢出以後怎麼處理,ellipsis 是指處理方式是以點狀顯示
    • white-space: nowrap; 讓文字不換行,文字的默認狀態是換行的,當到達容器壁以後自動換到下一行,該屬性讓文字一直在一行顯示,即便到了容器壁也不換行
  • 多行文字溢出打點

    • 雖然有屬性可達到多行文字溢出打點的功能,但兼容性十分很差,除了移動端的網頁(由於移動端的瀏覽器通常版本都比較高)以外
    • pc 端的網頁通常都是用其餘方式來實現,像百度就是經過計算文字的寬高,而後在最後手寫 「…」 來實現多行文字溢出打點效果
    • 而若想要以屬性方式來完成多行文字溢出打點的功能,要用到如下屬性
      • line-clamp 屬性是指讓文字顯示幾行。-webkit 是兼容 webkit 內核的瀏覽器,目前還有不少瀏覽器不支持 line-clamp 屬性,只有 webkit 較高版本勉強支持
      • box-orient 也是很是勉強,所以該功能雖然存在,但因爲兼容性問題不多有公司會使用
      • display: -webkit-box 是 CSS3.0 的一個屬性
      text-overflow: ellipsis;
      overflow: hidden;
      display: -webkit-box;
      -webkit-line-clamp: 3; //行數
      -webkit-box-orient: vertical;  
      複製代碼

如何讓背景圖片出不來時顯示文字

  • 有時網頁會被用戶禁止加載圖片和 CSS 樣式,若沒有給背景圖片設置任何信息,那用戶就徹底不知道這個空白地方是什麼東西,因此要讓圖片加載不出來時也可以有文字展現出來,可使用如下兩種方法來實現這種效果

text-indent

  • 比較傳統的作法:利用 text-indent 配合 white-space: nowrap 、overflow: hidden; 讓元素內部的文字在有 CSS 時會被縮進到元素外面並被隱藏起來,當 CSS 不能加載時文字不會被縮進,因此能夠展現出來

背景圖片放到 padding 裏,高度強制爲 0

  • background-image 是能夠放到 padding 裏,元素自己的高度爲 0,利用 padding-top 撐起元素的內容區,這樣當有 CSS 樣式時配合 overflow: hidden 一塊兒使用就可讓文字隱藏,沒有 CSS 樣式時文字就會正常顯示出來
.taobao-head .header .logo-bd {
    display: block;
    margin-left: 22px;
    width: 142px;
    padding-top: 58px;
    height: 0;
    overflow: hidden;
    background: url(xxxx) 0 0 no-repeat;
}
複製代碼

爲何有時用 translate 來改變位置而不是定位?

  • translate 是 transform 的一個值,改變 transform 或 opacity 不會觸發瀏覽器從新佈局(reflow)或重繪(repaint),只會觸發複合(compositions)
  • 而改變絕對定位會觸發從新佈局,進而觸發重繪和複合
  • transform 使瀏覽器爲元素建立一個 GPU 圖層,但改變絕對定位會使用到 CPU,所以 translate 更高效,能夠縮短平滑動畫的繪製時間
  • 而 translate 改變位置時元素依然會佔據其原始空間,絕對定位就不會發生這種狀況
相關文章
相關標籤/搜索