您的位置:首页 > Web前端 > CSS

重量级(CSS)层叠样式表教程(转)

2005-02-16 14:58 399 查看
重量级(CSS)层叠样式表教程I
本文是一篇关于CSS的应用概述,并提供了一些示例来演示CSS是如何工作的,以便于你更加有效的学习CSS。
本文并不是参考或者兼容性指南一类的文章(尽管其中有一些非常好的参考和兼容性注解的链接)。如果你已经习惯了使用CSS,并想学到更多样式表的知识,我们保证你会在本文中能够找到一些非常有用的信息:)。
CSS不能做什么?
层叠样式表通常被理解为实现“内容”和“风格”分开的手段。其实这种说法并不完全正确,因为根据你对“风格”和“内容”的定义不同,层叠样式表的作用也不尽相同。
HTML定义了文档的结构,同时将正文和图像及其他资料通过标记(tags)组织到一起。而CSS并不能影响文档的结构组成。
层叠样式表(CSS)所做的是定义这些元素以什么样的版式、什么样的颜色、间距……显示到页面当中,它还可以影响页面内容的布局,却不可能改变页面的结构。CSS只能在有限的限度内应用于元素(不是万能的),而文档元素的结构还是要通过标记语言HTML来定义。
使用CSS有什么好处?
所有的HTML标记(Tags)都有各自默认的样式(style).也就是说,浏览器会按照一定的基本规则来解释和显示每一个标记中的内容,但是我们通过内联样式(inline style)就可以优先于浏览器的默认样式来控制内容的显示样式。浏览器默认的样式表优先权最低。内联样式示例如下:
<p style="float:right;margin-left:1em;width:50%">Some text.</p>
内联样式影响的仅仅是某些特定的标记,如上面示例当中的<P>...</P>。而层叠样式表却提供了应用于所有给定标记样式或者特定子集合样式的途经。
CSS允许你设置与内容文档分离的“批量”样式表文档,和样式内嵌(inline style)至HTML代码当中的方法不同,这就是样式表使“内容”和“样式”分离说法的由来。同时,层叠样式表文档可以让更多的内容文档共享使用。
包含样式表
每一个样式表都是一系列的样式规则的集合。可以在内容文档的<HEAD>...</HEAD>之间使用STYLE标记来定义,示例如下:
<style type="text/css">
...style rules...
</style>
或者象调用JavaScript脚本文件那样通过URL链接到外部样式表文件,外联样式表利用 LINK 标记来设置,位置在内容文件的<HEAD>...</HEAD>内,示例如下:
<link href="url" rel="stylesheet" type="text/css">
注:在WEB站点内共享一个公共样式表是非常有用的,只要修改公共样式表,就能够影响所有调用该样式表的内容文档。
在同一文档内可以设置多个内联样式(inline style)和外联样式(link),但是具体文档显示时浏览器要根据那些样式的顺序来确定使用什么样式。(顺序非常重要)
定义样式规则
CSS规则设置由下面所示的语句组成:
selector { property : value }
selector {
property : value;
property : value;
property : value;
...
}
"Selector"定义了什么元素将要被样式规则所影响。紧接下来是声明区,由大括号"{","}"包围。内部由若干个声明(声明个数大于等于零>=0)组成。每一声明之间由分号“”隔开。
每个声明由“属性(property)”和具体的一个“值(value)”组成,他们之间通过冒号连接。“属性”是一个标识符,例如字体大小“font-size”,背景色“background-color”...等等。"值"的多少要控制在标识符属性值的范围内。
空白处以及分行形式来显示主要是为了阅读方便,空白处可以加入“注解”文字,示例如下:
selector { /* a comment for this rule */
property : value;
property : value;
property : value;
}
注解包含在/ *和* /内,同JavaScript、C程序设计语言的注释写法一样。
Selectors 选择器
最简单的形式由标记名称组成,不同的标记样式规则相同时可以通过逗号“”连接合并到一起说明,示例:
h1 { background-color: #ffff00 }
h2 { background-color: #ffff00 }
h3 { background-color: #ffff00 }
上面的样式说明合并到一起,写法如下:
h1, h2, h3 { background-color: #ffff00 }
这种定义称为“群组”定义。注意同一标记可以再次设置,次数不限,例:
h1, h2, h3 { background-color: #ffff00 }
h1 { color: red }
HTML标识名是不区分大小写的,所以“H1”等价于“h1”,但是语法更加严格的XHTML中,标识名必须小写,所以最好有一个良好的书写习惯,建议在书写你的样式表时使用小写字母。
Pattern Matching模式匹配
Selectors并不仅仅局限于标识名,事实上,有多种匹配模式可以定义元素的样式,甚至利用元素的属性来定义。
Internet Explorer现在还不能支持所有的selector的匹配模式。建议使用Netscape或者Opera来测试下面的演示。
列表中例举了Selectors不同的匹配模式和解释以及在线演示的示例链接。
模式说明演示
E标准的selector、标识名E相配元素EDEMO
E FDescendant selector, 如果E标记包含F时,匹配FDEMO
E>FChild selector 、如果F是E的子标记,则匹配FDEMO
E+FAdjacent selector、如果E和F有相同的parent父标识同时F紧临着E,则匹配FDEMO
注意:其中" parent "、" child "、" descendant "、和" adjacent "这些名词涉及到文档内部的标记分级关系结构。举例来说明:
<div>
<h3>What Good is CSS?</h3>
<p>CSS gives you <i>very precise control</i> over how your web ages
look. Use it to your advantage!
</p>
</div>
为了更好的理解分析各个标记之间的关系,我做了一个示意图:



H3标记和P标记是DIV标记的children子标记。

H3、PI标记都是DIV标记的descendants后代

H3P 标记的父标记是DIV

I标记是Pchildren子标记,它的parent标记是P

I标记不是DIV标记的children子标记,它是DIV标记的grandchild标记或descendants标记

DIV标记是H3PIancestor源标记

H3P标记是adjacent相邻关系

Selector中还可以使用通用匹配符“*”:
h2 + * { color: red }
将任何紧接着H2的任何元素显示为红色

重量级(CSS)层叠样式表教程II

元素的属性(Attribute)也可以用于selector。下面的列表中例举了几种模式:

Attribute Selector Patterns
模式说明
E[attr]Attribute selector属性选择器、匹配任何含有该属性的E元素,不必考虑它的值的大小
E[attr="value"]Attribute selector,属性选择器、匹配任何具有该属性的元素E,条件是属性的值必须与设定的值相等。
E[attr~="value"]Attribute selector属性选择器、有些元素属性当中可能包含若干个值(通过空格分隔开)。这种模式匹配任何具备属性attr,同时包含特定值(值可能是列表形式)的元素E
E.valueClass selector, “类”选择器、仅对HTML有效。匹配任何设置了CLASS类属性的元素E,与 E[ class ~ = " value "]等效.
E#valueID selectorID选择器、相配任何设置了ID属性的元素E.对于HTML等价于
E [ id = " value "]
上面这些selector设置模式可以灵活地使用到标记的样式规则当中,例如:
*.highlight { background-color: #ffff00 }
*#mainTitle { font-size: 150%; font-weight: bold; }

*.highlight匹配设置 class ="highlight" 的“任何”元素。第二个规则匹配了 id ="mainTitle"的任何元素。多数情况下星号“*”可以被省略,就象下面这样。
.highlight { background-color: #ffff00 }
#mainTitle { font-size: 150%; font-weight: bold; }

类"CLASS"和"ID"哪种方式更加实用好用呢?通过上面的两个例子,我们来探讨一个非常有趣的问题:“CLASS VS ID” 类和ID的对决

●Class vs ID

HTML标记的ID属性为标记设定了唯一的标识符,而类属性是允许用户为HTML元素设置样式的一种方式。
严格来讲、在同一个文档(网页)内,没有两个元素具有相同的ID。无论何时,只要为标记设置ID,就必须保证ID的值不能和其它元素的ID冲突,哪怕他们拥有不同的标记名称也不行。所以,如果用ID设置样式,每一个ID只能应用于页面当中的一个元素。(一对一关系)
为什么不使用内联样式(inline style)代替ID selector呢?在实际应用当中,你会发现:将所有样式定义在一起要比那些遍布于文档当中的内联样式要方便的多。如果是外联样式表,它还可以被其它文档共享使用。
类(class)选择器可以匹配页面当中的若干元素(一对多关系),即使元素使用不同的标记名称也可以。同一标记可以使用若干个“类”(class)来定义样式(指定一列使用空格分隔的类class的名称)。例如:
h3.warning { color: red }
.highlight { background-color: yellow }

...

<h3 class="warning highlight">Danger</h3>

<h4 class="warning highlight">Proceed with Caution</h4>

H3标记的内容显示红色,背景色为黄色。H4标记的背景色为黄色,但是内容不会显示为红色,。

●Pseudo-classes 和 Pseudo-elements 伪类和伪元素

最后一种selectors模式为“伪类别”和“伪元素”,它能够设置特殊条件下某些元素或者某些元素所包含内容的样式

Pseudo-class and Pseudo-element Selectors
模式说明
E:first-childPseudo-class, 伪类,匹配元素E,条件是E是第一个其父标识的子标识。与* > E相似,但是仅仅匹配一元素的第一个子标记。
E:first-letter
E:first-line
Pseudo-elements, 伪元素,作用与E元素包含的内容中第一个字符或首行(注意不是全部内容)
E:before
E:after
Pseudo-elements, 伪元素,可作用于元素E的内容之前/之后嵌入的内容
E:link
E:visited
Link pseudo-classes,链接伪类,应用于不同状态的超链接 (未访问:link、已访问:visited)
E:active
E:hover
E:focus
Dynamic pseudo-classes, 动态伪类,应用于超链接或表单元素相应用户响应时的样式(激活:active、鼠标悬停:hover、 输入焦点:focus)
first-letter和first-line selectors之所以称之为伪类是因为它们不是作用于整个元素内容而只是内容的一部分
链接伪类应该是比较熟悉的,它们与以前用于BODY标记的 LINK ="color" 和 VLINK ="color" 属性类似,同样地、动态伪类 :active 相当于以前BODY标记的 ALINK = "color"。这样使用的目的是使用户在视觉上能够区分链接不同状态下的颜色,已经被CSS所采用。

为链接定义任何 :hover 规则时需要注意 :hover 的位置要写在 :visited 规则之后,目的是使链接被访问之后鼠标悬停在超链接上面时产生效果(如果顺序掉过来,先写 :hover 后写 :visited ,就不会有悬停效果了),原因是样式排列有优先顺序关系。
另一个动态伪类 :focus 可以应用于用户使用表单输入时的样式效果

●Language Selectors

Language选择器
不能不介绍的还有Language Selectors,E[lang|="cc"] 和 E:lang(cc) 对于显示外国文字和标点符号是很有用的,可以查阅有关的资料。

●Chaining Selectors

联合Selectors
实际应用当中,有些CSS样式规则的Selectors可能是由多种基本模式组合而成,这样的规则使用时更加精确,例如:
div p a.definition { color: green }
div p a.definition:hover { color: red }

此规则应用于超链接,条件是该链接的类class为" definition ",同时超链接包含于P标记内,而P标记又包含于DIV标记内,用户未访问时超链接为绿色,鼠标悬停时为红色。

重量级(CSS)层叠样式表教程III

■继 承 和 层 叠
CSS规则影响元素的显示形态,但是如果没有样式匹配或者存在多种样式规则同时匹配该元素时,元素显示的形态到底是遵循哪个规则呢?本节论述的内容涉及到样式的继承和层叠方面的知识。
●继 承
有些样式通过默认的样式设置而“继承”,也就是说,子元素继承父元素的样式规则,包括color、font和text-align等等。
例如:
p { color: red }
...
<p>Sample paragraph with <b>bold</b> text.</p>
<B>和</B>标记内的文字显示为红色,因为其父元素P标记有一个样式规则color:red,同时没有设置针对B标记的匹配样式,根据继承原则 <B>和</B>标记内的文字显示为红色。

同样,任何B标记的子元素将继承段落的样式显示为红色。例如:
<p>Sample paragraph with <b>bold and <i>bold italic</i></b> text.</p>
但是如果增加了:
b { color: green }
<B>和</B>标记内的文字将要变成绿色,<I>和</I>标记内的文字也将继承其父标记B的样式而显示为绿色

Some style properties permit a value of inherit, indicating that the value should be taken from the element's parent, even if the property is not inherited by default
●样式冲突
有时侯元素可能是与若干式样规则相配,此时就产生了样式规则之间的冲突。为了断定哪个规则被应用,CSS按一定的梯级优先分配规则,根据优先权决定执行哪个规则。
理解式样声明之间是否存在冲突是非常重要的,例如,下面的样式不存在样式冲突:
b { font-size: 12pt; } /* no conflicts */
p b { color: red; }
但是下列样式规则中,对于P标记中的B标记来说,font-size出现冲突:
b { font-size: 12pt; } /* conflict between font-size property */
p b { font-size: 14pt;
color: red; }
这两种规则根据优先顺序决定执行哪个规则。
CSS按下列规则判定优先权的归属

如果没有施加继承或缺省样式,此时不存在优先权问题,样式按设定的规则显示。

依据来源(网页制作者还是最终用户)、层叠秩序、重要性(特指!important关键字)来判断执行。

依据特殊性(基于特性级别)判断执行。

定义的顺序,最后定义的规则优先执行。

●层 叠
样式表有三个来源:“用户代理”、“最终用户”、“网页设计者”。
每个用户代理都具有一个默认的样式表,也就是说总要有一个样式表应用到页面当中。即使浏览器没有使用任何一个自定义样式。大多数浏览器允许用户改变一些默认的样式,比如字体和颜色、在选项设置中设定。
用户样式表允许定义自己的样式表应用到页面当中,有些用户可能需要比浏览器默认样式或页面设计者的样式设定的字体要大,色彩对比性更强的颜色。
程序设计者样式表:参看式样定义或参考内部包含样式的资料
设计者样式表>用户样式>默认样式
●!important关键字
!imporant关键字能被用于一个样式说明中,其优先权高于设计者和用户的样式。也就是说,如果用户样式表指定了一个!important声明,它将跨越设计者设定的样式而作用于页面。
* in the user's style sheet */
p {
color: red;
font-size: 18pt !important;
}
/* in the author's style sheet */
p {
color: green;
font-size: 12pt;
}
段落正文显示为18点绿色文字,而设计者指定的字体大小是12,颜色为绿色,按一般规则,设计者优先权高于用户,但是这里用户样式规则中声明了字体大小为!important级别。所以优先权最高.
注解:如果设计者的样式中声明字体大小为!important用户的字体大小仍然具有优先权。
浏览器兼容性
CSS规范(CSS1)允许设计者设置!important声明优先权高于用户的!important声明。而CSS2中将这个规则翻转过来。用户的! important声明高于设计者的声明。因为有些浏览器依然使用CSS1标准,所以设计者应该避免使用!important声明。
Netscape 6.0使用CSS2标准,用户!important声明总是优先的。但是Netscape 6.1的一个bug会引起设计者声明反而超越用户的!important声明!!。
在同"源"(用户、设计者……)的样式表内部,!important关键字声明同样具有绝对的优先权。举例来说:下列第二个样式规则按常理来讲应该具有优先权(因为顺序靠后)
/* in the author's style sheet */
p {
color: green !important;
font-size: 12pt;
}
p {
color: red;
font-size: 18pt;
}
但是段落正文将显示为18点绿色字体。因为第一个规则的颜色标记为!important。

重量级(CSS)层叠样式表教程IV

Specificity
本节讲述的是用来判断样式优先权的是“specificity”。“specificity”和选择符selector中元素的数目以及元素的属性有关,“specificity”高的优先应用。
怎样计算选择符的“specificity”值呢?涉及到三项内容:
1.选择符中ID标识符属性的数目A

注意:一个匹配ID的属性选择符不能算作一个ID,它仅能当作一个属性选择符.例如"id = value"的specificity值远远小于"#_value"

2.选择符中其它属性、伪类的数目B
注意:Class类选择符是属性选择符的一种.

3.选择符中标识、伪元素的数目C
例外:如果样式规则内嵌到一个式样属性内,它并不具备selector、此时它的specificity要比其它任何selector都高.
这三个值通过逗号“连”在一起构成一个加权值。举例如下:

ListABCSpecificity
#blurb { ...}1101,0,0
.message.big { ... }0110,1,1
div.message { ... }0110,1,1
.message { ... }0100,1,0
div { ... } 0010,0,1
* { ... }0000,0,0
#id1 { ... }1001,0,0
UL UL LI.red { ... }0130,1,3
LI.red { ... }0110,1,1
LI { ... }0010,0,1
#z { ... }1001,0,0
UL LI { ... }0020,0,2
UL OL+LI { ... }0030,0,3
H1 + *[REL=up]{ ... }0110,1,1
UL OL LI.red { ... }0130,1,3
LI.red.level { ... }0210,2,1
#x34y { ... }1001,0,0
H1 {(simple selector)}0010,0,1
P EM {(contextual selector)}0020,0,2
.grape {(class selector)}0100,1,0
P.bright {(element/class selector combo)} 0110,1,1
P.bright EM.dark {(contextual element/class)}0220,2,2
#greg {(ID selector)}1001,0,0
*{ ... }0000,0,0
li{ ... }0010,0,1
ul li{ ... }0020,0,2
ul ol+li{ ... }0030,0,3
[id=value] { ... }0100,1,0
h1 + *[rel=up] { ... }0110,1,1
ul ol li.class { ... }0130,1,3
li.c1.c2 { ... }0210,2,1
#value{ ... }1001,0,0
DIV.a DIV.b DIV.c DIV.d DIV.e DIV.f DIV.g DIV.h DIV.i DIV.j DIV.k { color: red; } 011110,b,b
注:ID总是优先于属性,属性总是优先于标记名。所以一个具有ID标识符的selector总是优先于其它类定义的样式。
●顺序:后来者居上
最后一节讲按照次序决定优先顺序,末尾的规则定义超过任何前面的定义,假设两个规则:
p { color: red; background: yellow }
p { color: green }
段落显示绿色文字,同时背景色为黄色,因为规则一设置的颜色将被规则二取代,而背景色不存在样式冲突,所以规则一中定义的背景色仍然被采用,
★★临时测验:
看一下下列代码:
p.red { color: red }
p.green { color: green }
p.blue { color: blue }
...
<p class="red green blue">Sample text.</p>
<p class="green blue red">Sample text.</p>
<p class="blue red green">Sample text.</p>
每个段落的正文是什么颜色?

//
function toggleAnswer(event) {

var linkEl, divEl;

linkEl = document.getElementById("answerLink");
divEl = document.getElementById("answerDiv");
if (divEl.style.display == "") {
divEl.style.display = "none";
linkEl.firstChild.nodeValue = "Show Answer";
}
else {
divEl.style.display = "";
linkEl.firstChild.nodeValue = "Hide Answer";
}

return false;
}

//]]>
【点击这里显示答案】

它们全部显示为蓝色。类在属性设置中的顺序先后没有相关性,可任意。每个段落匹配全部三个样式规则,根据样式表中的顺序,后来者居上,段落内容为蓝色。
综合应用我们学到的样优权定义规则的知识,就拿超链接四种常见状态的样式定义来举例:

以下资料来自: http://www.meyerweb.com/eric/css/link-specificity.html
问:
我已经使用CSS定义了超链接的样式,但是浏览时hover(鼠标悬停)却不起作用。为什么会这样?是浏览器的问题吗?
答:
虽然你认为可能原因是浏览器问题,但是更多的可能是你样式定义时顺序错误。为了保证能看到不同状态下的连接样式,正确的样式顺序应该是:
" link - visited - hover - active "或" LVHA "(缩写)。
核心内容:
每个选择符selector都有一个“specificity”如果两个selectors应用于同一个元素,具有较高specificity的选择符将胜出,具有优先权。例如:
P.hithere {color: green;} /* specificity = 1,1 */
P {color: red;} /* specificity = 1 */
任何设置了类class=hithere的段落内容显示为绿色而不是红色。两个selectors都设置了颜色,但是具有更高specificity的选择符将胜出。
伪类如何影响specificity呢?它们具有完全相同的加权值,下列样式具有相同的specificity加权值:
A:link {color: blue;} /* specificity = 1,1 */
A:active {color: red;} /* specificity = 1,1 */
A:hover {color: magenta;} /* specificity = 1,1 */
A:visited {color: purple;} /* specificity = 1,1 */
这些都是用于超链接的样式设置。大部分情况下需要同时设置其中的几个样式,例如,一个未被访问的超链接在鼠标悬停和点击时可设置“鼠标悬停”和“鼠标激活“两种状态下的不同样式,由于上述三个规则都可应用于超链接,并且全部选择符具备相同的specificity,那么根据规则,最后一个样式“胜出”。所以" active "式样永远也不会显示出来,因为它总是被" hover "式样覆盖(即" hover "优先)。现在再来分析一下已经被访问过的超链接鼠标悬停是什么效果,结果永远是purple紫色的:( ,因为它的" visited "式样总是优先于其它的状态样式规则(包括" active "和" hover")而显示。
这就是为什么CSS1推荐样式顺序的原因:
A:link
A:visited
A:hover
A:active

实际上,开头两个样式的顺序可以调换,因为一个超链接不可能同时存在“未访问”和“已访问”两种状态。( :link意思是" unvisited ";我不知道为什么不这样定义呢.)
CSS2现在允许伪类可以以“联合成组”形式出现,例如:
A:visited:hover {color: maroon;} /* specificity = 2,1 */
A:link:hover {color: magenta;} /* specificity = 2,1 */
A:hover:active {color: cyan;} /* specificity = 2,1 */
They have the same specificity, but they apply to fundamentally different beasts, and so don't conflict. You can get hover-active combinations, for example.
如何理解本文当中所涉及到的“specificity”呢?specificity可以理解未简单地连在一起的号码字符串,上面的一个例子:
P.hithere {color: green;} /* specificity = 11 */
P {color: red;} /* specificity = 1 */
这好像是一个基于十进制的简单运算。然而计算“specificity”不能使用十进制算法,例如你把15种选择符连在一起使用、它们具有的“specificity”加权值还是比简单的class选择符低。举例:
.hello {color: red;} /* specificity = 10 */
HTML BODY DIV UL LI OL LI UL LI OL LI UL LI OL LI (color: green;} /* specificity = 15 */
" 10 "实际上是一个“1”后面接着“零”、不是"十",我们可以使用十六进制描述前面的样式规则的specificitiy,像下面:
.hello {color: red;} /* specificity = 10 */
HTML BODY DIV UL LI OL LI UL LI OL LI UL LI OL LI (color: green;} /* specificity = F */
唯一的问题是如果你想为第二个样式规则增加两个或更多的选择符时,那时你就可能得到一个“17”的specificity、会再一次混淆。事实上specificity可能是无穷大的,所以为了避免更多的混乱,建议使用逗号来分隔specificity的值。
站长建议:反复练习specificity的加权值的计算,网站CSS的设置体现了你控制页面的能力,在动态网站开发中,CSS的地位也是非常重要的,多看资料,多练习,多来MXSKY:),站长制作翻译的教程不会在内容上有所保留的.如果你觉得MXSKY内容还不错,请帮忙宣传哦:)

(转自www.mxsky.com)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: