CSS 設計指南 學習筆記 一

原文地址:http://justclear.github.io/css-stylin-with-css-note-1css

因爲 CSS 做用的對象是 HTML ,因此做者在這章主要先講了一些基本的 HTML 標籤的用法和結構。html

1.2 HTML 文檔剖析

做者在這節主要講了一個 HTML 頁面所需的最基本的文檔結構以下:html5

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <!-- 這裏是網頁內容 -->
</body>
</html>

首先 <!DOCTYPE html> 是 HTML5 中新的文檔類型聲明語法,相比 HTML4 的冗長文檔類型聲明語法來講 HTML5 是大大的簡化了。git

1.2.2 塊級元素和行內元素

做者在這一節介紹了兩個比較重要的概念————塊級元素和行內元素,默認狀況下塊級元素會始終佔居一行,而行內元素並不會。除了 table 元素的 display 屬性比較特殊之外,基本上全部的 HTML 元素的 display 的屬性值要麼是 block,要麼是 inline。做者的一個思想是,不管你想了解哪一個 HTML 元素,第一個要問的問題就是:它是塊級元素仍是行內元素,而後在編寫標記的時候預想到這個元素在初始狀態下是如何定位的,這樣才能進一步想好未來怎麼用 CSS 從新定位它,由於塊級元素和行內元素在定位上有很大的區別,後面的拓展會詳細說明。github

塊級元素盒子(一個很重要的概念————盒模型,後面會詳細說明)會擴展到與父元素同寬,這也是爲何塊級元素會佔居一行的緣由了,由於全部塊級元素的父元素都是 body,而它的默認寬度就是瀏覽器的視口(viewport)大小,因此默認狀況下塊級元素的寬度也和瀏覽器的視口同樣寬,這樣以來,一個塊級元素旁邊也就沒有空間來容納另外一個塊級元素了。canvas

相比於塊級元素會擴展到與父元素同寬,然而行內元素的行爲倒是偏偏相反,它會盡可能的「收縮包裹」其內容(也是盒模型的概念),這也就是爲何幾個行內元素會並排顯示在一行直到它們排滿一行纔會另起一行,而每一個塊級元素會直接另起一行的緣由了。瀏覽器

拓展:ide

做者在這一節中並無對塊級元素和行內元素的一些其餘特性進行詳細的解釋,在這裏筆者對它們的一些特性知識進行拓展。首先先列出一些常見的塊級元素和行內元素:佈局

<!-- 常見的塊級元素 -->
div, form, table, header, aside, section, article, figure, figcaption, h1~h6, nav, p, pre, blockqoute, canvas, ol, ul, dl

<!-- 常見的行內元素 -->
span, a, img, label, input, select, textarea, br, i, em, strong, small, button, sub, sup, code

以前做者提到過不管你想了解哪一個 HTML 元素,第一個要問的問題就是:它是塊級元素仍是行內元素,由於它們在盒模型上的表現有很大的不一樣,不過在瞭解它們的不一樣以前咱們還得先知道另一個概念————替換元素非替換元素,其中替換元素就是指瀏覽器是根據元素的屬性來判斷具體要顯示的內容的元素,好比 img 標籤,瀏覽器是根據其 src 的屬性值來讀取這個元素所包含的內容的,常見的替換元素還有 inputtextareaselectobjectiframevideo 等等,這些元素都有一個共同的特色,就是瀏覽器並不直接顯示其內容,而是經過其某個屬性的值來顯示具體的內容,好比瀏覽器會根據 input 中的 type 的屬性值來判斷到底應該顯示單選按鈕仍是多選按鈕亦或是文本輸入框。而對於非替換元素,好比 plabel 元素等等,瀏覽器這是直接顯示元素所包含的內容。看到這裏你應該大概的知道了什麼是替換元素和非替換元素了。性能

對着兩個概念有了大概的瞭解後就能夠對 blockinline 在盒模型上的表現差別進行了解了,首先是 marginW3C 對其所支持了元素對象是這麼定義的:

Applies to: all elements except elements with table display types other than table-caption, table and inline-table

英語不是很好,沒太明白這句話的意思,個人理解就是全部元素都支持 margin 除了 display 屬性值爲 table-captiontable-inline 之外的全部表格顯示類型好比 table-row-grouptable-celltable-rowtable-header-group等等,可是爲了驗證個人理解,我發先 display 屬性值爲 table 的元素也支持,多是我對原文標準的理解有誤。但還有一個要特別注意的是 margin-topmargin-bottom 兩個屬性比較特殊,它們對非替換行內元素沒有效果,下面是 W3C 上對於 margin-topmargin-bottom 支持對象的介紹:

Applies to: all elements except elements with table display types other than table-caption, table and inline-table

These properties have no effect on non-replaced inline elements.

前面一句和以前對 margin 的描述是同樣的,這毫無疑問,下面這句話的意思是這些( margin-topmargin-bottom )屬性對非替換行內元素沒有效果好比 aspan,注意這裏是非替換行內元素而不僅僅是非替換元素或者是行內元素。好比 img 就是一個行內元素, margin-topmargin-bottom 對它是有效果的,由於它是一個替換元素而不是非替換元素,因此對於「 margin-topmargin-bottom 對行內元素沒有效果」這種說法是不對的。

而對於 padding 的支持對象,W3C 是這麼描述的:

all elements except table-row-group, table-header-group, table-footer-group, table-row, table-column-group and table-column

上面這句話的意思是除了表格顯示類型爲 table-row-grouptable-header-grouptable-footer-grouptable-row, table-column-grouptable-column 的元素不支持,其餘全部的元素都支持。

但這裏有些特殊狀況須要注意的是,對行內元素好比 spanimg 設置左右內邊距的效果是可見可,可是對行內元素設置上下內邊距在有些狀況下是不可見的,這些狀況又要分爲是否爲替換元素和是否設置了背景色,爲了能更直觀的瞭解這些概念,我在這裏作了個表格:

<!-- padding-top,bottom是否可見 -->

padding-top 和 padding-bottom 對於行內元素是否可見:

<div class="table-responsive">

替換元素(e.g: input) 非替換元素(e.g: span)
設置背景色 可見,影響行高,會撐開父元素 可見,不影響行高,不會撐開父元素
沒有設置背景色 可見,影響行高,會撐開父元素 不可見,不影響行高,不會撐開父元素

</div>

因此對於「 padding-toppadding-bottom 對行內元素沒有效果」這種說法也是不對的,由於它們只是對於沒有設置背景色的行內非替換元素效果不可見而已,而對於行內替換元素來講,無論是否設置了背景色都是有效果了,而且會把父元素撐開。

說了這麼多 blockinline-block 的區別,其實除了這兩個常見的 display 屬性之外還有一個屬性也是很是常見的,那就是 inline-block ,沒錯,這就是前面兩種狀況的結合體,它既有 block 的特性又有 inline 的特性,好比把一個 display 屬性值爲 block 或者 inline 的元素屬性值設置成 inline-block 後,既能夠用只對行內元素有效的 text-align: center; 聲明對其進行居中之外,還能夠用 padding-toppadding-bottom 對元素設置上下內邊距而無需對其設置背景色,而且能把父元素撐開。

對於塊級元素和行內元素的拓展就暫時到這,若是有不明白或者不對的地方也歡迎指出。

1.3 文檔對象模型

做者在這一小節只要介紹了 HTML 結構所對應的文檔對象模型(DOM,Document Object Model),DOM 是從瀏覽器的視角來觀察頁面中的元素以及每一個元素的屬性,由此能夠得出這些元素的一個家族樹。經過 DOM 能夠很清晰的看出文檔中每一個元素之間的關係。好比下面的 HTML 代碼的 DOM 的家族樹就以下圖:

<body>
    <section>
        <h1>The Document Object Model</h1>
        <p>The page's HTML markup structure defines the DOM.</p>
    </section>
</body>

DOM

上面是一個很是簡單的 DOM 結構圖,由此你能夠和直觀的看出 HTML 文檔流中每一個元素之間的關係,好比究竟是父子元素仍是兄弟元素。

1.4 小結

做者在本章主要講解了 HTML 標籤是怎麼爲內容提供結構的,以及每一個元素會在屏幕上生成什麼樣子的盒子,好比是行內盒子仍是塊級盒子,最後又簡單的講解了什麼是 DOM ,它是瀏覽器中文檔的模型,而 CSS 能夠修改 DOM 中的元素樣式屬性,從而修改頁面自己的佈局和外觀。

第二章 CSS 工做原理

在本章中做者主要講解了 CSS 如何對 HTML 添加樣式的,而且解釋了層疊的工做機制好比當元素的同一個屬性被屢次設置樣式後到底應該選擇何種樣式,這就要靠 CSS 的層疊機制來決定最終應用哪一種樣式了。

每一個 HTML 元素都有一組樣式屬性,這些屬性涉及元素在文檔流中顯示時的不一樣方面,好比在文檔流中的位置、邊框、背景、顏色等等。CSS 就是一種先選擇 HTML 元素,而後設定選中元素 CSS 屬性的機制。CSS 選擇符和要應用的樣式構成一條 CSS 規則。

2.2 上下文選擇器

上下文選擇器的格式以下:

標籤1 標籤2 { 聲明}

其中標籤2就是咱們要選擇的目標,並且只有在標籤1是標籤2的祖先元素(不必定是父級元素)的狀況下才會被選中。上下文選擇器嚴格來說應該叫「後代組合式選擇器(Descendant Comninator Selector)」。

還有一點要注意的是,上下文選擇器以空格做爲分隔符,而分組選擇器則以逗號做爲分隔符,不要弄混。

2.3 特殊的上下文選擇器

前面一節做者介紹的上下文選擇器是以某個祖先元素做爲上下文的,只要目標元素在 DOM 結構「上游」存在這麼一個祖先元素便可,不管這個祖先元素和目標元素隔了多少層級都沒有關係,但有的時候咱們須要比「某個祖先元素」更具體的上下文,這時候咱們就可使用一些特殊的選擇器了,好比自選擇器 >、 緊鄰兄弟選擇器 +、通常兄弟選擇器 ~ 和通用選擇器 *

2.3.1 子選擇器 >

標籤1 > 標籤2

這裏的標籤2必須是標籤1的子元素,也就是說標籤1必須是標籤2的父元素,而不能是標籤2的任何其餘祖先元素。

2.3.2 緊鄰兄弟選擇器 +

標籤1 + 標籤2

在這裏標籤2必須緊跟在兄弟標籤1的後面,不然無效。

2.3.3 通常兄弟選擇器 ~

標籤1 ~ 標籤2

在這裏標籤2必須跟(不必定要緊跟,只需在標籤1的後面便可)在其兄弟標籤1後面。

2.3.4 通用選擇器 *

*

通用選擇器 * 是一個是一個通配符,表明文檔流中的任意元素,不過通用選擇器 * 一般會搭配一些其餘選擇器來使用,好比:

section > *

表明 section 的全部子元素,不過通常狀況下不多經過通配符來選擇某個元素下的全部子元素,由於這涉及到瀏覽器性能問題,它會影響網頁的渲染時間,咱們寫的時候是從左到右寫的,可是瀏覽器渲染倒是從右到左的,就上面這段代碼來講,瀏覽器會先遍歷全部的元素,而後在找出哪些元素的父元素是 section,另外舉一個例子,有選擇器:

div.container #main > .article {}

瀏覽器在渲染時,先把全部類中包含 article 的元素取出來組成一個集合,而後對每個集合中的元素進行遍歷,若是元素的父元素的 id 不爲 main 則把元素從集合中刪去。 再而後從這個元素的父元素開始向上找,沒有找到一個標籤名爲 div 而且類名中有 container 的元素,就把元素從集合中刪去,直到匹配全部的條件,因此在能不使用通配符的狀況就儘可能不要使用它。

2.4 ID 和類選擇器

做者在這一節介紹了 idclass 選擇器,爲咱們選擇元素提供了另外一種手段,利用它們能夠不考慮元素在文檔流中的層次結構,只要在元素中添加了 idclass 屬性和值,咱們就能夠經過它們的值來找到目標元素。

能夠給 idclass 屬性設定任何值,但不能以數字或者特殊符號開頭。

2.4.3 何時用 id,何時用 class

id 的用途是在頁面中惟一地標識元素,因此每一個頁面中每個 id 屬性值都是獨一無二的。而 class 的目的是爲了標識一組具備相同特徵的元素,也就是說一個頁面中能夠出現多個相同的類。

對於何時用 id 這個問題做者的觀點是:

每個頂級區域都應該添加一個 id,從而獲得很是明確的上下文關係,以便編寫 CSS 時只選擇嵌套在相應區域內的標籤。

對於何時使用 class,因爲 class 的目的是爲了標識一組具備相同特徵的元素,因此若是當頁面中有一組元素具備某種相同的特徵,就應該絕不猶豫的時候 class 了。

可是這裏也應該注意不要亂用類,避免形成類氾濫,例如:

<nav>
    <ul>
        <li class="boy"><a href="#">Alan</a></li>
        <li class="girl"><a href="#">Andrew</a></li>
        <li class="boy"><a href="#">Angela</a></li>
        <li class="boy"><a href="#">Angus</a></li>
        <li class="girl"><a href="#">Anne</a></li>
        <li class="girl"><a href="#">Annette</a></li>
    </ul>
</nav>

上面這個例子就是一個典型的類氾濫。

2.4.4 id 和 class 的小結

對於何時用 id 和何時用 class,我想每一個人都有不一樣的見解,這裏寫說一下筆者的觀點,筆者認爲能不實用 id 就儘可能不使用 id,實際狀況是筆者基本不在 CSS 中使用 id,由於在 CSS 的層疊機制中,id 的權重是 class 的10倍,其實不少狀況下對某個元素設置某個不同的樣式來覆蓋以前的樣式並無效果就是由於以前的樣式權重過高,而爲了達到效果就要編寫權重更高的選擇器,因此只有在某個元素須要被 JavaScript 找到的時候纔會在某個元素中添加 id ,以即可以經過 document.getElementById() 方法來快速獲取須要的元素。

2.5 屬性選擇器

屬性選擇器包括屬性名選擇器和屬性值選擇器,它們是經過元素的屬性和值來獲取元素的:

標籤名[屬性名]
標籤名[屬性名="屬性值"]

例如:

img[title] {border: 2px solid blue;}
a[target="_blank"] {background-image: url(_blank.png);}

上面第一段代碼意思是,若是某個 img 標籤帶有 title 這個屬性,那麼就爲它添加一個寬度爲 2px 的藍色實線邊框。第二段代碼的意思是,若是某個 a 標籤帶有 target 這個屬性,而且這個屬性的值爲 _blank 那麼就爲這個元素添加一個背景圖。

拓展:

其實除了以上兩種屬性選擇器,還有其餘幾種屬性選擇器做者並無列出來,這裏這幾種其餘的屬性選擇器做一個簡單的介紹:

標籤名[name^="value"]  讓你匹配屬性爲 `name` 而且屬性值以 `value` 開始的標籤,如:a[href^= "http://"]則匹配全部具備 `href` 屬性而且屬性值以 `http://` 開始的標籤。

標籤名[name$="value"]  讓你匹配屬性爲 `name` 而且屬性值以 `value` 結束的標籤,如:a[href$=".com"]則匹配全部具備 `href` 屬性而且屬性值以 `http://` 結束的標籤。

標籤名[name*="value"]  讓你匹配屬性爲 `name` 而且屬性值包含 `value` 的標籤,如:a[href*= "renren"]則匹配全部具備 `href` 屬性而且屬性值包含 `http://` 的標籤。

標籤名[name|="value"]  讓你匹配屬性爲 `name` 或者以 `name-` 開始的標籤,如:p[lang|= "en"]則匹配具備 `lang` 屬性的 `p` 標籤,無論其屬性值是 `en` 仍是 `en-us` 。

標籤名[name~="value"]  讓你匹配屬性爲 `name` 而且其屬性值是具備多個空格分隔的值,其中一個值爲 `value`,若有:
<a title="I'm title for learn more">Learn More</a>
就能夠用 p[title~="learn"] 來選擇這個元素。

你應該注意到了這些屬性選擇器與前面兩種屬性選擇器之間的差異了,經過這些屬性選擇器咱們能夠很容易的作出許多意想不到的效果,好比:

a[href$=".pdf"] {background-image: url(pdf.png);}

好比上面這段代碼就爲連接是 pdf 文檔鏈接的 a 標籤添加一個表示這個連接是 pdf 文檔的圖片,而其餘 href 屬性的值不是以 .pdf 結尾的 a 標籤就不會應用這條樣式聲明,讓用戶很清楚的判斷這是一個什麼類型的連接。

2.6 僞類

僞類這個叫法源自它們與類類似,但實際上並無類會附加到標記中的標籤上,僞類分爲兩種:

  • UI(User Interface,用戶界面)僞類:會在 HTML 元素處於某個狀態時(好比鼠標指針位於鏈接上),爲該元素應用 CSS 樣式。

  • 結構化僞類:會在標記中純在某種結構上的關係時(好比某個元素是一組元素的第一個或者最有一個元素),爲相應的元素應用 CSS 樣式。

2.6.1 UI僞類

  1. 連接僞類

    • link: 連接就在那兒等着用戶點擊。

    • visited:用戶此前點擊過這個連接。

    • hover:鼠標指針正懸停在鏈接上。

    • active:連接正在i被點擊(鼠標在元素上按下,尚未釋放)。

    注意以上幾種連接僞類要按必定的順序纔有效果,爲了方便記憶做者是這麼建議的:"LoVe?HA!",大寫字母就是每一個僞類的第一個字母,其實也能夠這麼記: "LoVe,HAte",其實都差很少就是了。

    一個冒號(:)表示僞類,兩個冒號(::)表示 CSS3 新增的僞元素。

  2. :focus 僞類

    表單中的文本字段在用戶單擊它時會得到焦點,例如:

    input:focus {border: 1px solid blud;}

    這段代碼的意思就是當用戶單擊表單中的文本字段的時候,爲該 input 標籤添加寬度爲 1px 的藍色實線邊框,須要注意的是,僞類的冒號要緊跟着標籤名,之間不能有空格,不然該聲明無效。

  3. :target 僞類

    若是用戶點擊一個指向頁面中其餘元素的連接,則哪一個元素就是目標(target),能夠用 :target 僞類選中它,好比:

    <a href="#more-info">More Information</a>

    位於頁面其餘地方、idmore-info 的那個元素就是目標元素,該元素多是這樣的:

    <h2 id="more=info">This is the information you are looking for.</h2>

    那麼 CSS 規則以下:

    #more-info:target {background: #eee;}

    此時會在用戶點擊連接轉向 idmore-info 的元素時,該目標元素的背景就會變成淺灰色。

2.6.2 結構化僞類

  1. first-child 、 last-child 和 nth-child(n)

    e:first-child
       e:last-child

    first-childlast-child 分別表明一組同胞元素中的第一個元素和最後一個元素,而 nth-child(n) 則表明一組同胞元素中的任何一個元素,其中 n 表示一個整數(也能夠是 odd-奇數 或 even-偶數)或者也能夠是一個算數表達式(2n + 1),例如:

    <ul>
           <li>My Fast Pony</li>
           <li>Steady Trotter</li>
           <li>Slow Ol' Nag</li>
       </ul>
    
       ul li:first-child {color: black;}
       ul li:nth-child(2) {color: red;}
       ul li:last-child {color: blue;}

    上面的 HTML 應用了上面的 CSS 規則後,無序列表的第一個元素字體顏色就會變成黑色,第二個元素變成紅色,最後一個元素就變成藍色。

2.7 僞元素

顧名思義,僞元素就是文檔中如有實無的元素,下面是幾個比較經常使用的僞元素。

  1. ::first-letter 僞元素,好比:

    p::first-letter {font-size: 300%;}
    
    這樣 `p` 標籤的第一個字母大小就會變成原來的 3 倍了,而其餘元素則不會。
  2. ::first-line 僞元素:能夠選中文本段落的第一行。

  3. ::before 和 ::after 僞元素

    e::before
        e::after
    
    可用在特定元素前面或後面添加特殊內容,好比:
    
        <p class="age">25</p>
    
        .age::before { content: "Age: ";}
        .age::after { content: " years";}
    
    這裏須要注意的是,對於 `::before` 和 `::after` 僞元素,其 `content` 屬性是必須的,還有就是搜索引擎不會取得僞元素的信息(由於它在文檔流中並不存在),所以不要經過僞元素添加一些對搜索引擎來講是重要的內容。

拓展:

其實僞元素前面冒號能夠是兩個也能夠是一個,可是爲了區別僞類,筆者建議你們仍是使用兩個冒號。還有一個要注意的是,好比經過 ::before::after 僞元素爲 classpseudo-element 添加兩個僞元素,則生成的兩個僞元素分別處於 pseudo-element 元素的內部,也就是說是 pseudo-element 元素的子元素,而且分別位於 pseudo-element 元素的內容的最前面和最後面,代碼以下:

<div class="pseudo-element">
    <p>Pseudo Element</p>
</div>

.pseudo-element::after,
.pseudo-element::before {
    content: "";
}

Pseudo Element

如上圖所示,生成的兩個僞元素分別處於 pseudo-element 元素的內部,而且分別位於 pseudo-element 元素的內容 p 標籤的前面和後面,而不是以下圖所示的位於 pseudo-element 元素外部的前面和後面:

Pseudo Element

2.9 層疊

層疊就是層疊樣式表中的層疊,是一種樣式在文檔層次中逐層疊加的過程,目的是讓瀏覽器面對某個標籤特定屬性值的多個來源肯定最終使用哪一個值。

層疊是 CSS 的核心機制,理解了它才能以最經濟的方式寫出最容易改動的 CSS,讓文檔外觀在達到設計要求的同時,也給用戶留下一些空間,讓他們能根據須要更改文檔的顯示效果。

2.9.1 樣式來源

做者在這一節中介紹了樣式的幾種來源:

  • 瀏覽器默認樣式表

  • 用戶樣式表

  • 做者連接樣式表

  • 做者嵌入樣式

  • 做者行內樣式

做者在書中是這麼描述的:

瀏覽器會按照上面的順序依次檢查每一個來源的樣式,並在有定義的狀況下,更新對每一個標籤屬性值的設定,整個檢查更新過程結束後,再將每一個標籤以最終設定的樣式顯示出來。

2.9.4 計算特指度

做者在這一節主要介紹了特指度的計算方法,相比做者個計算方式,筆者我的仍是比較喜歡本身以前的計算方式,雖然差很少,以下:

// 首先規定四個等級:A - B - C - D
  1. A 等級表明內聯樣式:例如 style=" ",權值爲:1000;

  2. B 等級表明 ID 選擇器:例如 #main,權值爲:100;

  3. C 等級表明類、僞類和屬性選擇器: .class[title],權值爲:10;

  4. D 等級表明元素(標籤)名或者僞元素選擇器:例如 p::after,權值爲:1。

    //計算完每一個值後再將每一個值加起來,哪一個值大哪一個值的權重就高。

例如:

body #main .class a[title]::after {}

咱們先分析它由哪些選擇器構成,上面這條規則有一個 id 選擇器(#main),一個類選擇器(.class),一個屬性選擇器([title])、一個僞元素選擇器(::after)和兩個標籤名選擇器(bodya),因此它的權重就等於:

100 × 1 + 10 × 2 + 1 × 3 = 123

還有一點要注意的是,權重值 001(12) 與 0020 相比,任然是 0020 的權重更高,對於權重同樣的狀況,則後聲明的樣式更高。

2.10 小結

做者在本章介紹了 CSS 的一些規則,好比各類選擇器的使用,層疊機制,還有權重的計算。

相關文章
相關標籤/搜索