CSS继承和选择器详解

86 阅读9分钟

CSS继承和选择器详解

骚话王又来分享知识了!今天咱们聊聊CSS选择器和继承,这可是前端开发中的基本功,但很多人就是搞不明白,一不小心就写出让人头秃的代码。CSS选择器就像是给网页元素贴标签,而继承就像是基因遗传,掌握好了能让你的代码优雅到飞起!

CSS继承机制

什么是CSS继承

CSS继承就像是现实生活中的基因遗传,子元素会继承父元素的某些样式属性。这让我们不用给每个元素都写一遍相同的样式,简直是懒人福音!

/* 父元素设置字体 */
body {
    font-family: 'Arial', sans-serif;
    color: #333;
    line-height: 1.6;
}

/* 子元素自动继承这些属性,不用重复写 */
.container {
    /* 不需要写 font-family、color、line-height */
    /* 这些属性会自动从body继承 */
    padding: 20px;
}

可继承的属性

不是所有CSS属性都能继承,只有这些属性会遗传给子元素:

文本相关属性

/* 这些属性会继承 */
font-family, font-size, font-weight, font-style
color, text-align, text-indent, line-height
letter-spacing, word-spacing, text-transform

列表相关属性

/* 列表样式会继承 */
list-style-type, list-style-image, list-style-position

表格相关属性

/* 表格边框会继承 */
border-collapse, border-spacing

其他属性

/* 这些也会继承 */
visibility, cursor, direction

不可继承的属性

这些属性不会遗传,每个元素都需要单独设置:

/* 盒模型属性不继承 */
margin, padding, border, width, height
background, position, display, float
overflow, z-index, box-shadow

继承的优先级

继承的优先级是最低的,比不过任何其他选择器:

/* 继承的样式 */
body {
    color: blue;
}

/* 元素选择器覆盖继承 */
p {
    color: red; /* 这个会生效,p标签显示红色 */
}

/* 类选择器覆盖元素选择器 */
.highlight {
    color: green; /* 这个会生效,显示绿色 */
}

CSS选择器详解

基础选择器

元素选择器:直接选择HTML元素

/* 选择所有p标签 */
p {
    color: red;
    font-size: 16px;
}

/* 选择所有div标签 */
div {
    background-color: #f0f0f0;
    padding: 10px;
}

类选择器:选择具有特定class的元素

/* 选择class为"highlight"的元素 */
.highlight {
    background-color: yellow;
    font-weight: bold;
}

/* 选择class为"error"的元素 */
.error {
    color: red;
    border: 1px solid red;
}

/* 选择class为"success"的元素 */
.success {
    color: green;
    border: 1px solid green;
}

ID选择器:选择具有特定id的元素(页面中唯一)

/* 选择id为"header"的元素 */
#header {
    background-color: #333;
    color: white;
    padding: 20px;
}

/* 选择id为"footer"的元素 */
#footer {
    background-color: #666;
    color: white;
    text-align: center;
}

通配符选择器:选择所有元素

/* 选择所有元素,重置默认样式 */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* 选择所有元素,设置基础字体 */
* {
    font-family: 'Arial', sans-serif;
}

组合选择器

后代选择器:选择指定元素内的所有后代元素

/* 选择div内的所有p标签 */
div p {
    color: blue;
    margin-bottom: 10px;
}

/* 选择.container内的所有a标签 */
.container a {
    color: #007bff;
    text-decoration: none;
}

.container a:hover {
    text-decoration: underline;
}

子元素选择器:只选择直接子元素

/* 只选择ul的直接子元素li */
ul > li {
    list-style-type: none;
    padding: 5px 0;
}

/* 只选择nav的直接子元素a */
nav > a {
    display: inline-block;
    padding: 10px 15px;
}

相邻兄弟选择器:选择紧跟在指定元素后的兄弟元素

/* 选择紧跟在h1后的p标签 */
h1 + p {
    font-size: 18px;
    color: #666;
    margin-top: 10px;
}

/* 选择紧跟在.error后的.success */
.error + .success {
    margin-top: 10px;
}

通用兄弟选择器:选择指定元素后的所有兄弟元素

/* 选择h2后的所有p标签 */
h2 ~ p {
    text-indent: 20px;
    line-height: 1.8;
}

/* 选择.highlight后的所有span */
.highlight ~ span {
    font-weight: bold;
}

属性选择器

基础属性选择器:选择具有特定属性的元素

/* 选择有title属性的元素 */
[title] {
    cursor: help;
}

/* 选择有class属性的元素 */
[class] {
    border: 1px solid #ccc;
}

属性值选择器:选择属性值等于指定值的元素

/* 选择type为"text"的input */
input[type="text"] {
    border: 1px solid #ccc;
    padding: 8px;
}

/* 选择class为"btn"的元素 */
[class="btn"] {
    background-color: #007bff;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
}

属性值包含选择器:选择属性值包含指定字符串的元素

/* 选择class包含"btn"的元素 */
[class*="btn"] {
    cursor: pointer;
    transition: all 0.3s;
}

/* 选择href包含"example.com"的链接 */
a[href*="example.com"] {
    color: #ff6b6b;
}

属性值开头选择器:选择属性值以指定字符串开头的元素

/* 选择class以"btn-"开头的元素 */
[class^="btn-"] {
    border-radius: 4px;
    font-weight: bold;
}

/* 选择href以"https"开头的链接 */
a[href^="https"] {
    color: #28a745;
}

属性值结尾选择器:选择属性值以指定字符串结尾的元素

/* 选择class以"-primary"结尾的元素 */
[class$="-primary"] {
    background-color: #007bff;
    color: white;
}

/* 选择src以".jpg"结尾的图片 */
img[src$=".jpg"] {
    border: 2px solid #ddd;
}

伪类选择器

状态伪类:基于元素状态选择

/* 链接状态 */
a:link {
    color: #007bff;
}

a:visited {
    color: #6f42c1;
}

a:hover {
    color: #0056b3;
    text-decoration: underline;
}

a:active {
    color: #dc3545;
}

/* 表单元素状态 */
input:focus {
    outline: none;
    border-color: #007bff;
    box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

input:disabled {
    background-color: #e9ecef;
    cursor: not-allowed;
}

/* 复选框和单选框状态 */
input:checked {
    accent-color: #007bff;
}

结构伪类:基于元素位置选择

/* 第一个子元素 */
li:first-child {
    font-weight: bold;
    color: #007bff;
}

/* 最后一个子元素 */
li:last-child {
    border-bottom: none;
}

/* 第n个子元素 */
li:nth-child(odd) {
    background-color: #f8f9fa;
}

li:nth-child(even) {
    background-color: #ffffff;
}

/* 第3个子元素 */
li:nth-child(3) {
    color: #dc3545;
}

/* 倒数第2个子元素 */
li:nth-last-child(2) {
    font-style: italic;
}

/* 唯一子元素 */
p:only-child {
    font-size: 18px;
    color: #28a745;
}

其他伪类

/* 空元素 */
div:empty {
    display: none;
}

/* 否定选择器 */
p:not(.highlight) {
    color: #666;
}

/* 目标元素(锚点链接的目标) */
:target {
    background-color: #fff3cd;
    border: 1px solid #ffeaa7;
    padding: 10px;
}

伪元素选择器

内容伪元素:在元素内容前后添加内容

/* 在元素前添加内容 */
p::before {
    content: "→ ";
    color: #007bff;
    font-weight: bold;
}

/* 在元素后添加内容 */
p::after {
    content: " ←";
    color: #dc3545;
    font-weight: bold;
}

/* 首字母样式 */
p::first-letter {
    font-size: 2em;
    font-weight: bold;
    color: #007bff;
    float: left;
    margin-right: 5px;
}

/* 首行样式 */
p::first-line {
    font-weight: bold;
    color: #28a745;
}

选择伪元素

/* 选中文本的样式 */
::selection {
    background-color: #007bff;
    color: white;
}

/* 占位符文本样式 */
input::placeholder {
    color: #6c757d;
    font-style: italic;
}

选择器优先级

优先级计算规则

CSS选择器的优先级就像是游戏里的战斗力,谁的战斗力高谁就赢:

/* 内联样式:1000分 */
<div style="color: red;">内联样式</div>

/* ID选择器:100分 */
#header { color: blue; }

/* 类选择器、属性选择器、伪类:10分 */
.highlight { color: green; }
[type="text"] { color: orange; }
:hover { color: purple; }

/* 元素选择器、伪元素:1分 */
p { color: black; }
::before { color: gray; }

优先级示例

/* 优先级:1分 */
p {
    color: black;
}

/* 优先级:10分 */
.highlight {
    color: green;
}

/* 优先级:11分(1+10) */
p.highlight {
    color: blue;
}

/* 优先级:100分 */
#header {
    color: red;
}

/* 优先级:110分(100+10) */
#header .highlight {
    color: orange;
}

/* 优先级:111分(100+10+1) */
#header p.highlight {
    color: purple;
}

优先级相同的情况

当优先级相同时,后面的样式会覆盖前面的:

/* 两个都是10分,后面的生效 */
.highlight {
    color: green;
}

.highlight {
    color: blue; /* 这个生效 */
}

使用!important

!important就像是开挂,优先级直接拉满:

/* 正常优先级 */
p {
    color: black;
}

/* 使用!important,优先级最高 */
p {
    color: red !important; /* 这个生效 */
}

经典应用示例

导航菜单样式

<nav class="navbar">
    <ul class="nav-list">
        <li><a href="#home">首页</a></li>
        <li><a href="#about">关于</a></li>
        <li><a href="#services">服务</a></li>
        <li><a href="#contact">联系</a></li>
    </ul>
</nav>
/* 导航菜单样式 */
.navbar {
    background-color: #333;
    padding: 15px 0;
}

.nav-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
}

.nav-list > li {
    margin: 0 15px;
}

.nav-list a {
    color: white;
    text-decoration: none;
    padding: 10px 15px;
    border-radius: 4px;
    transition: background-color 0.3s;
}

.nav-list a:hover {
    background-color: #555;
}

.nav-list a:active {
    background-color: #666;
}

表单样式

<form class="contact-form">
    <div class="form-group">
        <label for="name">姓名:</label>
        <input type="text" id="name" name="name" required>
    </div>
    <div class="form-group">
        <label for="email">邮箱:</label>
        <input type="email" id="email" name="email" required>
    </div>
    <div class="form-group">
        <label for="message">消息:</label>
        <textarea id="message" name="message" rows="4"></textarea>
    </div>
    <button type="submit" class="btn btn-primary">发送</button>
</form>
/* 表单样式 */
.contact-form {
    max-width: 500px;
    margin: 0 auto;
    padding: 20px;
}

.form-group {
    margin-bottom: 20px;
}

.form-group label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
    color: #333;
}

.form-group input,
.form-group textarea {
    width: 100%;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 16px;
    transition: border-color 0.3s;
}

.form-group input:focus,
.form-group textarea:focus {
    outline: none;
    border-color: #007bff;
    box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

.form-group input:invalid {
    border-color: #dc3545;
}

.btn {
    padding: 12px 24px;
    border: none;
    border-radius: 4px;
    font-size: 16px;
    cursor: pointer;
    transition: all 0.3s;
}

.btn-primary {
    background-color: #007bff;
    color: white;
}

.btn-primary:hover {
    background-color: #0056b3;
}

.btn-primary:active {
    background-color: #004085;
}

卡片组件

<div class="card-container">
    <div class="card">
        <div class="card-header">
            <h3>标题</h3>
        </div>
        <div class="card-body">
            <p>这是卡片的内容...</p>
        </div>
        <div class="card-footer">
            <button class="btn btn-sm">操作</button>
        </div>
    </div>
</div>
/* 卡片组件样式 */
.card-container {
    display: flex;
    justify-content: center;
    padding: 20px;
}

.card {
    width: 300px;
    border: 1px solid #ddd;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    transition: box-shadow 0.3s;
}

.card:hover {
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

.card-header {
    background-color: #f8f9fa;
    padding: 15px;
    border-bottom: 1px solid #ddd;
}

.card-header h3 {
    margin: 0;
    color: #333;
}

.card-body {
    padding: 15px;
}

.card-body p {
    margin: 0;
    color: #666;
    line-height: 1.6;
}

.card-footer {
    background-color: #f8f9fa;
    padding: 15px;
    border-top: 1px solid #ddd;
    text-align: right;
}

.btn-sm {
    padding: 8px 16px;
    font-size: 14px;
}

最佳实践和常见陷阱

选择器命名规范

/* 推荐:使用语义化的类名 */
.user-profile { }
.contact-form { }
.navigation-menu { }

/* 不推荐:使用无意义的类名 */
.div1 { }
.box { }
.container { }

/* 推荐:使用BEM命名法 */
.card { }
.card__header { }
.card__body { }
.card--featured { }

避免过度嵌套

/* 不推荐:过度嵌套 */
.container .wrapper .content .sidebar .widget .title {
    color: red;
}

/* 推荐:使用更具体的选择器 */
.widget-title {
    color: red;
}

/* 或者使用ID选择器 */
#sidebar .widget-title {
    color: red;
}

合理使用!important

/* 不推荐:滥用!important */
p {
    color: red !important;
}

.highlight {
    color: blue !important;
}

/* 推荐:通过提高选择器优先级 */
.container p.highlight {
    color: blue;
}

性能优化

/* 不推荐:使用通配符选择器 */
* {
    margin: 0;
    padding: 0;
}

/* 推荐:明确指定元素 */
body, h1, h2, h3, p, ul, li {
    margin: 0;
    padding: 0;
}

/* 不推荐:使用后代选择器查找深层元素 */
.container div div div p {
    color: red;
}

/* 推荐:给目标元素添加类名 */
.content-paragraph {
    color: red;
}

CSS选择器和继承就像是前端开发的基石,掌握好了能让你的代码既优雅又高效。记住,选择器不是越多越好,而是要精准有效。继承也不是万能的,要合理利用才能事半功倍。

如果觉得有用就收藏点赞,咱们下期再见!