4.4 简单选择器续

4.4.1 类选择器

1、语法

类选择器定义

.类名{ /*样式定义*/ }

匹配所有class属性包含指定类名的元素,类名由开发人员自定义。

类选择器调用

<标签名 class="类名">内容</标签名>

通过class指定类名。两处的类名需要完全一致。

示例代码。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>小步教程</title>

    <style>
        .class1{
            font-size: 20px;
            font-weight: 800;
        }

        .class2{
            font-style: italic;
        }
    </style>
</head>
<body>
    <div>
        <h4>小步教程 xiaobuteach.com</h4>
        <p class="class1">第1段</p>
        <p class="class2">第2段</p>
        <p class="class1">第3段</p>
        <p class="class2">第4段</p>
        <!-- <p class="class1 class2">第5段</p> -->
    </div>
</body>
</html>

定义class1与class2两个类选择器,“第1段”与“第3段”使用class1,“第2段”与“第4段”使用class2。

运行效果

img


2、需求场景理解

上述代码需求场景:为同一类的多个元素指定样式,第1类是大字号加粗,第2类是斜体。


3、DevError006 选择器设计错误导致无法匹配

错误操作:class值与选择器类名不同,故意将第1段的class1改成class11。

<p class="class11">第1段</p>

样式面板查看元素应用的选择器,选择器class1未被应用。


4、指定多个类名

一个元素可以属于多个类,即class属性指定多个类名,用空格分开。

<标签名 class="类名1 类名2 … 类名n">

调用代码如下

<p class="class1 class2">第5段</p>

“第5段”同时使用class1与class2定义的样式。


5、GramError009 class属性值多个类名逗号隔开

错误操作:故意用逗号隔开class属性的多个类名。

<p class="class1,class2" >第3段</p>

样式面板查看元素应用的选择器,两个选择器均未应用。应将逗号改为空格。


4.4.2 ID选择器

1、语法

ID选择器定义

#id值{ /*样式定义*/}

匹配id属性为指定值的元素,id由开发人员自定义。

ID选择器调用

<标签名 id="id值">内容</标签名>

两处的id值需要完全一致。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>小步教程</title>

    <style>
        #id1{
            text-decoration: underline;
        }
    </style>
</head>
<body>
    <p>第1段</p>
    <p>第5段</p>
    <p id="id1">第6段</p>
</body>
</html>

2、需求场景说明

标签选择器与类选择器会匹配多个元素,实现多个元素的样式代码重用。

ID选择器的需求场景:页面存在一个特别元素,其它元素无法重用它的样式代码。


3、ID选择器与类选择器的区别

按照HTML规范,一个页面内多个元素的id不能重复,class可以重复指定。

下列是不规范代码示例,两个元素使用相同id。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>小步教程</title>

    <style>
        #id1{
            text-decoration: underline;
        }
    </style>
</head>
<body>
    <p id="id1">第6段</p>
    <p id="id1">第6段666</p>
</body>
</html>

无论显示是否正确,id重复属于不规范用法,禁止这样使用。当前Chrome浏览器与Firefox浏览器并未严格实现规范,两段都会加下划线。


4.4.3 同时匹配多种选择器

一个元素能够同时匹配多种选择器,包括标签选择器、类选择器等能匹配到的任何选择器。

示例代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>小步教程</title>

    <style>
        h4{
            margin: 10px 0;            
        }
        p{
            border: 1px solid #ccc;
            color: #333;
            margin: 5px 0;
        }

        .class1{
            font-size: 20px;
            font-weight: 800;
        }

        .class2{
            font-style: italic;
        }

        #id1{
            text-decoration: underline;
        }
    </style>
</head>
<body>
    <div>
        <h4>小步教程 xiaobuteach.com</h4>
        <p class="class1">第1段</p>
        <p class="class2">第2段</p>
        <p class="class1">第3段</p>
        <p class="class2">第4段</p>
        <p class="class1 class2">第5段</p>
        <p id="id1">第6段</p>
    </div>
</body>
</html>

样式面板查看“第5段”匹配的选择器:匹配到3个选择器,另外2个选择器不匹配。

img

试一试。说明一个元素匹配多个选择器的需求场景。


4.4.4 思考:样式面板里选择器的顺序是按照编码顺序吗?

是不是先写的选择器显示在样式面板的上方或下方? 详情见“5.6 选择器优先级”。


4.4.5 属性选择器

属性选择器定义

[标签属性名=属性值] { /*样式定义*/ }

匹配标签属性名等于属性值的元素。

属性选择器调用

<标签名 标签属性名="属性值">内容</标签名>

属性选择器常用于表单元素,因为多个不同表单控件使用相同的标签名input,但不同的type值。示例代码如下。

<body>
    <div>小步教程 xiaobuteach.com</div>
    <div><input type="text" value="小步教程"></div>
    <div><input type="button" value="确认"></div>
    <div><input value="xiaobuteach.com"></div>    
</body>

运行效果

img

对于input标签,type=text表示文本框,type=button表示按钮,没有type属性时默认text也是文本框。

选择器代码

        input[type=text]{
            color: #0aaa76;
        }
        input[type=button]{
            border: none;
            background-color: #0aaa76;
            color: #fff;
        }

上述两个选择器同时使用标签选择器(input)与属性选择器(type=),两者紧跟中间不能有空格,表示同一个元素同时符合这两个条件。

运行效果

img

第2个文本框没有指定type属性,虽然默认值是text,但没有匹配到input[type="text"]选择器。需要结合伪类选择器:not( )实现,表示不符合小括号内指定选择器。

        input:not([type]){
            color: #0aaa76;
        }

表示input不存在type属性的元素。


4.4.6 通配符选择器

(1)基本使用

*{ /*样式定义*/ }

*表示匹配所有元素。

示例代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>小步教程</title>

    <style>
        *{
            border: 1px solid #ccc;
            padding: 5px;
            margin: 5px;
        }
    </style>
</head>
<body>
    <div>
        <p>第1段</p>
        <p>第2段</p>
        <p>第3段</p>
        <p>第4段</p>
    </div>
</body>
</html>

运行效果

img

共显示4层边框,分别是html元素、body元素、div元素、p元素。


(2)全局公共样式

不是页面的全局公共样式都通过实现。实际项目根据CSS属性的可继承性分别处理:如果一个CSS属性是可继承,例如font-size与color,会放在body元素,其它后代元素会自动继承;当一个CSS属性是不可继承的,才通过表示。

body设置可继承属性示例

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>小步教程</title>

    <style>
        body{
            font-size: 20px;
            color: #0aaa76;
        }
    </style>
</head>
<body>
    <div>
        <p>第1段 小步教程 xiaobuteach.com</p>
        <p>第2段</p>
    </div>
</body>
</html>

运行效果

img

p元素继承祖先body元素的font-size与color属性,实现全局样式的设置。


(3)通配符修改CSS属性初始值

实际项目,大多数不可继承的CSS属性的默认值符合日常开发习惯,除box-sizing属性。早期设置默认值为content-box,后来最佳实践证明border-box更合理,使用通配符改变不可继承CSS属性box-sizing的初始值。详情见“5.3 属性初始默认值”与“第6章 盒子模型”。


4.4.7 伪类选择器

伪类选择器定义

:伪类名称{/*样式定义*/}

伪类选择器以单冒号开头,加伪类名称。伪类名称是由CSS规范定义,每个伪类有特定用途,并相应自动调用。这里介绍常用的hover伪类与first-child伪类。

伪类选择器作为简单选择器的一种,重点学习它的语法。实际运用不会单独使用,而是作为复合选择器的一部分,与其它选择器组合使用。

(1)伪类hover

伪类:hover表示鼠标悬停状态,鼠标移开后选择器无效。:hover是相当于JS事件的伪类。

需求场景:每个元素悬停时颜色变成蓝色。此需求没有实际意义,仅作研究语法用。

        :hover{
            border: 1px solid #0aaa76;
        }

因为body与html元素也具有hover伪类样式,所以需要鼠标移到窗口外,hover颜色才会消失。

事件冒泡机制。hover属于事件性质伪类。事件有冒泡机制,默认情况下,子元素的事件会同时冒泡给父元素,然后一直往上冒,各级都能捕捉到这个事件。

当鼠标指向“第3段”时,显示效果如下。

img

p“第3段”的祖先元素依次:div1、body、html,所以也会触发它们的hover事件,所以也显示边框。

注意事项。此案例使用border这个不可继承属性,而没有使用color等可继承属性。如果使用color,则无法准确看到其效果,因为鼠标悬停在任何元素,总是会触发html的hover事件,所有元素都会继承html元素的颜色,则总是所有元素显示指定颜色。


(2)伪类first-child

:first-child

:first-child判断每个元素是否它父元素的第一个子元素,如果是则匹配,如果不是则排除。


提问。:first-child匹配到哪几个元素?

        :first-child{
            border: 1px solid #4aa6fc;
        }

运行效果

img

结果是匹配到html、body、div1、“第1段”、“第3段”。head元素因为display:none没有生成盒子,所以body是html元素的第1个子元素。

last-child的逻辑与first-child完全相同,只是判断是否最后一个子元素。