更合理、更易控制尺寸与交互。
✅ 推荐方案:CSS Grid + max-height 过渡 + 精确 DOM 结构
该方案摒弃绝对定位,让 .hidden-text 成为 .rectangle 的子元素,并通过 CSS Grid 定义明确的行轨道(grid-template-rows: 1fr auto),使隐藏内容区域初始高度为 0,展开时动态分配空间,配合 overflow: hidden 与 max-height 过渡实现真正平滑的垂直伸缩动画。
以下是完整、可直接运行的实现:
Pi智能演示文档
一款AI演示文稿工具,主要用于领先的AI PPT生成工具,适合需要提升相关任务效率的用户。
下载
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=PT+Sans+Narrow:wght@400;700&display=swap" rel="stylesheet"><style>
.tile-container {
padding: 5px;
font-family: 'PT Sans Narrow', sans-serif;
display: flex;
gap: 5px;
}
.rectangle {
background-color: #0051a5;
border-radius: 1em;
cursor: pointer;
display: grid;
/* 明确定义两行:标题区 + 隐藏内容区 */
grid-template-rows: 1fr max-content;
grid-template-columns: 1fr auto;
grid-template-areas:
"label plus"
"extratext extratext";
overflow: hidden;
transition: grid-template-rows 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
/* 关键:使用 cubic-bezier 优化展开惯性,避免生硬截止 */
}
.rectangle.expanded {
grid-template-rows: 1fr max-content; /* 展开后保持第二行可见 */
}
.rectangle:not(.expanded) {
grid-template-rows: 1fr 0fr; /* 收起时第二行高度为 0,但保留轨道结构 */
}
.plus {
grid-area: plus;
width: 1.2em;
height: 1.2em;
margin: 0.5em;
background:
linear-gradient(#fff 0 0),
linear-gradient(#fff 0 0),
#0051a5;
background-position: center;
background-size: 60% 2px, 2px 60%;
background-repeat: no-repeat;
transition: transform 0.3s ease;
border-radius: 50%;
}
.tile-label {
grid-area: label;
font-size: 1em;
text-transform: uppercase;
font-weight: 600;
color: white;
padding: 0.7em 1em 0.5em;
align-self: end;
margin-bottom: 0.2em;
}
.tile-accent {
color: #FFC72C;
}
.hidden-text {
grid-area: extratext;
font-size: 0.8em;
color: #333;
background-color: #fff;
padding: 0.7em 1em;
margin: 0.2em;
line-height: 1.5;
overflow: hidden;
/* 配合 max-height 实现过渡 */
max-height: 0;
opacity: 0;
transition:
max-height 0.35s ease-out,
opacity 0.25s ease-out 0.05s;
}
.rectangle.expanded .hidden-text {
max-height: 200px; /* 设定安全上限,防止超长内容截断 */
opacity: 1;
}
/* 可选:添加淡入动画增强体验 */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.rectangle.expanded .hidden-text {
animation: fadeInUp 0.35s ease-out forwards;
}
</style><div class="tile-container">
<div class="rectangle">
<div class="plus"></div>
<div class="tile-label">
Sample <span class="tile-accent">Text</span>
</div>
<div class="hidden-text">
<ul style="margin: 0; padding-left: 1.2em;">
<li>Item 1 — 详细说明内容</li>
<li>Item 2 — 支持多行文本与列表项</li>
<li>Item 3 — 响应式排版,适配不同字体缩放</li>
</ul>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const tile = document.querySelector('.rectangle');
const plus = tile.querySelector('.plus');
tile.addEventListener('click', () => {
tile.classList.toggle('expanded');
plus.style.transform = tile.classList.contains('expanded')
? 'rotate(45deg)'
: 'rotate(0)';
});
// ✅ 无障碍增强:支持键盘操作(Enter/Space)
tile.setAttribute('role', 'button');
tile.setAttribute('tabindex', '0');
tile.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
tile.click();
}
});
});
</script>
? 关键要点解析: