摘要:每個元素都有一組樣式屬性,這些屬性涉及元素在文檔流中顯示時的不同方面,比如在文檔流中的位置邊框背景顏色等等。選擇符和要應用的樣式構成一條規則。上下文選擇器嚴格來講應該叫后代組合式選擇器。
原文地址:http://justclear.github.io/css-stylin-with-css-note-1
由于 CSS 作用的對象是 HTML ,所以作者在這章主要先講了一些基本的 HTML 標簽的用法和結構。
1.2 HTML 文檔剖析作者在這節主要講了一個 HTML 頁面所需的最基本的文檔結構如下:
Document
首先 是 HTML5 中新的文檔類型聲明語法,相比 HTML4 的冗長文檔類型聲明語法來說 HTML5 是大大的簡化了。
1.2.2 塊級元素和行內元素作者在這一節介紹了兩個比較重要的概念————塊級元素和行內元素,默認情況下塊級元素會始終占居一行,而行內元素并不會。除了 table 元素的 display 屬性比較特殊以外,基本上所有的 HTML 元素的 display 的屬性值要么是 block,要么是 inline。作者的一個思想是,無論你想了解哪個 HTML 元素,第一個要問的問題就是:它是塊級元素還是行內元素,然后在編寫標記的時候預想到這個元素在初始狀態下是如何定位的,這樣才能進一步想好將來怎么用 CSS 重新定位它,因為塊級元素和行內元素在定位上有很大的區別,后面的拓展會詳細說明。
塊級元素盒子(一個很重要的概念————盒模型,后面會詳細說明)會擴展到與父元素同寬,這也是為什么塊級元素會占居一行的原因了,因為所有塊級元素的父元素都是 body,而它的默認寬度就是瀏覽器的視口(viewport)大小,所以默認情況下塊級元素的寬度也和瀏覽器的視口一樣寬,這樣以來,一個塊級元素旁邊也就沒有空間來容納另一個塊級元素了。
相比于塊級元素會擴展到與父元素同寬,然而行內元素的行為卻是恰恰相反,它會盡量的「收縮包裹」其內容(也是盒模型的概念),這也就是為什么幾個行內元素會并排顯示在一行直到它們排滿一行才會另起一行,而每個塊級元素會直接另起一行的原因了。
拓展:
作者在這一節中并沒有對塊級元素和行內元素的一些其他特性進行詳細的解釋,在這里筆者對它們的一些特性知識進行拓展。首先先列出一些常見的塊級元素和行內元素:
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 的屬性值來讀取這個元素所包含的內容的,常見的替換元素還有 input 、textarea、 select、 object、 iframe 和 video 等等,這些元素都有一個共同的特點,就是瀏覽器并不直接顯示其內容,而是通過其某個屬性的值來顯示具體的內容,比如瀏覽器會根據 input 中的 type 的屬性值來判斷到底應該顯示單選按鈕還是多選按鈕亦或是文本輸入框。而對于非替換元素,比如 p、label 元素等等,瀏覽器這是直接顯示元素所包含的內容。看到這里你應該大概的知道了什么是替換元素和非替換元素了。
對著兩個概念有了大概的了解后就可以對 block 和 inline 在盒模型上的表現差異進行了解了,首先是 margin ,W3C 對其所支持了元素對象是這么定義的:
Applies to: all elements except elements with table display types other than table-caption, table and inline-table
英語不是很好,沒太明白這句話的意思,我的理解就是所有元素都支持 margin 除了 display 屬性值為 table-caption 和 table-inline 以外的所有表格顯示類型比如 table-row-group、 table-cell、 table-row 和 table-header-group等等,但是為了驗證我的理解,我發先 display 屬性值為 table 的元素也支持,可能是我對原文標準的理解有誤。但還有一個要特別注意的是 margin-top 和 margin-bottom 兩個屬性比較特殊,它們對非替換行內元素沒有效果,下面是 W3C 上對于 margin-top 和 margin-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-top 和 margin-bottom )屬性對非替換行內元素沒有效果比如 a 和 span,注意這里是非替換行內元素而不單單是非替換元素或者是行內元素。比如 img 就是一個行內元素, margin-top 和 margin-bottom 對它是有效果的,因為它是一個替換元素而不是非替換元素,所以對于「 margin-top 和 margin-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-group、 table-header-group、 table-footer-group、 table-row, table-column-group 和 table-column 的元素不支持,其他所有的元素都支持。
但這里有些特殊情況需要注意的是,對行內元素比如 span 和 img 設置左右內邊距的效果是可見可,但是對行內元素設置上下內邊距在有些情況下是不可見的,這些情況又要分為是否為替換元素和是否設置了背景色,為了能更直觀的了解這些概念,我在這里做了個表格:
padding-top 和 padding-bottom 對于行內元素是否可見:
替換元素(e.g: input) | 非替換元素(e.g: span) | |
---|---|---|
設置背景色 | 可見,影響行高,會撐開父元素 | 可見,不影響行高,不會撐開父元素 |
沒有設置背景色 | 可見,影響行高,會撐開父元素 | 不可見,不影響行高,不會撐開父元素 |
所以對于「 padding-top 和 padding-bottom 對行內元素沒有效果」這種說法也是不對的,因為它們只是對于沒有設置背景色的行內非替換元素效果不可見而已,而對于行內替換元素來說,不管是否設置了背景色都是有效果了,并且會把父元素撐開。
說了這么多 block 和 inline-block 的區別,其實除了這兩個常見的 display 屬性以外還有一個屬性也是非常常見的,那就是 inline-block ,沒錯,這就是前面兩種情況的結合體,它既有 block 的特性又有 inline 的特性,比如把一個 display 屬性值為 block 或者 inline 的元素屬性值設置成 inline-block 后,既可以用只對行內元素有效的 text-align: center; 聲明對其進行居中以外,還可以用 padding-top 和 padding-bottom 對元素設置上下內邊距而無需對其設置背景色,并且能把父元素撐開。
對于塊級元素和行內元素的拓展就暫時到這,如果有不明白或者不對的地方也歡迎指出。
1.3 文檔對象模型作者在這一小節只要介紹了 HTML 結構所對應的文檔對象模型(DOM,Document Object Model),DOM 是從瀏覽器的視角來觀察頁面中的元素以及每個元素的屬性,由此可以得出這些元素的一個家族樹。通過 DOM 可以很清晰的看出文檔中每個元素之間的關系。比如下面的 HTML 代碼的 DOM 的家族樹就如下圖:
The Document Object Model
The page"s HTML markup structure defines the 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 和類選擇器作者在這一節介紹了 id 和 class 選擇器,為我們選擇元素提供了另一種手段,利用它們可以不考慮元素在文檔流中的層次結構,只要在元素中添加了 id 和 class 屬性和值,我們就可以通過它們的值來找到目標元素。
2.4.3 什么時候用 id,什么時候用 class可以給 id 和 class 屬性設定任何值,但不能以數字或者特殊符號開頭。
id 的用途是在頁面中唯一地標識元素,所以每個頁面中每一個 id 屬性值都是獨一無二的。而 class 的目的是為了標識一組具有相同特征的元素,也就是說一個頁面中可以出現多個相同的類。
對于什么時候用 id 這個問題作者的觀點是:
每一個頂級區域都應該添加一個 id,從而得到非常明確的上下文關系,以便編寫 CSS 時只選擇嵌套在相應區域內的標簽。
對于什么時候使用 class,由于 class 的目的是為了標識一組具有相同特征的元素,所以如果當頁面中有一組元素具有某種相同的特征,就應該毫不猶豫的時候 class 了。
但是這里也應該注意不要亂用類,避免造成類泛濫,例如:
上面這個例子就是一個典型的類泛濫。
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`,如有: Learn More 就可以用 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偽類
鏈接偽類
link: 鏈接就在那兒等著用戶點擊。
visited:用戶此前點擊過這個鏈接。
hover:鼠標指針正懸停在連接上。
active:鏈接正在i被點擊(鼠標在元素上按下,還沒有釋放)。
注意以上幾種鏈接偽類要按一定的順序才有效果,為了方便記憶作者是這么建議的:"LoVe?HA!",大寫字母就是每個偽類的第一個字母,其實也可以這么記: "LoVe,HAte",其實都差不多就是了。
一個冒號(:)表示偽類,兩個冒號(::)表示 CSS3 新增的偽元素。
:focus 偽類
表單中的文本字段在用戶單擊它時會獲得焦點,例如:
input:focus {border: 1px solid blud;}
這段代碼的意思就是當用戶單擊表單中的文本字段的時候,為該 input 標簽添加寬度為 1px 的藍色實線邊框,需要注意的是,偽類的冒號要緊跟著標簽名,之間不能有空格,否則該聲明無效。
:target 偽類
如果用戶點擊一個指向頁面中其他元素的鏈接,則哪個元素就是目標(target),可以用 :target 偽類選中它,比如:
More Information
位于頁面其他地方、id 為 more-info 的那個元素就是目標元素,該元素可能是這樣的:
This is the information you are looking for.
那么 CSS 規則如下:
#more-info:target {background: #eee;}
此時會在用戶點擊鏈接轉向 id 為 more-info 的元素時,該目標元素的背景就會變成淺灰色。
2.6.2 結構化偽類
first-child 、 last-child 和 nth-child(n)
e:first-child e:last-child
first-child 和 last-child 分別代表一組同胞元素中的第一個元素和最后一個元素,而 nth-child(n) 則代表一組同胞元素中的任何一個元素,其中 n 表示一個整數(也可以是 odd-奇數 或 even-偶數)或者也可以是一個算數表達式(2n + 1),例如:
上面的 HTML 應用了上面的 CSS 規則后,無序列表的第一個元素字體顏色就會變成黑色,第二個元素變成紅色,最后一個元素就變成藍色。
2.7 偽元素顧名思義,偽元素就是文檔中若有實無的元素,下面是幾個比較常用的偽元素。
::first-letter 偽元素,比如:
p::first-letter {font-size: 300%;} 這樣 `p` 標簽的第一個字母大小就會變成原來的 3 倍了,而其他元素則不會。
::first-line 偽元素:可以選中文本段落的第一行。
::before 和 ::after 偽元素
e::before e::after 可用在特定元素前面或后面添加特殊內容,比如:25
.age::before { content: "Age: ";} .age::after { content: " years";} 這里需要注意的是,對于 `::before` 和 `::after` 偽元素,其 `content` 屬性是必須的,還有就是搜索引擎不會取得偽元素的信息(因為它在文檔流中并不存在),因此不要通過偽元素添加一些對搜索引擎來說是重要的內容。
拓展:
其實偽元素前面冒號可以是兩個也可以是一個,但是為了區別偽類,筆者建議大家還是使用兩個冒號。還有一個要注意的是,比如通過 ::before 和 ::after 偽元素為 class 為 pseudo-element 添加兩個偽元素,則生成的兩個偽元素分別處于 pseudo-element 元素的內部,也就是說是 pseudo-element 元素的子元素,并且分別位于 pseudo-element 元素的內容的最前面和最后面,代碼如下:
.pseudo-element::after, .pseudo-element::before { content: ""; }Pseudo Element
如上圖所示,生成的兩個偽元素分別處于 pseudo-element 元素的內部,并且分別位于 pseudo-element 元素的內容 p 標簽的前面和后面,而不是如下圖所示的位于 pseudo-element 元素外部的前面和后面:
2.9 層疊層疊就是層疊樣式表中的層疊,是一種樣式在文檔層次中逐層疊加的過程,目的是讓瀏覽器面對某個標簽特定屬性值的多個來源確定最終使用哪個值。
層疊是 CSS 的核心機制,理解了它才能以最經濟的方式寫出最容易改動的 CSS,讓文檔外觀在達到設計要求的同時,也給用戶留下一些空間,讓他們能根據需要更改文檔的顯示效果。
2.9.1 樣式來源作者在這一節中介紹了樣式的幾種來源:
瀏覽器默認樣式表
用戶樣式表
作者鏈接樣式表
作者嵌入樣式
作者行內樣式
作者在書中是這么描述的:
2.9.4 計算特指度瀏覽器會按照上面的順序依次檢查每個來源的樣式,并在有定義的情況下,更新對每個標簽屬性值的設定,整個檢查更新過程結束后,再將每個標簽以最終設定的樣式顯示出來。
作者在這一節主要介紹了特指度的計算方法,相比作者個計算方式,筆者個人還是比較喜歡自己之前的計算方式,雖然差不多,如下:
// 首先規定四個等級:A - B - C - D
A 等級代表內聯樣式:例如 style=" ",權值為:1000;
B 等級代表 ID 選擇器:例如 #main,權值為:100;
C 等級代表類、偽類和屬性選擇器: .class 和 [title],權值為:10;
D 等級代表元素(標簽)名或者偽元素選擇器:例如 p 和 ::after,權值為:1。
//計算完每個值后再將每個值加起來,哪個值大哪個值的權重就高。
例如:
body #main .class a[title]::after {}
我們先分析它由哪些選擇器構成,上面這條規則有一個 id 選擇器(#main),一個類選擇器(.class),一個屬性選擇器([title])、一個偽元素選擇器(::after)和兩個標簽名選擇器(body 和 a),所以它的權重就等于:
100 × 1 + 10 × 2 + 1 × 3 = 123
還有一點要注意的是,權重值 001(12) 與 0020 相比,任然是 0020 的權重更高,對于權重一樣的情況,則后聲明的樣式更高。
2.10 小結作者在本章介紹了 CSS 的一些規則,比如各種選擇器的使用,層疊機制,還有權重的計算。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/115070.html
摘要:原文地址本篇文章是筆者的設計指南學習筆記的第二部分,由于最近都在準備期末考的事,所以都沒來得及對設計指南進行一些總結,沒有看之前第一部分的話也可以從這里傳送過去。 原文地址:http://justclear.github.io/css-stylin-with-css-note-2 本篇文章是筆者的 《CSS 設計指南》 學習筆記的第二部分,由于最近都在準備期末考的事,所以都沒來得及對 ...
摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入匯總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應和斧正,會及時更新,平時業務工作時也會不定期更...
摘要:行內元素不會在它本身之前或之后生成分隔符,所以可以出現在另一個元素的內容中,而不會破壞其顯示。標記標記基本目的是允許創作人員將包含標記的文檔與其他文檔相關聯。更多細節請看權威指南 題外話:HTML是一種結構化語言,而CSS是它的補充;這是一種樣式語言。CSS是前端三板斧之一,因此學習CSS很重要。而我還是菜鳥,所以需要加強學習CSS。這個是我學習CSS權威指南的筆記,如有不對,請諒解和...
摘要:前言月份開始出沒社區,現在差不多月了,按照工作的說法,就是差不多過了三個月的試用期,準備轉正了一般來說,差不多到了轉正的時候,會進行總結或者分享會議那么今天我就把看過的一些學習資源主要是博客,博文推薦分享給大家。 1.前言 6月份開始出沒社區,現在差不多9月了,按照工作的說法,就是差不多過了三個月的試用期,準備轉正了!一般來說,差不多到了轉正的時候,會進行總結或者分享會議!那么今天我就...
閱讀 2262·2021-09-28 09:36
閱讀 1995·2021-09-22 15:14
閱讀 3623·2019-08-30 12:47
閱讀 3034·2019-08-30 12:44
閱讀 1226·2019-08-29 17:06
閱讀 535·2019-08-29 14:12
閱讀 973·2019-08-29 14:01
閱讀 2580·2019-08-29 12:17