时间:2026-02-28 15:20
人气:
作者:admin
点赞 + 收藏 === 学会????????????
display: contents是一个相对较新的 CSS 属性值,它会让元素自身不生成任何盒子,但它的子元素和伪元素仍然正常生成。简单说:元素本身从渲染树中消失,但它的孩子还在。
<div class="parent"> <div class="child">内容</div> </div>
/* 正常情况下 */
.parent {
display: block; /* parent 生成一个块级盒子 */
}
/* 使用 contents 后 */
.parent {
display: contents; /* parent 不生成盒子,child 直接"上升"到 parent 的位置 */
}
应用前:
<main>
<div class="grid-container"> <!-- 这个元素只是个包装 -->
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
</main>
应用后:
<main> <!-- grid-container 元素消失了,但它的子元素还在 --> <div>Item 1</div> <div>Item 2</div> <div>Item 3</div> </main>
<!-- 想要使用 ul,但又需要 flex 布局 --> <ul style="display: contents;"> <li>项目1</li> <li>项目2</li> <li>项目3</li> </ul>
ul {
display: contents; /* ul 本身不生成盒子 */
}
/* li 直接参与父容器的布局 */
.parent-of-ul {
display: flex; /* li 会成为 flex 项目,而不是 ul */
}
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
/* 包装器不破坏网格布局 */
.wrapper {
display: contents;
/* 这个元素不生成盒子,它的子元素直接成为 grid 项目 */
}
html
<div class="grid-container">
<div>直接项目1</div>
<div class="wrapper"> <!-- 这个元素不占位置 -->
<div>包装的项目2</div>
<div>包装的项目3</div>
</div>
<div>直接项目4</div>
</div>
.flex-container {
display: flex;
}
.group {
display: contents; /* 子元素直接成为 flex 项目 */
}
<div class="flex-container">
<div>项目1</div>
<div class="group"> <!-- 这个 div 不生成盒子 -->
<div>组内项目1</div> <!-- 直接成为 flex 项目 -->
<div>组内项目2</div> <!-- 直接成为 flex 项目 -->
</div>
<div>项目3</div>
</div>
<table>
<tr style="display: contents;"> <!-- tr 不生成盒子 -->
<td>单元格1</td>
<td>单元格2</td>
<td>单元格3</td>
<!-- td 直接成为 table 的子元素 -->
</tr>
</table>
/* 原本需要额外 div 来添加样式 */
.card {
display: flex;
}
.card-extra {
display: contents; /* 这个 div 只用于逻辑分组,不影响布局 */
}
/* 现在可以更灵活地组织代码 */
<div class="responsive-grid">
<!-- 移动端:堆叠显示 -->
<!-- 桌面端:网格显示 -->
<div class="group" style="display: contents;">
<div>项目A</div>
<div>项目B</div>
</div>
</div>
/* ⚠️ 注意:元素本身消失,但语义还在吗? */
.button-group {
display: contents;
role: group; /* 虽然设置了 ARIA 角色,但元素不生成盒子,可能无效 */
}
// ⚠️ 元素不生成盒子,点击事件可能无法在元素上触发
document.querySelector('.contents-element').addEventListener('click', () => {
// 这个元素在视觉上不存在,点击区域是子元素的
});
.contents-element {
display: contents;
background: red; /* ❌ 不会显示,因为元素没有盒子 */
border: 1px solid; /* ❌ 不会显示 */
padding: 10px; /* ❌ 不会显示 */
margin: 10px; /* ❌ 不会显示 */
width: 100px; /* ❌ 不会显示 */
height: 100px; /* ❌ 不会显示 */
}
.contents-element {
display: contents;
}
.contents-element::before {
content: "✨"; /* ✅ 伪元素仍然会显示,成为第一个子元素 */
}
/* 在开发者工具中检查元素布局 */
.contents-element {
display: contents;
outline: 2px solid red; /* 不会显示,帮助理解元素确实消失了 */
}
.contents-element {
display: contents;
/* 临时查看元素范围 */
display: block; /* 临时改为 block 查看原始位置 */
}
<div class="card-grid">
<!-- 想要分组但不破坏网格 -->
<div class="card-group" style="display: contents;">
<div class="card">卡片1</div>
<div class="card">卡片2</div>
</div>
<div class="card-group" style="display: contents;">
<div class="card">卡片3</div>
<div class="card">卡片4</div>
</div>
</div>
.card-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
}
/* card-group 不破坏网格,所有卡片直接成为 grid 项目 */
优点:
缺点:
最佳实践:
