- 做者:陈大鱼头
- 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
在各位开发者心目中的地位。因为鱼头我水平有限,文笔有限,若是各位在文章中发现有任何不合理,不正确的地方,还烦不吝指出,我会很是感谢的;若是经过文章有任何想法或疑问,也但愿各位能积极留言,咱们互相探讨;若是经过本系列文章有所收获,这就让鱼头我喜不自胜了!