, ( ) , ( ) , TeX, Microsoft Word . : ", ".
— , 1994
蒂姆·伯纳斯·李(Tim Berners-Lee)于1991年宣布创建HTML时,无法对页面进行样式设置。 HTML标签的呈现方式由浏览器确定,并且受用户偏好的影响很大。但是,创建一个允许页面“提示”其首选样式呈现的标准工具似乎是一个好主意。
但是在CSS出现之前,还需要五年的时间,而要完全实施CSS还要再十年。在这段艰苦的工作和不断创新的时期,导致了许多相互竞争的风格的产生,这些风格很可能成为标准。
虽然这些语言今天显然没有得到广泛使用,但我有兴趣思考世界的情况。更令人惊讶的是,甚至在今天,这些语言中的许多语言都具有开发人员会在CSS中愉快使用的功能。
第一候选人
在1993年初,Mosaic浏览器甚至没有达到1.0版,并且所有现有的浏览器仅使用HTML。无法指定HTML样式,因此您
<h1>
以浏览器决定显示标记的方式查看了标记。
同年6月,罗伯特·赖斯(Robert Reisch)向www-talk邮件列表提交了一份提案,以创建“一种易于解析的格式,用于将样式信息与网络文档一起传送”,他称之为RRP。
@BODY fo(fa=he,si=18)
如果您不了解此代码的作用,这是可以原谅的。在前gzip时代,当连接速度通常低于14.4 kbps时,将这种新格式的内容保持尽可能紧凑是合乎逻辑的。具体来说,此规则选择
fa
Helvetica(he
)作为字体系列(),并将字体大小(si
)设置为18磅。
奇怪的是,Reisch的建议缺乏度量单位,所有数字都是根据上下文进行解释的(例如,所有字体大小均以磅为单位)。这是因为RRP的设计更多是作为“渲染器的技巧和窍门”,而不是作为规范。这被认为是必要的,因为相同的样式表应该可以在常规的文本模式浏览器(例如Lynx),以及越来越流行的图形浏览器。
Lynx浏览器的屏幕截图
有趣的是,RRP包含一种指定列布局的方法-在CSS中,直到2011年才实现。例如,三列,每列80单位宽,如下所示:
@P co(nu=3,wi=80)
解析起来有些棘手,但可能并不困难
white-space: nowrap
。
值得注意的是,RRP不支持我们今天将样式表与之关联的任何“级联”。任何文档一次最多只能有一个活动的样式表,对于样式文档而言,这是很合逻辑的,尽管对于当今的我们而言这是不寻常的。
Marc Andreessen(Mosaic的创建者,最终成为最受欢迎的浏览器)了解RRP提案,但从未在Mosaic中实现它。取而代之的是,Mosaic几乎立即采取了使用HTML标签进行样式设置的方法(这非常悲惨),并添加了诸如
<FONT>
和的标签<CENTER>
。
中提琴和原始浏览器之战
“那么为什么不仅仅执行那里的许多样式表建议之一。有了正确的结构,这几乎可以完全解决问题。”
然后我必须告诉人们:“好的,您需要学习这种语言来编写文档,然后学习另一种语言来使文档看起来像您想要的样子。” 哦,他们会喜欢的。
-马克·安德森(Mark Andreessen),1994年
与流行的看法相反,Mosaic不是第一个图形浏览器。在此之前出现了ViolaWWW,这是由魏佩元在短短四天内编写的图形浏览器。
Viola Browser
Pei-Yuan的屏幕快照创建了一种样式表语言,该语言支持当今CSS中使用的那种层次结构:
(BODY fontSize=normal
BGColor=white
FGColor=black
(H1 fontSize=largest
BGColor=red
FGColor=white)
)
在这种情况下,我们将颜色应用于文档的主体(主体),尤其
H1
是要对主体内部的样式进行设置。 PWP没有重复选择器来控制此嵌套,而是使用了括号系统,这使我们想到了Stylus和SASS之类的语言中使用的缩进系统,一些开发人员今天仍然喜欢CSS。这可能使PWP语法在至少一个方面比CSS更好,CSS随时间演变为Web的通用语言。
PWP还因为它有一种引用外部样式表的方式而著名,我们今天仍在使用它:
<LINK REL="STYLE" HREF="URL_to_a_stylesheet">
不幸的是,ViolaWWW主要是为了与X Window System一起使用而编写的,X Window System仅在Unix系统上流行。当Mosaic移植到Windows时,很快使Viola尘土飞扬。
网络之前的样式表
HTML是只有计算机科学家才能爱上的那种东西。是的,它表示文档的内部结构,但是文档不仅是结构化的文本数据库;它们具有视觉效果。HTML完全破坏了文档开发人员可能具有的任何图形创造力。
罗伊·史密斯(1993)
对能够表达文档样式的语言的需求比Internet本身要古老得多。
您可能知道,我们知道的HTML最初基于称为SGML的Internet之前的语言。 1987年,美国国防部决定测试SGML是否可用于简化其大量文档的存储和传输。像任何好的政府项目一样,他们所做的第一件事就是想出一个名字。该团队最初被命名为计算机辅助物流支持团队,然后被命名为计算机辅助采购和物流支持团队,最后是连续采购和生命周期支持计划。无论如何,缩写都是CALS。
CALS团队创建了一种用于样式化SGML文档的语言,称为FOSI。她出版了一种语言规范,其内容之详细无法理解。它包括了我最喜欢的网络上最无意义的信息图表。
Internet上无一例外的规则是,如果您可以证明某人在此过程中做错了,那么您总是会做得更多。 1993年,就在Pei-Yuan提出提案的四天后,Stephen Heaney提出,与其重新发明轮子,不如使用FOSI版本的网络样式更好。
FOSI文档本身是用SGML编写的,考虑到Web开发人员对SGML版本HTML的熟悉,这是很合乎逻辑的举动。示例文档如下所示:
<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
“上下文中的元素”的含义。但是,FOSI首次引入度量单位便引人注目,em
现在它已成为CSS调整大小的首选方式。
导致的语言冲突实际上与编程本身一样古老。这是功能性Lisp样式语法与更声明性语言的语法之间的斗争。Pei-Yuan本人将自己的语法描述为“类似LISP”,但是真正的LISP版本出现在现场只是时间问题。
图灵完成的样式表
尽管有复杂性,但FOSI实际上被视为解决文档格式设置问题的中间方法。长期计划是基于功能编程语言Scheme创建一种语言,该语言能够实现可想象的最强大的文档转换。该语言称为DSSSL。让我们请一位语言开发者约翰·博萨克(John Bosak)发言:
不要将DSSSL误认为是脚本语言。是的,DSSSL已经完成图灵;是的,这是语言progrmmirovaniya。但是脚本语言(至少在我对术语的解释中)是程序性的;而DSSSL绝对不是。DSSSL功能齐全,完全没有副作用。DSSSL样式表中什么都没有发生。样式表是一个巨大的函数,其值是对格式化文档的抽象,与设备无关的非过程描述,作为要渲染区域的规范(如果需要,可以声明),传递给下游渲染器。
以最简单的形式,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多个独立样式的属性。
进一步的开发工作导致了XSL的诞生-XSL是一种同样复杂但又更为流行的文档转换语言。
为什么赢得样式表
CSS没有父选择器(一种基于其包含的子样式设置父样式的方法)。这个事实长期 困扰着 Stack Overflow用户 ,但事实证明,缺席用户是有充分理由的。在Internet的早期,人们认为在文档完全加载之前可以呈现页面至关重要。换句话说,必须能够在页面末HTML完全加载之前呈现页面顶部HTML。
拥有父选择器意味着在加载HTML文档时需要更新样式。像DSSSL这样的语言被完全排除在外,因为它们可以对文档本身执行操作,而在渲染时还不能完全使用它们。伯特·玻色(Bert Bose)
于1995年3月率先提出了这个问题,并提出了一种可以解决该问题的语言。他的建议还包含表情符号“笑脸”的早期版本:-)。
该语言本身在语法上相当“面向对象”:
*LI.prebreak: 0.5
*LI.postbreak: 0.5
*OL.LI.label: 1
*OL*OL.LI.label: A
该符号
.
表示最近的孩子和*
祖先。
Bose的语言还有一个有趣的特性:您可以指定样式表本身中的元素(如链接)如何工作:
*A.anchor: !HREF
在上面的示例中,我们指定了link元素的导航地址是其attribute中的值
HREF
。诸如链接之类的元素的行为应受到控制的想法在许多其他建议中也很普遍。在JavaScript之前的时代,无法控制这些方面,因此将这些方面包括在这些建议中似乎是合乎逻辑的。
在一个一个的草案函数式语言,在1994年提出了一个名为S.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;
}
但是,事情很快变得有趣得多。例如,不仅可以根据指定给元素的大小(
Width
)来表示元素的位置,还可以根据在Actual Width
浏览器中呈现该元素的true()大小来表达该元素的位置:
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的幽灵
可以直接导致创建CSS的语言(至少顾名思义)是CHSS(级联HTML样式表)。它由HåkonW Lie在1994年提出。
像大多数好主意一样,最初的建议非常疯狂。
h1.font.size = 24pt 100%
h2.font.size = 20pt 40%
注意规则末尾的百分比。此百分比表示当前样式表对该值拥有多少“所有权”。例如,如果先前的样式表
h2
有指定的字体大小30pt
为60%
“所有权”,和样式表h2
指定的样式为20px 40%
,那么这两个值可以基于它们的所有权百分比以产生大约的值进行组合26pt
。
为何在文档HTML页面时代提出这样的提议是完全可以理解的:基于权衡的这种设计在我们面向应用程序的世界中是不会被理解的。尽管如此,它提出了有关需要级联样式表结构的基本思想。换句话说,在同一页面上需要多个样式表的想法。
在最初的表述中,这一想法通常被认为很重要,因为它使最终用户可以控制他们所看到的内容。原始页面可以有一个样式表,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
我们都知道接下来会发生什么
Microsoft完全致力于开放标准,尤其是在Internet上。
-约翰·路德曼(John Ludeman),1994年
Haakon Lee继续致力于简化提案,并与Bert Bose共同于1996年12月发布了CSS规范的第一版。他最终撰写了有关创建CSS的博士学位论文,并且该文档对我撰写本文有极大帮助。
与许多其他建议相比,CSS的显着方面是其简单性。它易于解析,易于编写和易于阅读。正如Internet历史上经常发生的那样,最适合初学者而不是对专家而言最强大的技术赢得了人们的青睐。
这本身就在提醒人们随机创新的可能性。例如,对上下文选择器的支持(
body ol li
)的添加是因为Netscape已经有一种方法可以从超链接的图像中删除边框,并且似乎有必要做流行浏览器可以做的所有事情。该功能本身在CSS的实现方面造成了严重的延迟,因为当时大多数浏览器在解析HTML时都没有存储标签的“堆栈”。这意味着需要重新设计解析器以完全支持CSS。
由于这些问题(以及广泛使用非标准HTML标签进行样式设置),CSS直到1997年才可用,并且直到2000年3月,任何浏览器都未完全支持CSS。正如任何开发人员都会告诉您的那样,浏览器支持远非符合标准,并且仅在几年前(即CSS发布15年后)就发生了变化。
Netscape 4 CSS,<body>
, , IE4<body>
, , CSS ? CSS. , IE4 , Netscape 4.
—
Internet Explorer 3以发布(相当糟糕)的CSS支持而闻名。决定为了能够在Netscape 4中竞争,还必须对此语言提供支持。但是,与其再加倍努力来实现第三种语言(在HTML和JavaScript之后),不如决定将其转换为JavaScript并执行它来实现。更糟糕的是,已决定该中间JavaScript样式表应该可供Web开发人员使用。
语法是纯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本身在当时还是很年轻的语言,但是由于进行了逆向工程,因此在IE3中以JScript的形式添加了对JavaScript的支持。更大的问题是,当时社区已经开始聚集CSS,而当时大多数标准社区都将Netscape视为犯罪者。当Netscape向标准委员会提出JSSS时,它充耳不闻。三年后,Netscape 6放弃了对JSSS的支持,并逐渐消失。
有什么可以等我们
由于受到W3C的公开指责,Internet Explorer 5.5于2000年发布,几乎支持CSS1。当然,正如我们现在所知道的,CSS的浏览器实现非常麻烦,并且至少在接下来的十年中很难使用。幸运的是,今天的情况已大大改善,这最终使实现开发人员的梦想成为可能,即您可以编写一次代码,并且在不同的浏览器中(几乎)功能相同。
就我个人而言,我从所有这一切中汲取了支配我们现代工具的决策是多么的随意和背景。如果将CSS设计为与1996年的约束兼容,那么也许二十多年后的我们才允许我们做一些不同的事情。