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选择器和继承就像是前端开发的基石,掌握好了能让你的代码既优雅又高效。记住,选择器不是越多越好,而是要精准有效。继承也不是万能的,要合理利用才能事半功倍。
如果觉得有用就收藏点赞,咱们下期再见!