我们都用过jquery,使用jquery选择器,非常的简单,最近刚好有项目上手,拿起书本看了一下,发现好多的东西都忘掉了,好记性不如烂笔头,就将这章内容记录下来,现在我们看下css原生的选择器。
选择器规则结构
每个规则都有两个基本部分:选择器(selector)和申明块(declaration block)。申明块由一个或者多个申明组成,每个申明是一个属性值对(property-value).每个css样式表由一个或多个规则组成。如下图所示
元素选择器(标签选择器)
元素选择器是最常见的选择器,往往是一些html与元素,当然也并不是只有html才能作为元素选择器,例如如果css文件包含xml文档的样式,那么xml的元素也可以作为元素选择器。我们常用的html选择器元素有 p h1 h2等,下面的p标签的元素的背景颜色将变为其指定的颜色
p { background-color:#06F}
分组选择器
如果想要为多个元素设置同一个样式类型该怎么弄,我们可以用到分组选择器,及将多个元素用逗号分开即可,如下面的p标签和h1标签将使用同一个背景颜色
p ,h1{ background-color:#06F}
通配选择器
css2引入了一种新的简单的选择器,称为通配选择器(universal selector),显示为一个*号,这个符号可以与任意一个元素匹配,例如要使html每一个元素都变为红色可以使用如下语法
*{ background-color:red}
ID选择器
除了指示文档元素的选择器外,还有另外的两种类型的选择器:id选择器和类选择器,这节主要介绍id选择器,它允许存在一种独立于文档元素的方式来指定样式。,这些选择器可以单独使用也可以结合其他元素选择器来使用。定义id选择器时,前面加上#号,在加上具体的id,这个id必须唯一。先定义id选择器,然后在标签元素中使用 id属性引用定义的id
#test{ background-color:red; width:400px; height:400px;} <div id="test"></div>
类选择器
和id选择器类似,不同的是我们不需要再定义的类前面加#号,而是需要换为.号,需要使用的时候,在标签中使用class属性类引用构造的类。
.test{ background-color:red; width:400px; height:400px;} <div class="test"="test"></div>
多类选择器
前面我们看到的是单类选择器,即一般只有一个类,在html中,一个class值有可能包含一个值列表,各个值用空格分开,即我们的元素的class属性可以是多个的类,元素会显示为多个类定义的样式结果。
.test{ background-color:red; width:400px; height:400px;} .fontstyle{ font-size:24px} <div class="test fontstyle"="test">adfsfd</div>
当然我们也可以这样定义多类
.test.fontstyle{ background-color:red; width:400px; height:400px;font-size:24px}
如果我们希望只看到 包含 test类和fontstyle类的 div元素 显示其定义的背景,我们可以这么定义,下面定义的样式可以理解为 所有包含 类test、fontstyle类的div元素 将会使用定义的样式,其他的元素不会使用此效果
div.test.fontstyle{ background-color:red; width:400px; height:400px;font-size:24px}
如果我们定义的类的是这样的
.test.fontstyle{ background-color:red; width:400px; height:400px;font-size:24px}
那么考虑一下,以下的html元素是如何显示的
.test.fontstyle{ background-color:red; width:400px; height:400px;font-size:24px}
<div class="fontstyle">我是样式1</div>
<div class="test">我是样式2</div>
<div class="test fontstyle">我是样式3</div>
<div class="test aa fontstyle">我是样式4</div>
<div class=" aa test fontstyle">我是样式5</div>
<div class=" aa test ">我是样式6</div>
<div class=" aa fontstyle">我是样式7</div>
第 三、四、五个div会显示样式表定义的样式,原因是如果一个多类选择器包含的类名列表中没有匹配定义的类名,匹配就会失败。第三、四、五个div都包含定义的多类列表。
根据前面我们的描述,我们知道类,可以被多个的元素引用,但是id选择器会使用一次,而且仅仅一次,如果我们为多个的元素指定一个id,元素也会显示为id定义的样式,但是我们通常不推荐这么做,这样会导致编写DOM脚本时比较困难,因为当我们使用document.getElementById方法时,只会得到选择的第一个元素,后面的自动忽略,并且,id选择器是区分大小写的,及定义的id样式和引用的id样式名字必须一样。
属性选择器
如果希望选择某个属性的元素,而不论该属性的值是什么我们可以这么写,下面第1 2个h1元素将会 显示为 定义的样式,第3个h1将不会显示为定义的样式
h1[class]{ background-color:#9F3} <h1 class="12">我是样式1</h1> <h1 class="13">我是样式2</h1> <h1>我是样3</h1>
当然我们也可以使用通配符定义,如下面的定义的通配符属性选择器,其意思是,所有的含有属性 title的元素都将应用其定义的样式。
*[title]{ background-color:#9F3}
当然我们也可以定义多个属性的选择器。下面的意思是,所有的h1元素,title等于test,有class属性都将应用其定义的样式。
h1[title="test"][class]{ background-color:#9F3}
当我们根据具体的属性值来选择元素的话,值必须完全匹配,如果属性值有空格,那么我们在进行属性选择的时候,值必须一致。考虑下面的属性选择器,第一个h1会匹配样式,第二个不会
h1[class="13"]{ background-color:#9F3} <h1 class="13">我是样式1</h1> <h1 class="1 3">我是样式2</h1>
当然如果你想属性中只匹配 部分值,我们可以像下面这么定义,下面的两个h1都是显示为定义的样式。
h1[class~="test"]{ background-color:#9F3} <h1 class="test">我是样式1</h1> <h1 class="test aa">我是样式2</h1>
其他的子串匹配属性选择器
h1[class^=bar]{ background-color:#F00} //class属性以bar开头
h1[class$=bar]{ background-color:#F00} //class属性以bar结尾
h1[class*=bar]{ background-color:#F00} //class属性包含子串bar
我们要注意 class~=bar和class*=bar意思是不一样的,前者是部分值等于bar,说明 class中 有多个类 如 <div class="test bar"></div>,这样bar是指部分值,而,后者是指class属性某个值包含bar字符串。如<div class="testbar"></div>这样才会匹配。我们看下下面的代码,哪个会显示为定义的样式,第二个会显示为定义的样式。
h1[class~=bar]{ background-color:#F00} <h1 class="testbar">我是样式2</h1> <h1 class="test bar">我是样式3</h1>
下面的代码,哪个会显示为定义的值,两个都会,因为两个class属性都 包含 bar子串
h1[class*=bar]{ background-color:#F00} <h1 class="testbar">我是样式2</h1> <h1 class="test bar1">我是样式3</h1>
特定属性选择类型
我们看下面的代码,其意思为 所有的h1元素 class值 等于bar或者以bar开头的元素,这种情况多用于 属性值有相同的开头,如有一系列的image alt值以 test开头,如alt="test-01" alt="test-02" 我们就可以使用特定类型选择器来选择元素。
h1[class|=bar]{ background-color:#F00}
后代选择器(包含选择器或者称为上下文选择器)
即指的是通过一定的方式得到某个元素的后代元素。我们可以如下定义,前面是标签元素然后加一个空格 空格后面加上子元素 这样我们就可以得到其后代标签元素,下面代码的意思是,h1标签所有的子元素标签strong 将会用到其定义的样式。记住是所有的后代子元素strong,不论这个后代隐藏的有多深,如下面的html中所有的strong元素的背景都为红色
h1 strong{ background-color:red}
<h1 >woshi<strong>asdfas</strong><a herf="http://www.baidu.com">百度<strong>网址</strong></a></h1>
子元素选择器
有时候我们不需要所有的后代子元素,那么我们该怎么弄呢。这里就会用到子元素选择器,我们只要将后代元素选择器中间的空格换乘大于号即可。大于号两边有误空格均无影响。如下面的h1元素只有h1元素的第一代子元素背景会变红,即test会变红,至于 a标签元素的strong元素不会变红。
h1>strong{ background-color:red}
<h1 >woshi<strong>test</strong><a herf="http://www.baidu.com">百度<strong>网址</strong></a></h1>
相邻兄弟元素
如果你希望对一个标题后紧接着的段落应用样式,或者一个段落后紧接的列表指定样式,即要选择紧接在另一个元素后的元素,这两个元素有相同的父元素,可以使用相邻兄弟结合符,其表示为一个加号,加号两边可以有空格,不影响结果如下,如下面的结果,第一个p的背景将会变红。第二个不会变红,
h1+p{ background-color:red}
<h1 >woshi<strong>asdfas</strong><a herf="http://www.baidu.com">百度<strong>网址</strong></a></h1> <p>我是测试1</p> <p>我是测试2</p>
伪类和伪元素
伪类和伪元素是预定义的、独立于文档元素的。它们获取元素的途径也不是基于id、class、属性这些基础的元素特征,而是在处于特殊状态的元素(伪类),或者是元素中特别的内容(伪元素)。当然,伪类和伪元素的表示形式也使用“:”(英文冒号)与其它选择器相区分。我总结的就是 伪类是对于元素的状态来改变样式,而伪元素是对于元素的内容改变状态‘。
a:visit{color:#999} <a href="http://www.baidu.com">百度</a>
以上基本是css选择器的内容了,那么我们如何在html中使用css样式呢,一般我们有三种方式
外联:
我们定义一个css文件,通过在html的<head></head>中 使用标签来link引用
<link rel="stylesheet" href="test1.css" type="text/css" />
嵌入:
通过在html的<head></head>中 使用标签style来引用
<style type="text/css"> ul ol ul em{ color:#F00} h1>strong{ background-color:#F00} .test.fontstyle{ background-color:red; width:400px; height:400px;font-size:24px} #mytest{ background-color:#F0F} /*h1[class^=bar]{ background-color:#F00} h1[class$=bar]{ background-color:#F00} */ h1[class|=bar]{ background-color:#F00} /*h1[class~=bar]{ background-color:#F00} */ </style>
内联:
即在元素标签内 通过style属性来定义样式
<h1 style=" background-color:#00F; font-size:36px">我是test</h1>
那么问题来了,我们对一个元素同时的应用到了上面的三种方式的css样式表,那么到底哪个起效果呢,我们看一下下面的例子,外联的样式背景是红色的,嵌入的样式是绿色的,内联的样式是红色的。那么这个div的背景是什么颜色的,答案是红色的。
<!doctype html> <html> <head> <meta charset="utf-8"> <title>无标题文档</title> <link type="text/css" rel="stylesheet" href="test1.css"/> <style type="text/css"> div{ background-color:#0F0} </style> </head> <body> <div style=" background-color:#00F">我是测试文本</div> </body> </html>
因为,内联的约束力>嵌入>外联。这样排的话有一个条件。嵌入的代码在外联代码的后面,其实我认为 内联的约束力是最大的,即元素最先显示的样式是内联的样式,然后如果碰到嵌入的代码和外联的代码,哪个在后面,就使用哪段样式,其约束力取决于其位置,因为浏览器是从 上到下 加载 过来的。前面的相同的样式会覆盖掉。如果上面的内联代码不存在,只有嵌入的样式和外联的样式,那么如果哪个样式在后,就会使用哪段样式。
好了说完了他们的优先级,下面我们在考虑一个问题,元素选择器 id选择器 元素选择器 哪个优先级高,如果同一个元素 既应用到了元素选择器,又有id和类选择器 哪个优先级高,在比较之前我们先讨论一下,外联样式和 嵌入样式的@import方式,优先级问题。通过测试我们发现
- 当
@import
与内联样式一起时,内联样式>导入样式 - 除了第一种情况,其它时候以样式加载顺序为参考,后加载的优先级越高(最近优先原则)(即 link方式 和@import方式 哪个在后面,使用哪个样式)
最后,其实这种@import文件导入的方式已经很少用了,个人建议用link方式。原因是link载入时是和HTML的载入同步加载的,而@import则是在页面内容载入完成之后再引用的。如果网速慢的话,可能会导致页面的样式混乱。
另外使用@import时要注意添加地方,在CSS手册中提到:
- 该规则必须在样式表头部最先声明。并且其后的分号是必需的,如果省略了此分号,外部样式表将无法正确导入,并会生成错误信息。
- IE使用@import无法引入超过35条的样式表
现在我们来讨论一下 所有的元素的选择器的优先级的问题了。
但是我们不能忘了,我们上面总结的规律,即内联的样式还是优先级最高的,嵌入的和外联的看顺序,哪个在最后面哪个 优先级高,假设,代码都处于嵌入代码段,且出现的次数一样,他们的优先级如下。(当然importent还是最高的权重,importent>内联,我们这里不做讨论)
即 ICE 原则 ID >CLASS> Element,即 id选择器大于类选择器,大于标签元素选择器,并且 假定id选择器的权重为100 ,class的权重10,属性选择或者伪类也为10, 标签选择器的权重 1,伪元素和标签元素一样的权重 1,结合符号(+ >)和通配符号(*)没有任何的作用即他们的权重为0,如果我们碰到了一些复杂的选择器,我们一般通过的权重的加法来计算,权重和最大优先级越高。我们看下下面的选择器(我们不推荐这样写,因为使用了id选择器后完全不需要再他前面加上标签,因为id选择器就是唯一的)。div的背景是红色还是蓝色,答案是蓝色的,我们通过加权来计算,第一个选择器的权重 10+1=11,第二个权重100+1=101,第二个权重大,显示为第二个样式。
div.test{ background-color:red} div#test{ background-color:blue} <div id="test" class="test">我是测试文本</div>
当然还有很多的其他的样式
h1{ background-color:red}//1
p em{ background-color:red}//2
.test{ background-color:red}//10
*.test{ background-color:red}//10
p.test{ background-color:red}//11
#test{ background-color:red}//100
div#test *[herf]{ background-color:red}//100+1+10
h1+p{ background-color:red}//2
h1>p{ background-color:red}//2
当然以上权重是我个人的方法,官方给出的方法是,权重值表示为4个部分,即0,0,0,0,。id的权重表示为0,1,0,0,类、属性、伪类0,0,1,0。元素和伪元素(css2.1规定)0,0,0,1,通配符合结合符0,0,0,0。即从左到右,最左边的位数上的值最大,即1,0,0,0>0,90,90,90。0,0,1,0>0,0,0,15。
好了css基本介绍到这里了,最后对css优先级还感兴趣的可以看看这篇博文,http://www.zhangxinxu.com/wordpress/2012/08/256-class-selector-beat-id-selector/