1. class 和 id 的使用场景:
- id:id选择器,使用#name定义(name为id名,可任意取名),使用id="name"调用,其优先级高于类选择器,一个标签只能有一个id且每个id只能使用一次,多用于页面分块的块级标签上;
- class:类选择器,使用.name定义(name为类名,可任意取名),使用class="name"调用,一个标签可以有多个类且同一个类可以用到不同的标签上,多用于多个标签样式相似或完全相同时。
2. CSS常见选择器:
- 基础选择器
- * : 通用元素选择器,匹配页面任何元素(这也就决定了我们很少使用)
- #id : id选择器,匹配特定id的元素
- .class: 类选择器,匹配class包含(不是等于)特定类的元素
- element: 标签选择器
- 组合选择器
- E,F 多元素选择器,用,分隔,同时匹配元素E或元素F
- E F 后代选择器,用空格分隔,匹配E元素所有的后代(不只是子元素、子元素向下递归)元素F
- E>F 子元素选择器,用>分隔,匹配E元素的所有直接子元素
- E+F 直接相邻选择器,匹配E元素之后的相邻的同级元素F
- E~F 普通相邻选择器(弟弟选择器),匹配E元素之后的同级元素F(无论直接相邻与否)
- .class1.class2 id和class选择器和选择器连写的时候中间没有分隔符,.和 # 本身充当分隔符的元素
- element#id id和class选择器和选择器连写的时候中间没有分隔符,.和 #本身充当分隔符的元素
- 属性选择器
- E[attr] 匹配所有具有属性为attr的元素(div[id]能选择所有具有id属性的div)
- E[attr=value] 匹配所有属性为value的元素(div[type=text]匹配id=text的div)
- E[attr~=value] 匹配所有属性attr具有多个空格分隔,其中一个值等于value的元素
- E[attr ^=value] 匹配属性attr的值以value开头的元素
- E[attr $=value] 匹配属性attr的值以value结尾的元素
- E[attr *=value] 匹配属性attr的值包含value的元素
- *伪类选择器
- E:first-child 匹配元素E的第一个子元素
- E:last-child 匹配元素e的最后一个子元素
- E:nth-child(n) 匹配其父元素的第n个子元素,第一个编号为1
- E:first-of-type 匹配父元素下使用同种标签的第一个子元素,等同于nth-of-type(1)
- E:hover 匹配鼠标悬停的e元素
- E:focus 匹配获得焦点的e元素
- 伪元素选择器
- E::first-line 匹配E元素的第一行
- E::first-letter 匹配E元素的第一个字母
- E::before 在e元素之前插入生成的内容
- E::after 在e元素之后插入生成的内容
3. 选择器的优先级及计算:
- 属性后+!important:p {color:#ccc!important;}
- 内联样式:
- id选择器: #id
- 类选择器: .class
- 伪类选择器:a:link
- 属性选择器:h1{}
- 标签选择器:p[XXX]
- 通用选择器:*
- 浏览器自定义
复杂场景时,计算优先级时通过数标签来计算,先数id,如果id相等再数类,如果id不相等,id多的选择器权重高,权重越高,优先级越高。如果id选择器数量相同,再数类选择器,最后数标签。
权重计算规则:
- 第一等:代表内联样式,如: style=" ",权值为1000。
- 第二等:代表ID选择器,如:#content,权值为0100。
- 第三等:代表类,伪类和属性选择器,如.content,权值为0010。
- 第四等:代表类型选择器和伪元素选择器,如div p,权值为0001。
- 通配符、子选择器、相邻选择器等的。如*、>、+,权值为0000。
- 继承的样式没有权值。
!important 的作用是提升优先级,换句话说。加了这句的样式的优先级是最高的(比内联样式的优先级还高)。
比较规则:
- 1,0,0,0 > 0,99,99,99。也就是说从左往右逐个等级比较,前一等级相等才往后比。
- 无论是行间、内部和外部样式,都是按照这个规则来进行比较。而不是直观的行间>内部>外部样式;ID>class>元素。之所以有这样的错觉,是因为确实行间为第一等的权重,所以它的权重是最高的。而内部样式可能一般写在了外部样式引用了之后,所以覆盖掉了之前的。
- 在权重相同的情况下,后面的样式会覆盖掉前面的样式。
- 通配符、子选择器、相邻选择器等的。虽然权值为0000,但是也比继承的样式优先。
实例:
a{color: yellow;} /*特殊性值:0,0,0,1*/
div a{color: green;} /*特殊性值:0,0,0,2*/
.demo a{color: black;} /*特殊性值:0,0,1,1*/
.demo input[type="text"]{color: blue;} /*特殊性值:0,0,2,1*/
.demo *[type="text"]{color: grey;} /*特殊性值:0,0,2,0*/
#demo a{color: orange;} /*特殊性值:0,1,0,1*/
div#demo a{color: red;} /*特殊性值:0,1,0,2*/
<a href="">第一条应该是黄色</a> <!--适用第1行规则-->
<div class="demo">
<input type="text" value="第二条应该是蓝色" /><!--适用第4、5行规则,第4行优先级高-->
<a href="">第三条应该是黑色</a><!--适用第2、3行规则,第3行优先级高-->
</div>
<div id="demo">
<a href="">第四条应该是红色</a><!--适用第5、6行规则,第6行优先级高-->
</div>
4. a:link, a:hover, a:active, a:visited 意义及顺序:
- a伪类解释:
- link:设置a对象在未被访问前的CSS样式;
- visited:设置a对象在其链接地址已被访问过时的CSS样式;
- hover:设置对象在其鼠标悬停时的CSS样式;
- active:设置对象在被用户激活(在鼠标点击与释放之间发生的事件)时的CSS样式;
- focus : 代表的是获取焦点时的样式,这个我们可以通过tab键来查看,一旦链接获取了焦点,则它的样式就是你设置的focus样式。
-
顺序:
a伪类的顺序为:a:link > a:visited > a:focus >a:hover > a:active。
前四个的顺序有个比较简便的记忆方法:L-V-H-A,即love & hate。 - 原因:
- 鼠标经过的“未访问链接”同时拥有a:link、a:hover两种属性,后面的属性会覆盖前面的属性定义;
- 鼠标经过的“已访问链接”同时拥有a:visited、a:hover两种属性,后面的属性会覆盖前面的属性定义;
- a:active是鼠标点击与释放之间发生的事件,并拥有鼠标悬停a:hover属性;
由于伪类的选择器优先级一致,后面的a链接样式会覆盖前面的。
所以说,a:hover定义一定要放在a:link、a:visited的后面,才能在鼠标悬停时,a:hover样式不被a:link和a:visited样式覆盖;
- a:visited一定要放在a:link的后面,因为这样能保证访问过的链接具有a:visited样式,并能覆盖a:link默认样式;
- a:active一定要放在a:hover后面。假如a:active放在a:hover前面,由于a:active拥有鼠标悬停a:hover属性,当鼠标按下时,首先会触发a:hover事件,然后触发
- a:active,但是a:ctive已被a:hover的样式所覆盖,因此无法看到a:active的样式。所以,a:active一定要放在a:hover后面。
- 补充a:focus的顺序:
- :hover 代表的是你光标经过某一元素时的样式,如果将此样式放在:focus之后,则当链接获取焦点时,显示:focus样式,当光标经过此链接时,会显示hover的样式,因为hover排在后,会覆盖focus样式。
- 如果:hover排在前,:focus排在后,则当光标获得焦点时显示:focus的样式,但当光标经过链接时,样式并未显示:hover的样式,而是继续是:focus的样式,因为应用的focus样式在hover之后,覆盖了前面的样式。
可用以下代码进行具体演示
a:focus{
color:black;
text-decoration:underline;
}
a:hover{
color:#FF0000;
text-decoration:underline;
}
a:active{
color:#FFCC00;
}
综上所述,a伪类的顺序为:a:link > a:visited > a:focus > a:hover > a:active。
5. 选择器举例:
/*id选择器,匹配id值为header的元素*/
#header{
}
/*class选择器,匹配class值为header的所有元素*/
.header{
}
/*后代选择器,匹配class值为header元素的所有class值为logo的后代*/
.header .logo{
}
/*匹配class值包含header和mobile的元素 */
.header.mobile{
}
/*匹配class值为header元素后代中的p和h3元素*/
.header p, .header h3{
}
/*匹配id值为header元素后代中class值为nav元素中的li元素*/
#header .nav>li{
}
/*为id值为header元素后代中的a元素指定鼠标移动到其上方的样式 */
#header a:hover{
}
/*在id值为header的元素后代中寻找:class值为logo元素之后的同级p元素*/
#header .logo~p{
}
/*在id值为header的元素后代中寻找type属性为”text"的input元素*/
#header input[type="text"]{
}
6. div:first-child和div:first-of-type的作用和区别
div:first-child 匹配的是 div 的父元素下第一个子元素,而 div:first-of-type
匹配的是父元素下同种元素类型的第一个子元素。例如:
<div class="father">
<h1 id="child1">AA</h1>
<h2 id="child2">BB</h1>
<h3 id="child3">CC</h1>
<h2 id="child4">DD</h1>
</div>
如果有选择器如下:
#child2:first-child
,选中AA;
#child2:first-of-type
,选中BB;
#child4:first-child
,选中AA;
#child4:first-of-type
,选中BB。
实例如下:
<style>
.item1:first-child{
color: red;
}
.item1:first-of-type{
background: blue;
}
</style>
<div class="ct">
<p class="item1">aa</p>
<!-- 父元素div下第一个类为item1的子元素,父元素div下第一个类为item1的p标签子元素,
因此满足.item1:first-child和.item1:first-of-type-->
<h3 class="item1">bb</h3>
<!-- 父元素div下第一个类为item1的h3标签子元素,满足.item1:first-of-type-->
<h3 class="item1">ccc</h3>
</div>
输出结果如下: