- 做者:陳大魚頭
- github: KRISACHAN
HTML是怎麼來的?css
在1982年的時候,萬維網的發明者Tim Berners-Lee爵士爲了讓全世界的物理學家可以方便的進行合做與信息共享,造了HTML(HyperText Markup Language) 超文本置標語言。html
在1991年3月,Tim Berners-Lee
把HTML
介紹給了給他在CERN(歐洲核子研究中心) 工做的朋友,當時網頁瀏覽器被其世界各地的成員用來瀏覽CERN
龐大的電話薄。react
而後在8年以後的1990年,博士發明了世界上第一個瀏覽器WorldWideWeb,也所以推進着互聯網高速發展。css3
在WorldWideWeb
問世以後的1993年NCSA推出了Mosaic瀏覽器而且迅速火了起來,成爲第一個世界級應用的瀏覽器,推進着互聯網發展。隨後跟着的有當時的兩大霸主Netscape
de Netscape瀏覽器與MicroSoft
的Internet Explorer瀏覽器,這兩個瀏覽器在當時掀起了一場互聯網瀏覽器大戰。這場戰爭的結果是以Internet Explorer
全勝了結。但也所以大大的推進了互聯網的發展。git
CSS是怎麼來的?github
就在承載HTML
的瀏覽器迅猛發展的90年代,CSS (Cascading Style Sheet)也應運而生。不一樣的瀏覽器結合各自HTML
語法結構實現了不少不一樣的外部樣式語法。但隨着HTML
的發展,爲了知足設計師的要求而增長了不少顯示功能,隨着這些功能的增長,外部樣式語法做用愈來愈沒有意義。web
在1994年10月10日,CSS之父Håkon Wium Lie提出了 CSS 的最初建議,而且爲 HTML 樣式在芝加哥的一次會議上正式提出了 CSS 。編程
在1996 年 12 月,W3C
在通過多方的討論以後,推出了CSS1.0
。這一規範一出現就引發了各方的注意,隨即 MicroSoft 公司和 Netscape 公司紛紛表示本身的瀏覽器可以支持 CSS1.0
。瀏覽器
CSS各版本的更新bash
CSS1.0
在1997 年 由W3C
發佈,初版主要規定了選擇器、樣式屬性、僞類 / 對象幾個大的部分;CSS2.0/2.1
在1998 年 由W3C
發佈,CSS2 規範是基於 CSS1 設計的,擴充和改進了不少更增強大的屬性。包括選擇器、位置模型、佈局、表格樣式、媒體類型、僞類、光標樣式;CSS2
經歷了 9 年的時間(從 2002 年 8 月到 2011 年 6 月)才達到 Recommendation(推薦) 狀態,此後W3C爲了加快那些已經確認沒有問題的特性的標準化速度,便做出了一項被稱爲 Beijing doctrine 的決定,將CSS模塊化,而且按照每一個模塊的進度來標準化。因此從形式上來說,CSS3
已經不存在了。如今CSS 包括了修訂後的 CSS2.1 以及完整模塊對它的擴充,模塊的 level(級別)數並不一致。能夠在每一個時間點上爲 CSS 標準定義一個 snapshots(快照)。下圖爲CSS模塊化的發展進程圖,來自MDN
如今的CSS也是通過一番爭鬥才脫穎而出的
如下內容翻譯於The Languages Which Almost Became CSS
早在1993年Mosaic
瀏覽器1.0發佈以前,當時現有的瀏覽器已經開始獨立處理HTML
了,可是它們並無能給標籤訂製樣式的方式,這就意味着你看到的標籤長什麼樣就長什麼樣,不能改。
因此在1993年的6月,Robert Raisch
給www-talk
郵件發了一個提案,但願建立一個「一種易於解析能夠與Web文檔一塊兒提供樣式信息的格式」,並給它起名叫RRP
。
格式以下:
@BODY fo(fa=he,si=18)
看不懂上面的代碼是情有可原的。在gzipping
以前的時代,網絡傳輸速度只有14.4K,因此格式儘可能壓縮都是合理的。這個特殊規則是將font family (fa)
設置爲helvetica (he)
,將font size(si)
設置爲18 points
。
和流行的見解不同,Mosaic
並非第一個圖形瀏覽器,ViolaWWW纔是。由Pei-Yuan Wei花了4天寫的。
如下是Pei-Yuan Wei
建立的樣式表語言:
(BODY fontSize=normal
BGColor=white
FGColor=black
(H1 fontSize=largest
BGColor=red
FGColor=white)
)
複製代碼
在這個例子中咱們給body
添加了顏色選擇器,而且給body
中的h1
添加了樣式。
值得一提的是PWP仍是引用外部樣式表的方法提出者,他提出的方法一直沿用至今。
<LINK REL="STYLE" HREF="URL_to_a_stylesheet">
複製代碼
不幸的是,ViolaWWW
只能運行在X Window System系統中,這個系統只在Unix中受歡迎。當Mosaic
移植到Windows
上不久後就把ViolaWWW
拋到身後了。
早在互聯網以前就有對文檔樣式進行修改的語言要求。
正於你所知道的,HTML
源於一個在互聯網以前就出現的語言,SGML
。早在1987年,美國國防部就決定研究SGML
是否可使文檔存儲和傳輸更加便捷,他們有大量的文檔須要處理。跟其餘好的政府項目同樣,他們沒有時間能夠浪費在起名上。這個團隊最初叫計算機輔助後勤支持隊,後來叫計算機輔助採集和後勤支持隊,最後叫持續獲取和生命週期支持計劃。反正簡寫都是CALS
。
CALS
爲SGML
建立了一個叫FOSI
(這是一個四字單詞簡寫,可是由於年代久遠,已經不知道是哪四個單詞了)的語言來爲文檔添加樣式。 例子以下:
<outspec>
<docdesc>
<charlist>
<font size="12pt" bckcol="white" fontcol="black">
</charlist>
</docdesc>
<e-i-c gi="h1"><font size="24pt" bckcol="red", fontcol="white"></e-i-c>
<e-i-c gi="h2"><font size="20pt" bckcol="red", fgcol="white"></e-i-c>
<e-i-c gi="a"><font fgcol="red"></e-i-c>
<e-i-c gi="cmd kbd screen listing example"><font style="monoser"></e-i-c>
</outspec>
複製代碼
若是你困惑docdesc
或charlist
,那麼你要知道,www-talk
的成員跟你有一樣的困惑。惟一給出上下文信息的是e-i-c
,即element in context
。FOSI
值得注意的是引入了em
做爲字體單位,如今已經成爲了不少熟悉CSS的人中更受歡迎的方法。
因爲它的複雜性,FOSI
被認爲是格式化文檔問題的臨時解決方案。長遠的解決方案是建立一個基於函數式編程語言Scheme的新語言,它能夠作任何你能想象到的文檔轉換。這門語言叫DSSSL
。
下面是語法:
(element H1
(make paragraph
font-size: 14pt
font-weight: 'bold'))
複製代碼
由於它是一門編程語言,因此你能夠函數化:
(define (create-heading heading-font-size)
(make paragraph
font-size: heading-font-size
font-weight: 'bold)) (element h1 (create-heading 24pt)) (element h2 (create-heading 18pt)) 複製代碼
並在樣式中使用數學結構,例如「條帶化」表的行:
(element TR
(if (= (modulo (child-number) 2)
0)
… ;even-row
…)) ;odd-row
複製代碼
最後,讓你妒忌一下,DSSSL能夠把繼承的值當成變量進行數學運算:
(element H1
(make paragraph
font-size: (+ 4pt (inherited-font-size))))
複製代碼
不幸的是,DSSSL
擁有和跟全部Scheme
類語言同樣的致命弱點:括號太多了。此外,當它最終發佈時,它可能過於完整,使瀏覽器開發人員感到懼怕。 DSSSL規範包含210多個獨立的能夠定製樣式的屬性。
CSS 沒有父級選擇器(一種基於子元素的樣式給父元素設置樣式的方法)。 這個問題在Stack Overflow上被頻繁的提問(這是其中一個)。可是事實證實,這個特性缺失是有理由的。特別在互聯網早期,讓網頁在徹底加載完成以前被渲染,是很重要的。意思就是,你們但願HTML加載完以前,就能夠渲染已經加載完的部分。
父選擇器意味着樣式得在HTML文檔一邊加載時,一邊更新。像DSSSL這樣的語言若是實現了這個功能,由於它們能夠對文檔進行操做,因此也沒極可能就不能用了。
在1995年3月,Bert Bos
做爲第一個提出這個問題的人,還提供可行方案。他的提案中還包括了一個早期的笑臉表情包:-)
。
這個語言有點像面向對象:
*LI.prebreak: 0.5
*LI.postbreak: 0.5
*OL.LI.label: 1
*OL*OL.LI.label: A
複製代碼
使用.
來指定直接子節點,使用*
來指定祖先節點。
他的語言還有一個很酷的屬性,就像這樣在樣式表中定義超連接:
*A.anchor: !HREF
複製代碼
在上面的例子中,指定link
的目標爲其HREF
的值。像這種可控制連接等元素的行爲在不少提案中都很流行。在Javascript
還沒出來以前,沒有什麼可控制元素的方法,因此它們看起來是很合理的。
一個函數式的提案,1994年被一位叫C.M. Sperberg-McQueen
的紳士提出,裏面包含了相似的行爲。
(style a
(block #f) ; format as inline phrase
(color blue) ; in blue if you’ve got it
(click (follow (attval 'href))) ; and on click, follow url 複製代碼
他的語言還引入了content
關鍵字做爲從樣式表控制HTML
元素內容的一種方式,這個概念後來被引入到CSS 2.1
中。
在我談到實際成爲CSS的語言以前,還有另外一種語言值得一提,由於它在某種程度上是早期Web開發者的夢想。
它就是PSL96
,按照當年的命名規範,1996年版的Presentation Specification Language
。PSL的核心很像CSS:
H1 {
fontSize: 20;
}
複製代碼
然而,它很快就變得頗有趣了。例如,你不只能夠根據元素寬度來渲染它的位置,也能夠基於瀏覽器的實際寬度來渲染。
LI {
VertPos: Top = LeftSib . Actual Bottom;
}
複製代碼
甚至你可使用元素左邊的兄弟姐妹來定製。
你還能夠爲樣式添加邏輯表達式。例如,僅設置具備href的錨元素的樣式:
A {
if (getAttribute(self, "href") != "") then
fgColor = "blue";
underlineNumber = 1;
endif
}
複製代碼
這種樣式能夠擴展到咱們今天用樣式來完成的各類事情:
LI {
if (ChildNum(Self) == round(NumChildren(Parent) / 2 + 1)) then
VertPos: Top = Parent.Top;
HorizPos: Left = LeftSib.Left + Self.Width;
else
VertPos: Top = LeftSib.Actual Bottom;
HorizPos: Left = LeftSib.Left;
endif
}
複製代碼
支持這功能的話或許真的能夠實現內容與樣式分離的夢想。遺憾的是這門語言拓展性太強,這就覺得着不用瀏覽器的實現可能會不同。並且,它是以一系列的文章出現出如今學術界,並無通過www-talk
郵件列表進行討論,因此,它永遠不會出如今主流瀏覽器。
一門語言,至少從名字上,直接引出了CSS
,它叫CHSS (Cascading HTML Style Sheets)
,提案在1994年被Håkon W Lie
提出。
跟不少好主意同樣,這個原始提案很是瘋狂。
h1.font.size = 24pt 100%
h2.font.size = 20pt 40%
複製代碼
注意行尾的百分比,這個百分比是指當前樣式表佔用該值的「權重」。例如,若是以前的樣式表已將h2字體大小定義爲30pt,擁有60%,而且此樣式表將h2s設置爲20px 40%,則這兩個值將根據其權重百分比進行組合在一塊兒,大概就是26pt。
很明顯,這個提案是在基於文檔的HTML
頁面的時代,基於拖鞋的設計是沒法在咱們面向應用的世界裏發揮做用的。不過,它已經具有了樣式表應該能夠疊加的基本思想。換句話說,應該能夠將多個樣式表應用於同一頁面。
它最初的形式被認爲是重要的,由於它讓用戶能夠控制他們所看到的內容。頁面有一個樣式表,而且Web用戶將擁有本身的樣式表,這兩個樣式表一塊兒渲染在頁面上。支持多個樣式表被視爲一種維護Web我的自由的方法,而不是支持開發人員(他們仍然手動編寫單獨的HTML頁面)的方式。
用戶能夠控制該頁面做者的建議的權重,就如提案中的ASCII 圖那樣。
User Author
Font o-----x--------------o 64%
Color o-x------------------o 90%
Margin o-------------x------o 37%
Volume o---------x----------o 50%
複製代碼
像許多這些提案同樣,它包含了幾十年來不可能出如今CSS中的特性。例如,能夠根據用戶的環境編寫邏輯表達式。
AGE > 3d ? background.color = pale_yellow : background.color = white
DISPLAY_HEIGHT > 30cm ? http://NYT.com/style : http://LeMonde.fr/style
複製代碼
在一個有點樂觀的將來場景中,瀏覽器會根據給定的內容對你的相關性,容許它以更大的尺寸展現給你看。
RELEVANCE > 80 ? h1.font.size *= 1.5
複製代碼
Håkon Lie
繼續簡化他的提案,且和Bert Bos
合做,並在1996年11月發佈的CSS
規範的初版。最終他將創造CSS
寫進了他的博士論文裏,也就是這個文檔幫助我寫了這篇文章。
與許多其餘提案相比,CSS的一個值得注意的事實是它的簡單性。它易於分析,易於編寫和輕鬆閱讀。與互聯網歷史上的許多其餘例子同樣,對於初學者來講,須要的是最容易上手的技術,而不是那些給更強大的專業人員用的技術。
它自己就給咱們一個提醒,這是一個偶然發生的創新。例如,僅添加了對上下文選擇器(body ol li
)的支持,由於Netscape
已經有一種方法能夠從超連接的圖像中刪除邊框,而且彷佛有必要實現流行瀏覽器能夠執行的全部操做。這個功能自己就大大拖延了 CSS
的實現,由於大多數瀏覽器在解析HTML時沒有保留標籤的「堆棧」。這意味着必須從新設計解析器才能徹底支持CSS。
像這樣的挑戰(以及普遍使用非標準HTML標籤來定義樣式)致使着CSS直到1997年纔可以使用,直到2000年3月纔有瀏覽器徹底支持它。這跟每一個開發者跟你說的同樣,瀏覽器近幾年才真正標準化,這裏距首次發佈CSS已通過去了21年(原文15年)了。
IE 3
以(有點可怕的)CSS
支持着稱。爲了競爭,Netscape 4
也考慮了CSS
。但它仍是決定經過將CSS轉換爲JavaScript並執行它來實現它,而不是將第三種(考慮HTML和JavaScript)。更有甚者,Web開發人員應該能夠訪問這個「JavaScript樣式表」中間語言。
語法是直接使用JavaScript
,而後添加了一些特定樣式的API:
tags.H1.color = "blue";
tags.p.fontSize = "14pt";
with (tags.H3) {
color = "green";
}
classes.punk.all.color = "#00FF00"
ids.z098y.letterSpacing = "0.3em"
複製代碼
你甚至能夠定義一個每遇到一個標籤就執行一次的函數:
evaluate_style() {
if (color == "red"){
fontStyle = "italic";
} else {
fontWeight = "bold";
}
}
tag.UL.apply = evaluate_style();
複製代碼
咱們應該簡化樣式和腳本之間分界線的想法是合理的,如今在React社區還出現了各類相似的思路。
在當時,JavaScript
自己就是一種很是新的語言,可是經過一些逆向工程,IE
已經在IE3
中添加了對它的支持(如「JScript
」)。更大的問題是社區已經在CSS
周圍團結起來,而Netscape
在這個時候被大多數標準社區視爲胖虎(原文bullies)。當Netscape確實向標準委員會提交JSSS時,它被置若罔聞。三年後,Netscape 6放棄了對JSSS的支持,並且本身也準備安樂死了。
因爲W3C的一些公開羞辱,IE 5.5
在2000年推出了幾乎完整的CSS1支持。固然,正如咱們如今所知,瀏覽器的CSS在將來10年裏都很是粗糙且難以使用。還好今天狀況大大改善了,讓開發者寫一份代碼並在不一樣瀏覽器中均可以運行的夢想(幾乎)實現了。
我我的的結論是,不管這些決策是拍大腿決定的仍是深思熟慮的,都決定了當前工具的形式。若是CSS的設計方式只是爲了知足1996年的限制,那麼20年後的咱們作事的方式應該會有些不一樣。
【Hello CSS】
是以CSS
基礎概念爲主題的系列文章,旨在幫助你們更深入地瞭解而且提升CSS
在各位開發者心目中的地位。因爲魚頭我水平有限,文筆有限,若是各位在文章中發現有任何不合理,不正確的地方,還煩不吝指出,我會很是感謝的;若是經過文章有任何想法或疑問,也但願各位能積極留言,咱們互相探討;若是經過本系列文章有所收穫,這就讓魚頭我喜不自勝了!