CSS选择器详解


  • 元素选择器
  • 类选择器
  • ID选择器
  • 属性选择器
  • 派生选择器

1. 元素选择器

最常见css选择器当属元素选择器,在HTML文档中该选择器通常是指某种HTML元素,例如p、h2、span、a、div乃至html。
用法十分简单,如:
html {background-color: black;}
p {font-size: 30px; background-color: gray;}
h2 {background-color: red;}
以上css代码会对整个文档添加黑色背景;将所有p元素字体大小设置为30像素同时添加灰色背景;对文档中所有h2元素添加红色背景。

通过上面的例子也可以看出css的基本规则结构;由选择器声明块组成。每个声明块中包含一个或多个声明。每个声明的格式为属性名:属性值。如下图所示:

css规则结构
css规则结构

每条声明以“;”结尾。如果在一个生命中使用了不正确的属性值,或者不正确的属性,则该条声明会被忽略掉。另外请主要不要忘记每条声明后面的分号。
我们举个不正确的例子:
p {background-color: red
font-family: 黑体;
wordsize: 20px;
float: left;
}
上面的例子第一条声明漏掉了分号,以上声明块会被解析为:
p{ background-color: red font-family: 黑体;
wordsize: 20px;
float: left;
}
red font-family: 黑体整个会被解析为background-color 的属性值,这当然不是一个合法的属性值,该条声明将会被忽略掉。另外第二条声明使用了不正确的属性名wordsize,该条声明也将会忽略掉,结果只会正确处理第三条声明,等价于:
p{float: left}
此外,我们也可以同时对多个HTML元素进行声明:
h1,h2,h3,h4,h5,h6,p{font-faminly: 黑体}
这样会将文档中所有的h1~h6以及p元素字体设置为“黑体”。
如果我们希望一锅粥的选取所有的元素,可以使用通用符“*”
*{font-size: 20px}
这样所有的元素都将被选中,虽然font-size属性对于某些元素是无效的,那么它将被忽略。

2. 类选择器

(1)单类选择器

单纯的元素选择器有些粗糙,如果我们希望在文档中突出加粗显示某种重要的内容,例如稿件的截止日期。问题在于我们不能确定稿件的截止日期将会出现在哪种元素中,或者它可能出现在多种不同的元素中。这个时候,我们可以考虑使用类选择器(class selector)。
要使用类选择器我们需要首先对文件元素添加一个class属性,比如截止日期可能会出现在以下元素中:
<p class="deadline">...</p>
<h2 class="deadline">...</h2>
这样我们就可以用以下方式使用类选择器了:
p.deadline { color: red; }
h2.deadline { color: red ;}
点号“.”加上类名就组成了一个类选择器。以上2个选择器会选择所有包含“deadline”类的p元素和h2元素。而其余包含该属性的元素则不会被选中。
如果我们省略.deadline 前面的元素名,那么所有包含该类的元素都将被选中:
.deadline { color: red; }
通常情况下,我们会组合使用以上两者得到更加有趣的样式:
.deadline { color: red;}
span.deadline { font-style: italic;}
以上代码首先会对所有的包含deadline的元素字体设置为红色,同时会对span元素中的文本添加额外的斜体效果。这样,如果你希望某处文本拥有额外的斜体效果将他们放在<span></span>中就可以了。

(2)多类选择器

在实践的做法中,元素的class属性可能不止包含一个单词,二是一串单词,单个单词之间用空格隔开。
比如某些元素包含一个“warning”类,某些元素包含一个“important”类,某些元素同时包含“warning、important”类。属性名出现的顺序没有关系:
class = "warning important"
class = "important warning"
以上2者是等价的。
我们希望包含warning类的元素有一个醒目的红色字体,包含important 属性的元素有一个加粗的字体显示,而同时包含以上2种属性的元素另外拥有一个蓝色的背景(不管能否看清文字),我们可以使用一下的css代码:
.warning { color: red;}
.important { font-weight: bold;}
.warning.important { background: blue;}
当然,第三条你也可以写成:
.important.warning { background: blue;}
和词序没有关系。
说明一下:.warning会匹配所有包含warning属性的元素,不管该元素还包含多少其他的属性.important同理。而.important.warning会匹配所有同时包含以上2中属性的元素,不管该元素还包含多少其他的类,也不管他们在类列表中出现的顺序,只要其中包含这两个属性,则会被选择进来!
同样,对于多类选择器,在前面加上元素名,则会匹配包含指定类名的指定元素,例如:
p.warning.important { }
将会匹配同时包含warning和important属性的p元素,其他同样包含以上2类的元素则不会被选中。

3. ID 选择器

ID选择器和类选择器有些类似,但是差别又十分显著。
首先一个元素不能像类属性一样拥有多个类,一个元素只能拥有一个唯一的ID属性。其次一个ID值在一个HTML文档中只能出现一次,也就是一个ID只能标识一个元素(不是一类元素,而是一个元素)。
类似类属性,在使用ID选择器前首先要在元素中添加ID属性,例如:
<p id="top-para">...</p>
<p id="foot-para">...</p>
使用ID选择器的方法为#号“#”后后面跟ID值。现在我们使用ID选择器选择以上2个p元素如下:
#top-para { }
#foot-para { }
这样我们就可以对以上2个段落进行需要的操作了。正因为ID选择器的唯一性,也使其用法变得相对简单。

4. 属性选择器

属性选择器在css2中引入,是为什么可以根据元素的属性及属性值来选择元素。下面分别来说明:

(1)简单属性选择器

简单的属性选择器可以使我们根据一个元素是否包含某个属性来做出选择。使用方法为:
元素名[属性名]或*[属性名]
比如我们希望选择带有alt属性的所有img元素:
img[alt] {...}
选择带有title属性的所有元素:
*[title] {...}
同类选择器类似,我们也可以根据多个属性信息进行选择,例如同时拥有href和title的a元素:
a[href] [title] {...}
组合使用类选择器使我们的选择更加富裕灵活性。

(2)具体属性值选择器

如果我们希望更加精确地根据属性值来选择元素,我们可以在简单的属性选择其中指定属性的值。最简单的我们希望找到href属性值为http://www.baidu.com的锚元素:
a[href="http://www.baidu.com"] { font-weight: bold}
要特别注意的是,这里的具体值匹配实质上是一个字符串匹配,所以在这里对于class属性而言,词条的顺序是有关系的!
p[class="warning important"] {...}
将不会匹配到<p class="warning important"></p>,也不会匹配到<p class="warning important mini-type">,这里就是一个生硬的字符串匹配。
另外,想要同时匹配多个属性的值也是可以的:
p[class="warning"][title="para" {...}]
将匹配到类为warning(仅有warning),title属性为para的p元素。

(3)部分属性值选择器

根据属性值来匹配元素无疑比简单的属性匹配更加精细化了,但是似乎有些精细化过头了,字符串的完全匹配显得过于生硬,比如我们希望选择在一串属性值中出现了某个关键字的元素,不妨再次以class属性为例,我们希望选择所有包含了warning类的p元素,属性值匹配将无法做到,好在还是有办法的,我们可以使用以下的部分值匹配选择器:
p[class~="warning" {...}]
该选择器在等号“=”前面添加了一个波浪号~,含义为包含后面的字符串的匹配。以上代码将会选择所有class属性中包含“warning”的p元素。为了更加清楚地说明问题,它和以下的选择器是等价的:
p.warning {...}
当然~=不仅仅只是用在class属性上,这只是一个实例。
在比如说,我们的文档中包含一系列任务介绍的div元素:
<div title="intro 1">...</div>
<div title="intro 2">...</div>
<div title="intro 3">...</div>
我们可以使用一下的方式选择所有人物简介div:
div[title~="intro"] {...}
不过遗憾的是<div title="animal intro">也将会被选择进来,这是需要我们特别注意的地方。关于部分值选择器也有其局限性,他匹配的是由空格分隔的单词,如果我们将上面的div写成下面的样子就会匹配失败:
<div title="intro-1">...</div>
<div title="intor-2">...</div>
<div title="intor-3">...</div>
对于这种情况,我可以使用子串匹配属性选择器。规则如下:
div[title^="intor"] {....} //title以intro开头的div元素
div[title$="intor"] {...} //title以intro结尾的div元素
div[title*="intro"] {...} //title中包含“intro”子串的div元素

举例来说:
a[href*="google." {...}]
将包含所有链接中包含“Google.”的a元素。
div[title$="y"] {...}
将包含以下所有div元素:
<div title="cloudy">...</div>
<div title="snowy">...</div>
<div title="rainy">...</div>
可以看出部分值属性选择器的功能是十分强大的。

5.派生选择器

派生选择器,乍一看名字不知所云,它又名上下文选择器,它是使用文档dom结构来进行css选择的。dom结构在此不再赘述了,但是为了更加清楚地说明问题,我们这里给出一个DOM树作为参考:


dom树
dom树
(1)后代选择器(descendant selector)

如上图们如果想要选择body元素的所有li子元素,方法如下:
body li {...}
这里会选择所有的li后代,也就是图中的body下的所有li,不论它们之间相隔的代数有多少。同理,如果想要选择h1元素下的span,可以使用以下代码:
h1 apan {...}
如果我们要选择拥有过warning类的元素的li后代,可以使用下面的方法:
.warning li {...}
当然,如果希望只选择拥有warning类的div原色的li后代,可以写作:
div.warning li {...}
由上面的例子不难看出,后代选择器的规则就是用空格链接2个或多个选择器。空格的含义为...的后代。多个选择器的情况如下:
ul li li {...}
这样,就会选择所有ul下包含在li元素下的所有li元素了,听起来十分拗口,参考我们的DOM树,会选择到文档树中最后一排li元素。

(2)子元素选择器(child selector)

子元素选择器和后代选择器不同,它只能选择某元素的直接后代,不能跨代选取,用法如下:
ul > li {...}
两个字元素中间用一个大于号>连接。上面的代码会选择到所有ul元素的直接li子元素,对应到DOM树种,所有的li元素都会被玄宗,原因是图中所有的li圆度都是ul的子元素。
但是,以下代码将不会选中任何元素:
h1 > span {...}
由于span是h1的“孙子元素,h1没有直接span子元素,因而上面的代码将不会选到任何结果,其他方面和后代元素类似,需要特别注意的就是子元素选择器不能隔代选取。

(3)相邻兄弟选择器(adjacent aibling sector)

相邻兄弟选择器,顾名思义将会选取某个元素的相邻兄弟元素,注意他选取的是相邻的兄弟元素而不是所有的兄弟元素,实际上选取的是紧跟在后面的兄弟元素
相邻兄弟选择器在实践中有比较不错的应用,例如,你想在一个h2标题后面的段落应用某种独到的样式或者希望在某类p段落后的table上添加一个额外的边距等等。
它的用法如下:
li + li {...}
以上代码会选择所有作为li相邻元素的li元素,听起来又有点拗口,参考dom树,他会选择除了排在第一个li元素的其余4个li元素,因为2个排在第1的li元素没有更靠前的兄弟元素来选择它。
再比如:
h1 + p {...}
会选择所有紧跟h1后面的p兄弟元素。

(4)几种派生选择器的结合使用

实际上,以上介绍的几种派生选择器可以结合使用,看下面的例子:
hetml > body li.warning +li {....}
上面的选择器含义为:HTML元素的body子元素中,所有拥有warning类的li元素的相邻兄弟元素。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352