当前位置: 首页 > backend >正文

CSS 伪类与伪元素:深度解析

在前端开发中,CSS 伪类和伪元素是两个强大的工具,它们能让你在不改动 HTML 结构的情况下,为元素添加复杂的样式和动态效果。它们就像 CSS 的“超能力”,让你的网页更具交互性和表现力。本文将带你深入了解它们的概念和用法,并通过代码案例让你彻底掌握。


一、伪类 (Pseudo-classes)

伪类是附加在选择器上的关键字,用于选择处于特定状态或位置的元素。它们的语法是一个冒号 (: )。

1. 用户行为伪类 (User Action Pseudo-classes)

这些伪类根据用户的交互行为来改变元素样式,是提升用户体验的关键。

  • :active: 选中元素被激活时的状态,通常是鼠标点击或按住时。
    • 案例: 鼠标点击按钮时,让按钮背景变暗。
    button:active {background-color: darkgray;transform: translateY(1px);
    }
    
  • :hover: 选中鼠标悬停在元素上时的状态。
    • 案例: 鼠标移入链接时,改变链接颜色。
    a:hover {color: crimson;
    }
    
  • :focus: 选中元素获得焦点时的状态,常用于表单输入框。
    • 案例: 用户点击输入框时,添加高亮边框。
    input:focus {outline: 2px solid deepskyblue;
    }
    
  • :focus-within: 选中当元素本身或其任何后代元素获得焦点时的状态。
    • 案例: 当表单内的任意输入框被选中时,整个表单添加边框。
    form:focus-within {border: 2px solid lightgreen;
    }
    

2. 输入伪类 (Input Pseudo-classes)

这些伪类专门用于根据表单元素的不同状态来添加样式,帮助用户进行输入校验。

  • :enabled: 选中当前可用的表单元素。
  • :disabled: 选中当前禁用的表单元素。
    • 案例: 让被禁用的输入框呈现灰色,并改变光标样式。
    input:disabled {background-color: lightgray;cursor: not-allowed;
    }
    
  • :checked: 选中已被勾选的复选框或单选按钮。
    • 案例: 选中复选框后,改变其背景颜色。
    input[type="checkbox"]:checked {background-color: blue;
    }
    
  • :valid & :invalid: 选中输入内容有效或无效的表单元素。
    • 案例: 根据输入是否为有效邮箱,改变边框颜色。
    input[type="email"]:valid {border-color: green;
    }
    input[type="email"]:invalid {border-color: red;
    }
    
  • :required & :optional: 选中带有 required 属性或不带该属性的输入元素。
    • 案例: 为必填项添加一个特殊的背景色。
    input:required {background-color: #fff9e6;
    }
    
  • :autofill: 选中被浏览器自动填充的输入框。
  • :in-range & :out-of-range: 选中值在指定范围之内或之外的输入元素。

3. 位置伪类 (Location Pseudo-classes)

这些伪类根据链接的访问历史或 URL 片段来定位和样式化元素。

  • :any-link: 选中所有带有 href 属性的链接,无论是否被访问过。
  • :link: 选中所有未被访问过的链接。
  • :visited: 选中用户已经访问过的链接。
    • 案例: 为访问过的链接设置不同的颜色,帮助用户区分。
    a:visited {color: #8a2be2; /* 紫色 */
    }
    
  • :target: 选中 URL 锚点所指向的元素。
    • 案例: 当用户点击导航链接跳转到某个章节时,高亮该章节。
    <a href="#intro">跳到引言</a>
    <div id="intro">...</div>
    
    /* CSS */
    #intro:target {background-color: lightyellow;
    }
    
  • :local-link & :target-within: 这些是较新的伪类,用于定位指向同一文档的链接或其子元素。

4. 树结构伪类 (Tree-structural Pseudo-classes)

这些伪类根据元素在 HTML 文档树中的位置来选择它们,是构建灵活布局的利器。

  • :root: 选中文档的根元素,通常是 <html>
  • :empty: 选中不包含任何子元素(包括文本和空格)的元素。
    • 案例: 隐藏空的警告信息容器。
    .alert-box:empty {display: none;
    }
    
  • :nth-child(n) & :nth-last-child(n): 根据位置选择元素。
  • :first-child & :last-child: 选中父元素下的第一个或最后一个子元素。
  • :only-child: 选中父元素下唯一的子元素。
    • 案例: 为唯一的列表项添加特殊样式。
    li:only-child {font-weight: bold;
    }
    
  • :first-of-type & :last-of-type: 选中父元素下同类型元素的第一个或最后一个。
    • 案例: 选中每个 section 中的第一个段落。
    section p:first-of-type {text-indent: 2rem;
    }
    
  • :nth-of-type(n) & :only-of-type: 根据同类型元素的位置进行选择。

5. 功能伪类 (Functional Pseudo-classes)

这些伪类接受参数,允许你进行更复杂的条件选择。

  • :is() & :where(): 这两个伪类都接受一个选择器列表,并选中匹配其中任意一个的元素。:where() 的特异性为零,非常适合用于样式重置。
    • 案例: 简化复杂选择器。
    /* 传统写法 */
    section h1, article h1, aside h1 {font-size: 2rem;
    }
    /* 使用 :is() */
    :is(section, article, aside) h1 {font-size: 2rem;
    }
    
  • :has(): 俗称“父选择器”,选中包含特定子元素的父元素。
    • 案例: 只有当卡片包含图片时,才为其添加阴影。
    .card:has(img) {box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    }
    
  • :not(): 选中不匹配给定选择器的所有元素。
    • 案例: 为除了 .primary 类之外的所有按钮设置灰色背景。
    button:not(.primary) {background-color: gray;
    }
    

二、伪元素 (Pseudo-elements)

伪元素是虚拟的、不存在于 HTML 中的元素,用于对元素中的特定部分进行样式设置,或在其前后插入内容。它们的语法是两个冒号 (::)。

  • ::before & ::after: 在元素内容的前面或后面插入内容。它们必须和 content 属性一起使用。
    • 案例: 在链接前添加一个图标。
    a::before {content: "➡️";margin-right: 5px;
    }
    
  • ::first-letter: 选中元素文本内容的第一个字母。
    • 案例: 为段落首字母创建“大写首字下沉”效果。
    p::first-letter {font-size: 3rem;color: blue;
    }
    
  • ::marker: 选中列表项的标记(如项目符号或编号)。
    • 案例: 改变列表标记的颜色。
    li::marker {color: green;
    }
    
  • ::placeholder: 选中表单输入框的占位符文本。
  • ::selection: 选中用户用鼠标高亮选择的文本。

掌握了这些伪类和伪元素,你就能用 CSS 创造出更加动态和丰富的网页体验,让你的代码更简洁、更强大。

http://www.xdnf.cn/news/19804.html

相关文章:

  • 从零构建Linux Shell解释器深入理解Bash进程创建机制
  • 【Spring Cloud微服务】11.微服务通信演义:从飞鸽传书到5G全息,一部消息中间件的进化史诗
  • Java项目打包成EXE全攻略​
  • Ubuntu22.04下编译googletest源代码生成.so动态库
  • 利用 openssl api 实现 TLS 双向认证
  • MySQL-MVCC多版本并发控制详解
  • LangChain实战(十二):自定义Tools扩展Agent能力
  • Python+DRVT 从外部调用 Revit:批量创建门
  • Streamable HTTP
  • sv中forever如何结束
  • AI 在金融、医疗、教育、制造业等领域有着广泛的应用,以下是这些领域的一些落地案例
  • STM32HAL 快速入门(十七):UART 硬件结构 —— 从寄存器到数据收发流程
  • 告别剪辑烦恼!3个超实用技巧,让你的视频瞬间高级起来
  • 【音视频】视频秒播优化实践
  • UnityWebRequest 数据获取和提交
  • wpf 只能输入int类型的文本框
  • WebSocket客户端库:websocket-fruge365
  • Ubuntu下把 SD 卡格式化为 FAT32
  • Hostol Magento电商服务器套餐:基于阿里云,预配置高性能环境,一键开店
  • 如何用java给局域网的电脑发送开机数据包
  • B样条曲线,已知曲线上的某个点到起点的距离,确定这个点的参数u的值的方法
  • 新手向:破解VMware迁移难题
  • MP4视频太大如何压缩?分享6种简单便捷的压缩小技巧
  • websocket用于控制在当前页只允许一个用户进行操作,其他用户等待
  • 硬件(一)51单片机
  • 阿里开源首个图像生成基础模型——Qwen-Image本地部署教程,中文渲染能力刷新SOTA
  • HTTP 协议核心组件与安全扩展深度解析
  • 机器学习与深度学习的 Python 基础之 NumPy(2)
  • uniapp+vue3 微信小程序全屏广告组件功能
  • AI IDE+AI 辅助编程,真能让程序员 “告别 996” 吗?