持續修正版請參見這裏:githubcss
Cascading Style Sheets (CSS) 是一個可以改造文檔和文檔集合呈現的強大工具,它已經擴展到web的幾乎每一個角落以及許多看起來是非web的環境。例如,基於Gecko1的瀏覽器經過CSS影響Chrome瀏覽器的呈現,以及一些即時通信客戶端(如Adium)使用CSS來格式化聊天窗口。JavaScript框架(如jQuery)所使用的語法中能夠找到CSS的面孔。它無處不在!html
CSS於1994年首次被提出,正當Web開始真正流行的時候。事實上,最終成爲CSS(被命名爲Cascading HTML Style Sheets)的第一個草案發表於Mozilla(其後成爲Netscape Navigator)初版被公佈的僅僅幾天前。git
當時,瀏覽器賦予用戶各類樣式化能力——例如,在Mosaic2的顯示偏好中,容許用戶基於每一個元素定義全部風格的字體系列、尺寸和顏色。而文檔開發者卻沒法作到這些,他們所能作的只是把一段內容標記爲段落、做爲某級標題、做爲預約義格式的文本或者其它不多量的元素類型中的一個。若是用戶配置本身的瀏覽器,把全部一級標題設置成「微小」和粉色,而把六級標題設置爲「巨大」和紅色,那瀏覽器就會如用戶所設置的顯示。github
CSS就是在這種背景下引入的。它的目標很簡單:提供一種簡單的、聲明式的樣式語言供文檔開發者靈活地使用,更重要的是,爲開發者和用戶提供一樣的樣式化能力。經過「層疊(cascade)」的手段,這些樣式能夠組合並按優先級排序,讓開發者和閱讀者都有對樣式的控制權——儘管閱讀者老是有最終的控制權。web
工做迅速推動,到1996年年末,CSS1完成了。新成立的CSS工做組繼續向前推動CSS2,瀏覽器們則在盡力以相互兼容的方式實現CSS1。儘管每一個單獨的CSS片斷都是至關簡單的,但它們的組合卻產生了使人意外的複雜行爲。早期的實現還存在一些不幸的失誤,好比今天已經臭名昭著的框模型實現的差別。這些問題使CSS面臨被徹底破壞的威脅,但幸運的是一些聰明的提案被實現了,瀏覽器們也開始協調起來了。幾年內,得益於持續增長的互通性和高關注度的開發者(如基於CSS從新設計的《連線(Wired)》雜誌和CSS禪意花園(Zen Garden)),CSS開始真正流行起來。chrome
在這一切發生以前,CSS工做組已經在1998年初完成了至關重的CSS2規範。CSS2一完成,CSS3(以及一個CSS2的清晰化版本:CSS2.1)的工做就當即開始了。與時俱進的CSS3被構造爲一系列(理論上的)獨立模塊,而不是單個的總體規範。這種作法體現了當時活躍的XHML規範的影響,它(XHML)也由於相似的緣由被拆分紅模塊。瀏覽器
把CSS3模塊化的理由是,每一個模塊能夠按照本身的步調發展,特別關鍵(或流行)的模塊能夠隨着W3C的路線先行推動,而沒必要被其它模塊拖延。事實也正是這樣。到2012年初,3個CSS3模塊(與CSS1和CSS 2.1一塊兒)實現了完整推薦3狀態——CSS Color Level 三、CSS Namespaces和Selectors Level 3。與此同時,七個模塊正處於候選推薦4狀態,其它幾十個模塊處在工做草案的不一樣階段。按照之前的作法,顏色、選擇器和命名空間三個模塊將不得不等待規範中的全部其它模塊都被完成或取消,才能做爲完整規範的一部分被提案。得益於模塊化,它們不須要等待規範的其它部分了。緩存
模塊化好處的另外一面是,很難說一個單一的「CSS3規範」。事實上沒有也不會有這樣一個東西。即使其它每一個CSS3模塊都完成了——假如,在2014年末——可能那時已經有一個Selectors Level 4正在推動中甚至已經要完成了,咱們應該把它叫作CSS4嗎?若是這樣的話,其它尚在使用中的CSS3特性算什麼呢?服務器
因此,雖然咱們不能指着一個大部頭說:「這就是CSS3」,但咱們能夠對每一個模塊名稱及它們所指代的功能特性進行討論。模塊靈活性上的好處遠遠大於它們引入的語義上尷尬的壞處。app
元素是文檔結構的基礎。在HTML中,最多見的元素很容易識別,例如p
、table
、span
、a
和div
。每一個元素都在文檔展現展現中扮演各自的角色。
雖然CSS依賴於元素,但並不是全部的元素都同樣。例如,圖片和段落就不是同類型的元素,span
和div
也不是。在CSS中,元素一般有兩種形式:替換的和非替換的。
替換元素是指那些內容會被其它東西所替換的元素,這些東西並不直接體如今文檔內容裏。在HTML中最爲人所熟悉的例子大概就是img
元素了,它會被存儲在文檔外部的一個圖片文件所替代。事實上,img
元素沒有實在的內容,正以下面的簡單示例中所展現的:
<img src="howdy.gif" >
這個代碼片斷只包含元素名稱和屬性。 除非你把它指向外部內容(這裏是由src
屬性指定的圖片),這個元素不會顯示任何內容。 若是把它指向有效的圖片文件,則圖片將被放置在文檔中。反之,它將不顯示任何內容或者瀏覽器將在這裏放置一個「損壞圖像」的佔位符。
相似地,input
元素也會被替換爲單選按鈕、複選框或文本輸入框 —— 這取決與input
元素的type
屬性。
大部分HTML元素是非替換元素。這意味着元素的內容會被用戶代理(一般是瀏覽器)顯示在一個由元素本身生成的「盒子」裏。例如,<span>hi there</span>
是一個非替換元素,文字「hi there」會由用戶代理顯示。對於段落、標題、表格單元格、列表以及HTML中的其餘大部分元素都是如此。
除了替換和費替換元素,CSS2.1還使用另外兩種基本類型來區分元素:塊級(block-level)和行內級(inline-level)。曾經花費時間在HTML標籤和它們在web瀏覽器中顯示上的開發者,會對這兩個類型更加熟悉。元素在圖1中展現。
圖1:HTML文檔中的塊級和行內元素
塊級元素生成一個(默認狀況下)填充其父元素的內容區域的元素框,而且在其兩側不能有其餘元素。 換句話說,它在元素框以前和以後生成「斷行」。 HTML中最多見的塊元素是p
和div
。 替換元素能夠是塊級元素,但一般它們不是。
列表項是一種特別的塊級元素。 除了與其餘塊級元素一致的行爲以外,它們還生成一個標記(一般是用於無序列表的項目符號和用於有序列表的數字)並「附加到」元素框。 除了這個標記,列表項與其餘塊級元素的行爲徹底相同。
行內元素在文本行內生成一個元素框,而且不會破壞該行的流。HTML中行內元素的最好例子是a
元素,其它還有strong
和em
。這些元素不會在自身以前或以後生成「斷行」,因此它們能夠出如今其它元素的內容之中,而且不會破壞其顯示。
須要注意,雖然名稱「塊級」和「行內」與HTML中的塊和行內元素有不少共同之處,但還有個重要區別:在HTML中,塊級元素不能做爲行內元素的後代;但在CSS中,對顯示角色之間的嵌套沒有限制。
要了解其工做原理,咱們來考慮一個CSS屬性display
:
取值:
none | inline | block | inline-block | list-item | run-in | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table- column-group | table-column | table-cell | table-caption | inherit
初始值:
inline
適用元素:
全部元素
繼承:
否
計算值:
因浮動,定位和根元素而異(參見CSS2.1,第9.7節); 其它狀況按規範取值
你可能已經注意到了這裏有許多取值,只有其中三個是我提到過的:block
、inline
和list-item
。
如今咱們把注意力放在block
和inline
上,看下面的代碼:
<body> <p>This is a paragraph with <em>an inline element</em> within > it.</p> </body>
這裏有兩個塊級元素(body
和p
)和一個行內元素(em
)。根據HTML規範,em
能夠做爲p
的後代,但反過來則不行。一般HTML的層級結構容許行內元素做爲塊級元素的後代,而不是相反。
另外一方面,CSS則沒有這樣的限制。你能夠保持現有的標籤結構,而後像這樣修改這兩個元素的顯示角色:
p {display: inline;} em {display: block;}
這使得元素在一個行內框裏面生成了一個塊級框,這在CSS中是徹底合法的,不會破壞任何規範。可是,若是你想在HTML中使用相反的嵌套結構,那就有會問題了,像這樣:
<em><p>This is a paragraph improperly enclosed by an inline element.</p></em>
無論你如何使用CSS來修改它們的顯示角色,這在HTML中都是不合法的。
修改元素的顯示角色在HTML文檔中頗有用,它對XML文檔也相當重要。XML文檔通常沒有默認的顯示角色,而徹底依賴文檔開發者去定義它們。例如,若是你想要展現下面的XML片斷:
<book> <maintitle>Cascading Style Sheets: The Definitive Guide</maintitle> <subtitle>Third Edition</subtitle> <author>Eric A. Meyer</author> <publisher>O'Reilly and Associates</publisher> <pubdate>November 2006</pubdate> <isbn type="print">978-0-596-52733-4</isbn> </book> <book> <maintitle>CSS Pocket Reference</maintitle> <subtitle>Third Edition</subtitle> <author>Eric A. Meyer</author> <publisher>O'Reilly and Associates</publisher> <pubdate>October 2007</pubdate> <isbn type="print">978-0-596-51505-8</isbn> </book>
由於display
屬性的默認值是inline
,因此這塊內容會默認被顯示爲行內文本,就像圖2所示的那樣。這樣的排版不太有用。
圖2:一個XML文檔的默認顯示
你能夠用display
來定義文檔的基本板式:
book, maintitle, subtitle, author, isbn {display: block;} publisher, pubdate {display: inline;}
這樣把7種元素中的5個設置成塊級元素,2個設置成行內元素。塊級元素會被像HTML中的div
那樣處理,兩個行內元素會被相似span
那樣處理。
由於這種設置顯示角色的基本能力,CSS在各類場景下都很是有用。你能夠從上面的規則開始,添加一些更具視覺效果的樣式,而後獲得像圖3這樣的顯示效果。
圖3:添加了樣式的XML文檔
在詳細學習如何編寫CSS以前,咱們先要看一下如何關聯CSS和文檔,畢竟,若是不把它們結合在一塊兒,CSS是沒法對文檔起做用的。咱們從最熟悉的HTML設置開始。
我提到過HTML文檔存在一個固有結構,這一點值得重複一下。事實上這是舊網頁問題的一部分:咱們太多人忘記了文檔是應該有一個內在結構的,這與一個視覺上的結構是徹底不一樣的。咱們急於在Web上建立看起來最酷的網頁,咱們改造轉換、修飾裝點,全然忽視了頁面應該包含具備一些結構意義的信息。
這種結構是HTML和CSS之間關係所固有的組成部分,沒有它,關係就不會存在。爲了更好地理解這種結構,咱們把下面這個示例的HTML文檔拆解來看:
<html> <head> <title>Eric's World of Waffles</title> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <link rel="stylesheet" type="text/css" href="sheet1.css" media="all"> <style type="text/css"> /* These are my styles! Yay! */ @import url(sheet2.css); </style> </head> <body> <h1>Waffles!</h1> <p style="color: gray;">The most wonderful of all breakfast foods is the waffle—a ridged and cratered slab of home-cooked, fluffy goodness that makes every child's heart soar with joy. And they're so easy to make! Just a simple waffle-maker and some batter, and you're ready for a morning of aromatic ecstasy! </p> </body> </html>
代碼的處理結果及應用的樣式的如圖四所示。
圖片4:一個簡單文檔
如今咱們來看文檔關聯CSS的幾種方式。
link
標籤首先是link
標籤的使用:
<link rel="stylesheet" type="text/css" href="sheet1.css" media="all">
link
標籤是一個有些被忽視的標籤,但它是在HTML規範中存在了許多年的合法標籤,一直在等着被善加利用。它最初的目的是容許HTML開發者把包含連接標籤的文檔與其餘文檔關聯起來。CSS使用Link
標籤把樣式表連接到文檔中,如圖5,一個名爲sheet1.css
的樣式表被鏈接到文檔。
圖片5:展現外部樣式表如何被應用到文檔
這些樣式表不是HTML文檔的一部分但仍被應用於文檔中,它們被稱爲外部樣式表,由於它們存在於HTML文檔的外部(看圖)。
連接必須放置在head
元素內,外部樣式才能成功加載,與title
不一樣,它不能被放置在任何其它元素裏。像圖5所示的那樣,web瀏覽器會定位並加載樣式表,而後把樣式表中的任何樣式都應用在HTML文檔渲染中。圖5中還展現了使用@import
聲明加載的外部樣式sheet2.css
。@import
必須在包含它的樣式表的開頭5,除此以外沒有其它限制。
那麼外部樣式表是什麼樣的格式呢?和咱們在前面章節中和在示例HTML文檔中看到的那些樣式同樣,外部樣式也是簡單的規則列表,可是這些規則存儲在本身的文件裏面。要記住,HTML和其它任何標記語言都不能放進樣式表中——它只能包含樣式規則。一個外部樣式表的內容是這樣的:
h1 {color: red;} h2 {color: maroon; background: white;} h3 {color: white; background: black; font: medium Helvetica;}
這就是它的所有內容——沒有HTML標記或者註釋,只有乾淨簡單的樣式聲明。它們被存儲在純文本文件中,一般用.css
做爲後綴,例如sheet1.css
。
外部樣式中不能包含任何文檔標記,只能包含CSS規則和CSS註釋,咱們將在後面的章節解釋它們。外部樣式表中的標記可能會致使其中的所有或部分樣式被忽略。
文件擴展名不是必需的,但若是文件名不是以.css
結尾,即便你在link
元素中設置了正確的文件類型text/css
,一些舊瀏覽器依然沒法把文件識別爲樣式表。實際上,若是文件名不是以.css
結尾,一些web服務器不會把文件當作text/css
來處理,但一般這個問題能夠經過修改服務器配置文件來解決。
對於link
標籤的其它部分,屬性和值都很直白。rel
表示「關係」(relation),這裏關係就是stylesheet
(樣式表)。type
屬性始終設置爲text/css
,這個值描述了被link
標籤加載的數據的類型。這樣,web瀏覽器就能夠知道這個樣式表是一個CSS樣式表,這決定着瀏覽器如何處理它引入的數據。畢竟,未來可能會用到其它樣式語言,因此聲明你所使用的是哪一種語言是有必要的。
接下來是href
屬性,這個屬性的值是樣式表的URL。這個URL能夠是絕對或相對地址,這取決於你的須要。固然在咱們的示例中URL是相對的,顯然它也能夠是http://meyerweb.com/sheet1.css.
這種形式。
最後是media
屬性,這個屬性的值是一個或多個媒體描述符。媒體描述符是關於媒體類型和這些媒體的特性的規則,每一個規則之間用逗號分隔。例如,你在屏幕和投影媒體上均可以使用一個這樣的連接樣式表:
<link rel="stylesheet" type="text/css" href="visual-sheet.css" media="screen, projection">
媒體描述符能夠設置得很是複雜,咱們將會在本章中稍後的部分作詳細解釋。如今咱們只使用基本的媒體類型。
注意,一個文檔能夠關聯多個樣式表。這時,只有那些包含rel
屬性值爲stylesheet
的樣式表會被用於文檔的初始顯示。所以,若是你想分別連接兩個名爲basic.css
和splash.css
的樣式表,看起來會像這樣:
<link rel="stylesheet" type="text/css" href="basic.css"> <link rel="stylesheet" type="text/css" href="splash.css">
這種寫法會使瀏覽器加載兩個樣式表,併合並每一個樣式表的規則,而後把它們所有應用於文檔。例如
<link rel="stylesheet" type="text/css" href="basic.css"> <link rel="stylesheet" type="text/css" href="splash.css"> <p class="a1">This paragraph will be gray only if styles from the stylesheet 'basic.css' are applied.</p> <p class="b1">This paragraph will be gray only if styles from the stylesheet 'splash.css' are applied.</p>
有一個能夠可是並無在示例代碼中出現的屬性title
。這個屬性並不經常使用,但它可能會在將來變得重要,若是使用不當會帶來意想不到的效果。爲何呢?咱們將在下一節中探討。
能夠定義備用樣式表。它們是經過把rel
屬性的值設爲alternate stylesheet
來實現的,並且它們只有被用戶選擇的時候纔會用於文檔顯示。
若是瀏覽器可以使用備用的樣式表,它會用link
元素的title
屬性值來生成一個可選擇的樣式列表。你能夠像下面這樣寫:
<link rel="stylesheet" type="text/css" href="sheet1.css" title="Default"> <link rel="alternate stylesheet" type="text/css" href="bigtext.css" title="Big Text"> <link rel="alternate stylesheet" type="text/css" href="zany.css" title="Crazy colors!">
而後用戶就能夠選擇他們想用的樣式,瀏覽器將會從第一個(這裏被標記爲「默認」(Default))切換到用戶選擇的任意一個。圖6展現了這種選擇機制的一個可能的(其實是CSS再次興起的早期所使用的)完成方式。
圖6:一個支持選擇備用樣式的瀏覽器
在2012年初,大部分基於Gecko引擎的瀏覽器已經支持了備用樣式表,如Firefox和Opera。在Internet Explorer系列的瀏覽器中可使用JavaScript實現支持,可是沒有被瀏覽器原生支持。Webkit系列瀏覽器不支持選擇備用樣式表。(相比之下,圖6所示的這麼老舊的瀏覽器都提供了支持,真是使人驚訝。)
經過給title
屬性賦相同的值,備用樣式表能夠分組組合。所以,你可讓用戶在不管屏幕媒體仍是打印媒體中都能選擇不一樣的展現方式。例如:
<link rel="stylesheet" type="text/css" href="sheet1.css" title="Default" media="screen"> <link rel="stylesheet" type="text/css" href="print-sheet1.css" title="Default" media="print"> <link rel="alternate stylesheet" type="text/css" href="bigtext.css" title="Big Text" media="screen"> <link rel="alternate stylesheet" type="text/css" href="print-bigtext.css" title="Big Text" media="print">
若是用戶在支持備用樣式表選擇機制的用戶代理中選擇了「Big Text」,那麼bigtext.css
將在屏幕媒體中爲文檔設置樣式,而print-bigtext.css
將會被用在打印媒體上。sheet1.css
和print-sheet1.css
不會被用在任何一個媒體中。
爲何會這樣?由於一旦你爲一個rel
屬性值爲styleshet
的link
標籤設置了title
,你就指派了這個樣式表爲優先樣式表。這表示它會比備用樣式表優先被使用,會被用在文檔第一次顯示的時候。可是,當你選擇了一個備用樣式表的時候,優先樣式表就不會再被使用了。
此外,若是你把多個樣式表都指派爲優先使用,那麼除了一個以外全部其它的樣式表都會被忽略。考慮下:
<link rel="stylesheet" type="text/css" href="sheet1.css" title="Default Layout"> <link rel="stylesheet" type="text/css" href="sheet2.css" title="Default Text Sizes"> <link rel="stylesheet" type="text/css" href="sheet3.css" title="Default Colors">
因爲都被設置了title
屬性,三個link
元素都被指定爲優先樣式表,但只有一個會被真正被做爲優先樣式表,而另外兩個會徹底被忽略。哪兩個呢?沒有辦法肯定。由於HTML並無提供一種方式,來決定哪一個樣式應該被忽略,哪一個樣式應該被使用。
若是你根本不給樣式表設置title
,它將變成一個持久的樣式表,並一直用在文檔顯示中。一般這正是開發者想要的。
style
元素一種包含樣式表的方法是使用style
元素,它像這樣顯示在文檔中:
<style type="text/css">...</style>
style
須要設置type
屬性,與link
標籤同樣,使用CSS文檔的時候type
值應該設置爲text/css
。
就像上面的示例所表示的,style
元素老是以<style type="text/css">
開始。後面緊接着是一個或多個樣式,最後一一個關閉標籤</style>
做結束。style
也能夠指定一個media
屬性,它的做用與前面介紹的在連接樣式表中的功能是同樣的。
這種在style
開始和結束標籤之間的樣式被稱爲文檔樣式表或者內嵌樣式表(由於這種樣式表是嵌入在文檔裏的)。內嵌樣式表包含許多應用於文檔的樣式,也可使用@import
指令連接至多個外部樣式。
@import
指令如今咱們開始討論style
標籤內部。首先是與link
很是相似的@import
指令:
@import url(sheet2.css);
像link
同樣,@import
能夠指示瀏覽器加載一個外部樣式而後把它應用到HTML文檔渲染中。它們之間主要的區別只是在於語法和命令的位置。正如咱們看到的這樣,@import
是被包含在style
中的。命令必須放在其餘CSS規則以前,不然它不會生效。看這個例子:
<style type="text/css"> @import url(styles.css); /* @import comes first */ h1 {color: gray;} </style>
與link
相同的是,一個文檔中能夠有多個@import
聲明。但與link
不一樣的是,@import
指令中的每一個樣式表都會被加載和使用,@import
不能設置備選樣式表。所以,若是使用下面的代碼:
@import url(sheet2.css); @import url(blueworld.css); @import url(zany.css);
所有三個外部樣式都會被加載,它們的樣式規則也都會被用於文檔顯示中。
相似link
,你能夠在樣式表的URL後添加媒體描述符,來限制樣式表被用於一個或多個媒體:
@import url(sheet2.css) all; @import url(blueworld.css) screen; @import url(zany.css) projection, print;
正如在link
元素的章節中介紹的,媒體描述符可能會很是複雜,咱們將在後面的章節詳細介紹。
若是你想要在一個外部樣式表中使用另外一個外部樣式表,@import
很是有用。由於外部樣式表不能包含任何文檔標記,link
元素就沒法使用,但@import
卻能夠。因此,一個外部樣式表多是這樣的:
@import url(http://example.org/library/layout.css); @import url(basic-text.css); @import url(printer.css) print; body {color: red;} h1 {color: blue;}
這些不是真正使用的樣式,可是你能夠經過它們看到@import
的用法。上例中同時使用了絕對和相對URL,像link
同樣,兩種都URL格式均可以使用。
還要注意,正如咱們在示例文檔中所作的,@import
指令出如今樣式表的開頭。CSS要求@import
指令出如今樣式表的其它規則以前。出如今其它規則(例如:body {color: red;}
)以後的@import
會被標準的用戶代理所忽略。
在Windows系統上的舊版的Internet Explorer瀏覽器中,即便@import
指令放在其餘規則以後,也不會被忽略。但其餘瀏覽器會忽略位置不正確的@import
指令,這很容易致使放置不正確的@import
引發其餘瀏覽器的顯示錯誤。
把CSS關聯到文檔還有一種很是晦澀的方式:你能夠經過HTTP標頭把它們連接在一塊兒。
在Apache環境下,能夠在.htaccess
文件中添加CSS的文件引用來完成關聯,例如:
Header add Link "</ui/testing.css>;rel=stylesheet;type=text/css"
支持該特性的瀏覽器會將引用的樣式表與任何該.htaccess
文件配置下的文檔相關聯,瀏覽器會把它當作一個連接樣式表。另外一個可能更有效的選擇是,把相同的規則添加到服務器的httpd.conf
文件中:
<Directory /path/to/ /public/html/directory> Header add Link "</ui/testing.css>;rel=stylesheet;type=text/css" </Directory>
對支持該特性的瀏覽器來講,這兩種方式效果是同樣的,惟一的區別是隻是你在哪裏聲明連接而已。
你確定注意到了前面所使用的「支持該特性的瀏覽器」。至2012年初,被普遍使用的瀏覽器中支持HTTP連接樣式表的有Firefox系列和Opera。這使得大部分狀況下這項技術被限制在使用這些瀏覽器的開發環境中。在這些環境中,你能夠在測試服務器上使用HTTP連接來標記測試環境網頁,從而與發佈的公共版網頁區分開來。這項技術仍是一種有趣的用來對WebKit和Internet Explorer系列瀏覽器隱藏樣式的方法——假如你基於某些緣由須要這麼作的話。
等價的技術存在於通用腳本語言中,如PHP和IIS,這兩種語言都容許開發者發出HTTP頭。使用這些語言能夠向服務器的文檔中寫入link
元素。這種技術有瀏覽器的更好的支持:每一個瀏覽器都支持link
元素。
若是你只想簡單地爲一個單獨元素設置一些樣式,不須要使用內嵌或者外部樣式表,使用HTML的style
屬性來設置行內樣式便可:
<p style="color: gray;">The most wonderful of all breakfast foods is the waffle—a ridged and cratered slab of home-cooked, fluffy goodness... </p>
除了位置在body
以外的標籤(head
及title
等),style
屬性能夠設置在任何HTML標籤上。
style
屬性的語法很普通,跟style
元素裏面的規則聲明很像,只不過花括號被換爲雙引號。<p style="color: maroon; background: yellow;">
會把當前段落的文本設置爲栗色,把背景設置爲黃色,文檔的其它部分不會受到這些樣式聲明的影響。
請注意,行內style
屬性只能放置樣式規則聲明塊,而不是整個樣式表。所以,style
屬性裏既不能放置@import
,也不能放進任何完整的樣式規則,style
屬性的值只能被設置爲樣式規則花括號裏面的那部分。
style
屬性一般不建議使用,實際上它也不大可能出如今HTML以外的XML語言中。當把樣式放置在style
屬性中時,許多CSS的主要優點——例如將整個文檔或服務器的全部文檔的樣式集中組織的能力——便沒法有效發揮了。從許多方面來講,使用行內樣式並不比使用font
標籤好多少,儘管處理視覺效果的時候它確實(比font
標籤)更靈活。
經過媒體查詢,開發者能夠定義不一樣媒體環境中瀏覽器可使用的樣式表。過去,這是經過使用media
屬性來爲link
元素或style
元素設置媒體類型,以及經過@import
或@media
聲明的媒體描述符來處理的。如今媒體查詢使這個概念更進一步,容許開發者經過使用所謂的媒體描述符,基於給定媒體類型的特性來選擇樣式表。
媒體查詢可使用在如下位置:
link
元素的media
屬性。style
元素的media
屬性。@import
聲明的媒體描述符部分。media
聲明的媒體描述符部分。媒體查詢能夠是簡單的媒體類型,也能夠是媒體類型和特性的複雜組合。
媒體類型最基礎的形式是媒體類型,首次出現於CSS2中。它們是表示不一樣類型媒體的簡單標籤。它們是:
all
用於全部演示媒體。
aural
用於語音合成器、屏幕閱讀器和文檔的其它音頻渲染媒體。
braille
用於布萊葉盲文渲染文檔。
embossed
用於布萊葉盲文設備的打印。
handheld
用於我的設備助理(PDA)或可以使用web的手機等手持設備。
print
用於可視用戶打印文檔以及顯示文檔的打印預覽。
projection
用於投影媒體,例如演講時用於展現幻燈片的數字投影儀。
screen
用於在桌面電腦顯示器等屏幕媒體中顯示文檔。在此類系統上運行的全部Web瀏覽器都是屏幕媒體用戶代理。
tty
用於固定間距顯示環境(如電傳打印機)中傳送文檔時使用。
tv
用於電視機中顯示文檔。
這些媒體類型的大多數都不能被當前的web瀏覽器所支持。最被普遍支持的三個類型是all
、screen
和print
。在撰寫本文時6,一些瀏覽器還支持projection
類型,容許把文檔顯示成幻燈片,一些移動設備瀏覽器支持handheld
類型。
可以使用逗號分隔的列表指定多個媒體樣式。下面的四個例子使用了相同的方式,把樣式表(或樣式規則代碼塊)應用於屏幕和投影媒體。
<link type="text/css" href="frobozz.css" media="screen, projection"> <style type="text/css" media="screen, projection">...</style> @import url(frobozz.css) screen, projection; @media screen, projection {...}
有趣的是當向這些媒體類型添加特性描述符(例如描述媒體分辨率和色深的值)時。
爲link
元素或者@import
聲明設置過媒體類型的開發者,將會對媒體查詢(描述符)的位置很是熟悉。下面是在彩色打印機上渲染文檔時應用外部樣式表的兩種基本等效的方法:
<link href="print-color.css" type="text/css" media="print and (color)" rel="stylesheet"> @import url(print-color.css) print and (color);
任何使用媒體類型的地方,均可以使用媒體查詢(描述符)。這意味着對上面的例子,可使用逗號分隔能夠列出多個查詢:
<link href="print-color.css" type="text/css" media="print and (color), projection and (color)" rel="stylesheet"> @import url(print-color.css) print and (color), projection and (color);
任何狀況下,只要任何一個(逗號分隔的)媒體查詢的判斷結果爲「真」,就會使用關聯的樣式表。所以,在前面的@import
中,print-color.css
將會被應用於彩色打印機或彩色投影環境的渲染。若是在黑白打印機上打印,兩個查詢的結果都是「假」,則print-color.css
不會被應用於文檔,對於任何屏幕媒體、灰階(非彩色)投影環境、聽覺媒體環境等都是如此。
每一個媒體描述符由一個媒體類型和一或多個媒體特性組成,每一個媒體特性描述符都被包括在括號中。若是沒有指定媒體類型,它將被默認設置爲all
,所以下面兩個示例是徹底等價的:
@media all and (min-resolution: 96dpi) {...} @media (min-resolution: 960dpi) {...}
通常來講,媒體特性描述符的格式相似於CSS中的屬性-值對,但有一些區別。最明顯的區別是能夠指定一些沒有值的特性,例如,使用(color)
來匹配任何基於顏色的媒體,而使用(color: 16)
來匹配16位色深的顏色媒體。實際上,不含值的描述符是一個對特性是否存在的一個真/假值判斷:(color)
表示判斷「是不是顏色媒體?」。
多個特性描述符可使用邏輯關鍵字and
連接,媒體查詢裏面有兩個邏輯關鍵字:
and
使用這種方式連接兩個或多個媒體特性時,只有當每一個媒體特性都爲真,總的查詢結果才爲真。例如,(color) and (orientation: landscape) and (min-device-width: 800px)
表示三個條件必須都被知足:當媒體環境具備顏色、橫向顯示,並且設備的顯示寬度至少爲800像素時,樣式表纔會被使用。
not
對整個查詢求反,若是全部的條件都爲真,樣式表則不會被使用。例如,not (color) and (orientation: landscape) and (min- device-width: 800px)
表示若是三個條件被知足,則表達式會被否認。所以,當媒體環境具備顏色、橫向顯示,而且設備顯示寬度至少爲800像素時,樣式表不會被使用;反之在其它任何狀況下,樣式表都會被使用。 請注意,not
關鍵字只能用在媒體查詢的開頭。(color) and not (min-device-width: 800px)
這樣的用法是不合法的,在這種狀況下,查詢會被忽略。一樣須要注意的是,太舊的瀏覽器會由於沒法理解媒體查詢而老是跳過媒體描述符以not
開頭的樣式表。
媒體查詢中沒有「或」關鍵字,但分隔查詢列表的逗號能夠起到「或」的做用——screen, print
表示「若是媒體是屏幕或打印機,則應用樣式」。設置screen and (max-color: 2) or (monochrome)
將會被忽略,應該寫成screen and (max-color: 2), screen and (monochrome)
來代替。
另外還有一個關鍵字only
,專門用於向後兼容。是的,你沒看錯。
only
@import url(new.css) only all
。對於可以理解媒體查詢的瀏覽器,only
關鍵字會被忽略,樣式表會被使用;對不能理解媒體查詢的瀏覽器,only
關鍵字會建立一個顯式的媒體類型only all
,而這是非法的,所以樣式表不會應用於這樣的瀏覽器中。要注意,only
關鍵字只能用在媒體查詢的開頭。咱們已經在示例中見過了一些媒體特性描述符,如今咱們來看描述符和它們取值的完整列表。
請注意,下面的取值都不能爲負數,並且特性描述符老是在括號內。
描述符:width, min-width, max-width
(min-width: 850px)
表示當視口寬度大於850像素時有效。描述符:device-width, min-device-width, max-device-width
7
(max-device-width: 1200px)
表示當設備輸出區域寬度小於1200像素時有效。描述符:height, min-height, max-height
(height: 567px)
表示當視口高度剛好爲567像素的時候有效。描述符:device-height, min-device-height, max-device-height
(max-device-height: 400px)
表示當設備輸出區域高度小於400像素時有效。描述符:aspect-ratio, min-aspect-ratio, max-aspect-ratio
width
和媒體特性height
的比值(請看下一節中關於ratio
的定義)。所以,(min- aspect-ratio: 2/1)
表示當視口的寬高比至少爲2:1時有效。描述符:device-aspect-ratio, min-device-aspect-ratio, max-device-aspect- ratio
device-width
和媒體特性device-height
的比值(請看下一節中關於ratio
的定義)。所以,(device-aspect-ratio: 16/9)
表示當輸出設備的寬高比正好是16:9時有效。描述符:color, min-color, max-color
(color)
表示對全部色深的設備有效,而(min-color: 4)
表示每一個顏色份量至少是4位色深。不支持顏色的設備將會返回0值。描述符:color-index, min-color-index, max-color-index
(min- color-index: 256)
表示當設備擁有至少256個顏色時有效。描述符:monochrome, min-monochrome, max-monochrome
(monochrome)
表示當單色輸出設備時有效,而(min-monochrome: 2)
表示當單色輸出設備幀緩存中的每一個像素至少爲2位時有效。描述符:resolution, min-resolution, max-resolution
resolution
>定義。當輸出設備不是正方形像素時,會使用最小密度的軸向,例如,若是一個設備在一個軸(水平或垂直)上的密度是100dpcm而在另外一個軸上的密度是120dpcm,那麼100會做爲返回值。另外,在非正方形像素狀況下,僅指定resolution
特性的任何值都不能成功匹配8(儘管min-resolution
和max-resolution
能夠)。描述符:orientation
portrait | landscape
height
值大於等於媒體特性width
值時取值爲portrait
,不然取值爲landscape
。描述符:scan
progressive | interlace
tv
的輸出設備的掃描方式9。描述符:grid
0 | 1
tty
終端)。柵格設備會取值爲1,不然取0值。媒體查詢引入了兩種以前(2012年初)未在其它場景下使用過的新值類型。這兩種類型與特定的媒體特性結合使用,下一節將詳細說明。
<比率>
比率值由兩個被斜線(/)分開的正整數值,和可選的空格組成。第一個(正整數)值表示寬度,第二個表示高度。所以,要表示寬高比是16:9,能夠寫成16/9或者16 / 9。到撰寫本文時,比率值不支持設置爲單個實數或者使用冒號代替斜線。
<分辨率>
分辨率值是正整數,後跟單位標識符dpi(每英寸點數)或dpcm(每釐米點數)。在CSS術語中,「點」能夠是任何顯示單位,其中常見的是像素。 整數值和標識符之間不容許有空格。 所以,一個每英寸正好具備150個像素(點)的顯示器與值150dpi
匹配。
那麼,樣式表的內容究竟是什麼樣呢?像這樣:
h1 {color: maroon;} body {background: yellow;}
各類各樣的嵌入樣式表都是有這樣的內容組成,不管內容長短,簡單仍是複雜。不多有文檔的style
元素不包含任何規則——儘管有的文檔可能只包含一個簡單的@import
聲明列表而沒有像上面那樣的真正的規則。
在開始本書的其它內容以前,咱們首先須要確認樣式表中能包含哪些東西,以及不能包含哪些東西。
樣式表中沒有標記。這彷佛是顯而易見的,但可能會讓你驚訝的是,有一個HTML註釋標記是例外,由於歷史緣由它容許存在於style
元素中:
<style type="text/css"><!-- h1 {color: maroon;} body {background: yellow;} --></style>
就這樣。
咱們把結構分解,詳細地說明規則的概念。
每條規則由兩個基本部分構成:選擇器和聲明塊。聲明塊由一個或多個聲明組成,每一個聲明是一個屬性-值對。每一個樣式表都是由一系列規則組成的。圖7展現了規則:
圖7:規則的結構
規則左側的選擇器,定義了文檔中的哪些部分這條規則影響。圖7中選擇了h1
元素,若是選擇器是p
,那全部的p
(段落)元素將會被選擇。
規則右側是由一或多個聲明組成的聲明塊。每一個聲明都由一個CSS屬性和這個屬性的取值組成。在圖7中,聲明塊包含兩個聲明。第一個會使受影響的那部分文檔的color
屬性值爲red
,第二個會使受影響的那部分文檔的background
屬性值爲yellow
。所以,文檔中全部的h1
元素(由選擇器決定)都會被設置爲紅色文字和黃色背景。
有時你會看到CSS中存在像-o-border-image
這樣在前面帶着短線和標籤的聲明。這被稱做廠商前綴(vendor prefixes)10,瀏覽器廠商在提供試驗性或專有(或二者)功能時,用它來標記屬性、值或其餘CSS內容。到2012年中已經有了不少廠商前綴,表1中列出了最多見的幾種。
表1: 一些常見的廠商前綴
前綴 | 廠商 |
---|---|
-epub- | 國際數字出版論壇epub格式 |
-moz- | 基於Mozilla的瀏覽器(如:Firefox) |
-ms- | Microsoft Internet Explorer |
-o- | 基於Opera的瀏覽器 |
-webkit- | 基於WebKit的瀏覽器(如:Safari和Chrome) |
如表1所示,廠商前綴的一般格式是短線-標籤-短線,儘管有些(廠商的)前綴錯誤地省略了第一個短線。
廠商前綴的使用以及其後的濫用是一個漫長而又曲折的過程,講述它超出了本書的範圍。咱們只需知道,它們一開始是做爲廠商測試新功能的一種方式,從而有助於加速(不一樣瀏覽器之間)的互通性,而不至於被其它不能兼容的舊瀏覽器禁錮腳步。這避免了一系列問題,使得CSS倖免於在初期就被扼殺的厄運。然而不幸的是,隨後前綴屬性被web開發者無所顧忌地配置,最終致使了一系列新的問題。到撰寫本文時,廠商前綴的將來受到了普遍的質疑,它們極可能在幾年內被棄用。
請記住,不管什麼時候都要謹慎地處理前綴CSS,使用以前在每種瀏覽器上測試它們各自的前綴。
雖然有些例外,但基本上CSS對規則間的空格不敏感,對規則內的空格則更加不敏感。
通常來講,CSS處理空格的方式相似HTML:任何空格字符的序列都被當作單個空格解析。所以,一個假想的rainbow
規則能夠格式化爲下面的格式:
rainbow:infrared red orange yellow green blue indigo violet ultraviolet; rainbow: infrared red orange yellow green blue indigo violet ultraviolet; rainbow: infrared red orange yellow green blue indigo violet ultraviolet ;
以及其餘你能想到的分隔模式。惟一的限制是分割字符須要是空白:空格、tab符、換行符,單個仍是組合使用,隨你喜歡。
相似地,你可使用空白把一系列樣式規則按照任何你偏好的風格格式化,這是無限多種可能中的五種格式:
html{color:black;} body {background: white;} p{ color: gray;} h2 { color : silver ; } ol { color : silver ; }
在第一條規則中,空白被最大化地略去了。這種狀況一般發生在CSS「壓縮」的時候,這時會把不影響語義的空格所有刪除。前兩條以後的規則逐漸加入更多空白,到最後一條規則,幾乎每一個能夠被分隔的地方都被分開了。
以上的每種方式都是合法的,所以你應該選擇一種最有意義的格式,即在你看來最易讀的格式,而後堅持一向地使用它。
有些地方是確切地須要空白的,最多見的例子是在屬性值中分隔關鍵字列表,例如上面的假想rainbow例子中。這些地方必須用空白來分隔。
若是須要將特定媒體下的規則嵌入樣式表中(而不是使用media
屬性或@import
聲明把媒體特性用於整個樣式表),可使用@media
塊。像這樣:
h1 {color: maroon;} @media projection { body {background: yellow;} }
在這個例子中,h1
元素會在全部媒中都顯示爲栗色,但body
元素僅會在投影媒體上被設置爲黃色背景。
能夠在一個樣式表中加入許多@media
塊,每一個擁有本身的媒體描述符(在後面的章節中詳細介紹)。若是你願意,甚至能夠把全部規則封裝進一個@media
模塊:
@media all { h1 {color: maroon;} body {background: yellow;} }
可是因爲這種寫法與去掉第一行和最後一行以後的寫法沒有什麼區別,所以這麼作沒有什麼意義。
本節中的縮進僅僅是爲了顯示得更清晰,你不須要遵照@media
塊中的縮進規則,但這樣作是推薦的,由於它可使你的CSS更易於閱讀。
CSS是容許添加註釋的。與C/C++中用/*
和*/
包裹的註釋相似:
/* This is a CSS1 comment */
象C++中同樣,註釋能夠連續多行:
/* This is a CSS1 comment, and it can be several lines long without any problem whatsoever. */
要記住,CSS註釋不容許嵌套,像這樣是不正確的:
/* This is a comment, in which we find another comment, which is WRONG /* Another comment */ and back to the first comment */
固然,沒人想要嵌套註釋,因此這個限制沒什麼要緊的。
一個可能會建立了「嵌套」註釋的場景是,當想要把樣式表中一大塊包含了註釋的代碼臨時註釋掉時。由於CSS不容許嵌套註釋,「外層」註釋會在「內層」註釋結束的時候就結束了。
不妙的是,CSS中沒有行註釋符,如//
和#
(這個字符是ID選擇器的保留字)。/* */
是惟一的CSS註釋方式。所以,若是你想要把註釋放置在規則的同一行,就要當心放置的方式,例如,這是正確的方式:
h1 {color: gray;} /* This CSS comment is several lines */ h2 {color: silver;} /* long, but since it is alongside */ p {color: white;} /* actual styles, each line needs to */ pre {color: gray;} /* be wrapped in comment markers. */
這個例子裏,若是單行註釋沒有關閉,會致使大部分樣式表變成註釋的一部分,也就不能生效了:
h1 {color: gray;} /* This CSS comment is several lines h2 {color: silver;} long, but since it is not wrapped p {color: white;} in comment markers, the last three pre {color: gray;} styles are part of the comment. */
在這個例子中,只有第一行規則(h1 {color: gray;}
)會被應用於文檔。其它的則被瀏覽器的渲染引擎當作註釋的一部分而忽略掉了。
CSS註釋會被CSS解析器當作不存在同樣,也不會當作空白處理,這意味着你能夠把註釋放進規則中間,甚至放在聲明裏!11
CSS能夠徹底改變用戶代理顯示元素的方式。這種改變可使用display
屬性在基本的顯示級別上執行,而且經過把樣式表關聯到文檔的不一樣方式來執行,用戶不會知道這是經過外部仍是內嵌樣式表,甚至行內樣式表完成的。外部樣式表的重要性在於容許開發者把一個站點的全部展現信息放在一個地方,而後把全部文檔指向這個地方。這不只使站點更新和維護變得容易,還由於在文檔中移除了全部展現信息而節省了帶寬。
爲了充分利用CSS的能力,開發者須要弄清楚如何將一組樣式與文檔中的元素相關聯。爲了徹底理解CSS是如何作到這一點的,開發者須要透徹地領會CSS選擇文檔片斷的方式,這就是下一個主題:「選擇器,特度和層疊」。
1. 譯註:Firefox等瀏覽器所使用的引擎。↩
2. 譯註:Web發展早期第一個普及的瀏覽器。↩
3. 譯註:Recommendation 是W3C的推薦標準,標準已經歷了理論上和實際上的評審和測試,由W3C做簽署,能夠普遍應用。這是W3C提案的最終成熟的階段。)↩
4. 譯註:Candidate Recommendation是W3C的候選推薦標準,候選推薦標準與工做草案相比更加穩定,提案的重大的特性大部分已經鎖定。↩
5. 譯註:@import
規則必須放在其餘除了@charset規則之外的CSS規則的前面↩
6. 譯註:本文寫於2012年。↩
7. 譯註:device-width
、device-height
、device-aspect-ratio
三個特性已經被移出Web標準。_↩
8. 譯註:由於設備的水平方向和垂直方向的像素密度不一樣,因此使用任何值都不能匹配。↩
9. 譯註:逐行掃描和隔行掃描。 ↩
10. 譯註:vendor prefixes有時被翻譯爲「瀏覽器引擎前綴」或「第三方前綴」,譯法未見統一,這裏採用直譯「廠商前綴」,以突出「vendor」的「廠商」之意。↩
11. 譯註:例如h1 { co/* comments */lor: red; }
。↩