CSS选择器文档
本文档基于15个HTML示例文件介绍了CSS的各种技巧实践,旨在记录开发时候CSS的场景应用。
- 影子DOM样式隔离
- :not()伪类简化代码
- :is()伪类简化选择器
- :active伪类实现埋点统计
- :focus-within实现搜索交互
<small>标签的使用<details>和<summary>实现折叠面板- :placeholder-shown实现输入提示
- :default伪类标记默认选项
<label>交互与计数器- 表单校验与反馈
<fieldset>和<legend>组织表单- :empty伪类处理空内容
- :only-child伪类条件显示
- :not()伪类初始化样式
1. 影子DOM样式隔离
使用attachShadow()方法创建影子DOM,实现组件的样式隔离,避免样式冲突。
<body>
<p>外部文字,颜色为黑色</p>
<div id="hostElement"></div>
</body>
<script>
const hostElement = document.querySelector('#hostElement')
const shadow = hostElement.attachShadow({ mode: 'open' })
shadow.innerHTML = `<p>可以实现组件的样式隔离,颜色为红色</p>`
shadow.innerHTML += `<style>p{color:red}</style>`
</script>
- 组件开发,特别是自定义元素
- 第三方插件集成
- 样式封装和隔离
2. :not()伪类简化代码
使用:not()伪类排除特定元素,简化CSS选择器,避免重复样式定义。
<ul>
<li>列表1</li>
<li>列表2</li>
<li>列表3</li>
</ul>
<style>
/*列表最后一项排除*/
li:not(:last-child){
border-bottom: 1px solid black;
padding-bottom:8px;
margin-bottom: 8px;
}
</style>
- 列表项样式处理(如最后一项无边框)
- 导航菜单样式
- 表单元素样式排除
3. :is()伪类简化选择器
使用:is()伪类将多个选择器组合成一个,简化CSS代码结构,提高可读性。
<body>
<header> <a href='#'> 头部字体 </a> </header>
<main> <a href='#'> 主题字体 </a> </main>
<footer> <a href='#'> 底部字体 </a> </footer>
</body>
<style>
/* 常见嵌套写法,需经过编译
header,main,footer{
a{ color: red; }
}
编译过后
header a,main a,footer a{ color: red }
*/
/* :is() 是原生 CSS 语法,无需编译,浏览器直接识别 */
:is(header, main, footer) a { color: red }
</style>
- 多个容器内相同元素的样式统一
- 复杂选择器的简化
4. :active伪类实现埋点统计
使用:active伪类结合content属性,实现无JavaScript的埋点统计功能。
<body>
<button class="button1">点我上传</button>
<button class="button2">点我上传2</button>
</body>
<style>
/* 第一次点击可以触发 */
.button1:active::after{
content: url(./pixxel.gif?action=click&id=button1);
}
.button2:active::after{
content: url(./pixxel.gif?action=click&id=button2);
}
</style>
- 简单的用户行为统计
- 按钮点击事件追踪
- 无需JavaScript的埋点方案
5. :focus-within实现搜索交互
使用:focus-within伪类实现父元素在子元素获得焦点时的样式变化,适用于搜索框下拉菜单等交互场景。
<!-- 适合做 搜索框结果的 下拉 -->
<div class="cs-details">
<a href="javascript:" class="cs-summary">我的消息</a>
<div class="cs-datalist">
<a href>我的回答<sup>12</sup></a>
<a href>我的私信</a>
<a href>未评价订单</a>
<a href>我的关注</a>
</div>
</div>
<style>
.cs-datalist {
display: none;
position: absolute;
border: 1px solid #000;
background-color: #fff;
}
.cs-details:focus-within .cs-datalist {
display: block;
}
</style>
- 搜索框下拉菜单
- 导航菜单的子菜单显示
- 表单元素的关联信息展示
6. <small>标签的使用
使用<small>标签表示小号文本,通常用于免责声明、注释等次要信息。
<small>你好</small>
<div>你好123</div>
- 法律声明和条款
- 文章注释和说明
- 表单字段的辅助信息
7. <details>和<summary>实现折叠面板
使用<details>和<summary>标签实现原生的折叠面板功能,无需JavaScript。
<details style="user-select:none;">
<summary>请选择</summary>
<ul>
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
</ul>
</details>
- 常见问题解答(FAQ)
- 内容折叠展示
- 配置选项面板
8. :placeholder-shown实现输入提示
使用:placeholder-shown伪类检测输入框是否显示占位符,实现输入状态的样式变化。
<input type="search" placeholder="请输入内容">
<small>尚未输入内容</small>
<style>
:not(:placeholder-shown)+small {
color: transparent;
}
</style>
- 输入框的状态提示
- 表单验证的视觉反馈
- 提升用户输入体验
9. :default伪类标记默认选项
使用:default伪类标记表单中的默认选项,如默认选中的单选按钮。
<!-- 更换选择,自动补充(推荐) -->
<p>请选择支付方式:</p>
<p><input name="pay" type="radio"><label>支付宝</label></p>
<p><input name="pay" type="radio" checked><label>微信</label></p>
<p><input name="pay" type="radio"><label>银行卡</label></p>
<style>
input:default+label::after {
content: '(推荐)';
}
</style>
- 表单默认选项标记
- 推荐选项提示
- 提高用户表单填写效率
10. <label>交互与计数器
使用<label>标签与复选框关联,结合CSS计数器实现选中项数量统计。
<body>
<p>请选择你感兴趣的话题:</p>
<input type="checkbox" id="topic1">
<label for="topic1" class="cs-topic">科技</label>
<input type="checkbox" id="topic2">
<label for="topic2" class="cs-topic">体育</label>
<input type="checkbox" id="topic3">
<label for="topic3" class="cs-topic">军事</label>
<input type="checkbox" id="topic4">
<label for="topic4" class="cs-topic">娱乐</label>
<p>您已选择 <span class="cs-topic-counter"></span>个话题。</p>
</body>
<style>
.cs-topic {
padding:5px 15px;
cursor: pointer;
border: 1px solid #000;
}
:checked+.cs-topic {
border-color: skyblue;
background-color: azure;
}
[type='checkbox'] {
position: absolute;
clip: rect(0 0 0 0);
}
body {
counter-reset: topicCounter;
}
:checked+.cs-topic {
counter-increment: topicCounter;
}
.cs-topic-counter::before {
content: counter(topicCounter);
}
</style>
- 兴趣标签选择
- 商品属性选择
- 多选项表单交互
11. 表单校验与反馈
使用CSS伪类实现表单验证的视觉反馈,包括输入合法、非法和空值状态。
<!-- 表单校验 -->
<form id="csForm" novalidate>
<p>
验证码:
<input class="cs-input" required pattern="\w{4}" placeholder="">
<span class="cs-vaild-tips"></span>
</p>
<input type="submit" />
</form>
<style>
/* 校验通过 */
.cs-input:valid {
background-color: green;
color: #fff;
}
.valid .cs-input:valid+.cs-vaild-tips::before {
content: '√';
color: green;
}
/* 校验不合法提示 */
.valid .cs-input:not(:placeholder-shown):invalid {
border: 2px solid red;
}
.valid .cs-input:not(:placeholder-shown):invalid+.cs-vaild-tips::before {
content: '不符合要求';
color: red;
}
/* 空值提示 */
.valid .cs-input:placeholder-shown+.cs-vaild-tips::before {
content: '尚未输入值';
}
</style>
<script>
const form = document.querySelector('#csForm')
const input = document.querySelector('.cs-input')
// 即时的校验
// form.addEventListener('input',(e)=>{
// form.classList.add('valid')
// })
// 优化:输入时实时更新校验提示(可选,提升体验)
input.addEventListener('input', () => {
if (form.classList.contains('valid')) {
// 强制重绘,更新样式
void form.offsetWidth;
}
})
form.addEventListener('submit', (e) => {
e.preventDefault()
form.classList.add('valid') // 触发校验样式
if (form.checkValidity()) {
alert('校验通过')
}
})
</script>
- 表单验证反馈
- 实时输入校验
- 提升表单填写体验
12. <fieldset>和<legend>组织表单
使用<fieldset>和<legend>标签组织表单内容,提高表单的结构性。
<form>
<fieldset>
<legend>问卷调查</legend>
<ol>
<li>1-3年</li>
<li>3-5年</li>
<li>5年以上</li>
<h4>你从事前端几年了?</h4>
</ol>
</fieldset>
</form>
- 复杂表单的分组
- 提高表单的可访问性
- 增强表单的语义结构
13. :empty伪类处理空内容
使用:empty伪类检测元素是否为空,为空白元素添加默认内容或样式。
<dl>
<dt>姓名:</dt> <dd>张三</dd>
<dt>性别:</dt> <dd></dd>
<dt>手机:</dt> <dd></dd>
<dt>邮箱:</dt> <dd></dd>
</dl>
<!-- :empty 兼容 ''、null,配合伪元素可填充自定义内容 -->
<style>
dt { float: left }
dd:empty::before {
color: gray;
/* content: '-'; */
content: '暂无';
}
</style>
- 数据展示中的空值处理
- 搜索结果为空的提示
- 表单字段的默认显示
14. :only-child伪类条件显示
使用:only-child伪类检测元素是否为唯一子元素,实现条件性的样式显示。
<ul>
<li> 仅剩一项时不可删除 <button>删除</button> </li>
<li> 仅剩一项时不可删除 <button>删除</button> </li>
<li> 仅剩一项时不可删除 <button>删除</button> </li>
</ul>
<style>
li:only-child button { display: none }
</style>
<script>
// 点击删除 li
const buttons = document.querySelectorAll('li button')
buttons.forEach(btn => {
btn.addEventListener('click', function () {
btn.parentElement.remove()
})
})
</script>
- 列表项的删除按钮控制
- 条件性UI元素显示
- 动态内容的样式调整
15. :not()伪类初始化样式
使用:not()伪类排除特定元素,实现样式的初始化和重置。
<!-- 激活面板优雅切换 -->
<!--
<div class="cs-panel">面板1</div>
<div class="cs-panel active">面板2</div>
<div class="cs-panel">面板3</div>
<style> .cs-panel:not(.active) { display: none} </style>
-->
<!-- 灵活性 -->
<div class="cs-panel">面板1</div>
<div class="cs-panel flex">面板2</div>
<div class="cs-panel active grid">面板3</div>
<style>
.cs-panel:not(.active) { display: none }
.flex { display: flex }
.grid { display: grid }
</style>
- 选项卡面板切换
- 激活状态的样式控制
- 组件的默认状态管理
总结
本文档介绍了CSS新世界中的15个实用技巧,涵盖了样式隔离、选择器优化、表单交互、内容展示等多个方面。这些技巧充分利用了现代CSS的新特性,能够帮助开发者编写更简洁、高效、可维护的代码,同时提升用户体验。
随着CSS标准的不断发展,我们可以期待更多强大的特性和技巧出现。希望本文档能够为开发者提供参考,让大家在CSS的世界中探索更多可能性。
参考资源
- 张鑫旭《css选择器》