;
将 .hidden-text 作为 .rectangle 的直接子元素(而非同级兄弟),确保 DOM 层级支持高度联动;
使用 CSS Grid 定义结构自治(非 Flex 或绝对定位),通过 grid-template-rows: 1fr auto 明确主标题与隐藏区的空间归属;
用 max-height + overflow: hidden 替代 height 过渡,实现物理高度的可控动画(比 height: auto 更稳定,比 display 切换更平滑)。
以下是生产就绪的推荐实现(已兼容 Chrome/Firefox/Safari):
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<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;
font-size: 25px;
max-width: 600px;
margin: 0 auto;
}
.rectangle {
background-color: #0051a5;
border-radius: 1em;
cursor: pointer;
display: grid;
/* 主标题占剩余空间,隐藏区初始高度为0 */
grid-template-rows: 1fr 0fr;
grid-template-columns: 1fr max-content;
grid-template-areas: "label plus" "extratext extratext";
overflow: hidden; /* 关键:防止内容溢出破坏动画 */
transition: grid-template-rows 0.35s cubic-bezier(0.33, 1, 0.68, 1);
}
.rectangle.expanded {
grid-template-rows: 1fr auto; /* 展开时第二行自动适配内容高度 */
}
.plus {
grid-area: plus;
background:
linear-gradient(#fff 0 0),
linear-gradient(#fff 0 0),
#0051a5;
background-position: center;
background-size: 60% 2.5px, 2.5px 60%;
background-repeat: no-repeat;
width: 1.2em;
height: 1.2em;
margin: 0.75em;
transition: transform 0.35s ease;
}
.rectangle.expanded .plus {
transform: rotate(45deg);
}
.tile-label {
grid-area: label;
font-size: 1em;
text-transform: uppercase;
font-weight: 700;
color: white;
padding: 1em;
align-self: center;
}
.tile-accent {
color: #FFC72C;
}
.hidden-text {
grid-area: extratext;
font-size: 0.8em;
color: #333;
background-color: #fff;
padding: 0.75em 1em;
margin: 0.5em;
border-radius: 0.5em;
line-height: 1.5;
/* 防止展开瞬间内容闪烁 */
opacity: 0;
transform: translateY(-10px);
transition:
opacity 0.25s ease,
transform 0.25s ease;
}
.rectangle.expanded .hidden-text {
opacity: 1;
transform: translateY(0);
}
</style>
</head>
<body>
<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.5em;">
<li>Item 1: 详细说明内容可自由扩展</li>
<li>Item 2: 支持任意 HTML 内容(段落、列表、链接等)</li>
<li>Item 3: 响应式字体与间距随容器缩放</li>
</ul>
</div>
</div>
</div>
<script>
document.querySelector('.rectangle').addEventListener('click', function() {
this.classList.toggle('expanded');
});
</script>
</body>
</html>? 关键要点与注意事项:
-
避免绝对定位陷阱:.hidden-text 必须是 .rectangle 的子元素,且不可设 position: absolute,否则将脱离 Grid 布局流,导致高度无法驱动容器伸缩;
-
max-height 不是唯一解:本方案采用 grid-template-rows 动态切换(0fr → auto),比 max-height: 0 → max-height: 500px 更语义化、更易维护,且无需预估最大高度;
-
动画曲线优化:使用 cubic-bezier(0.33, 1, 0.68, 1)(类似 ease-out 的弹性收尾),让展开更具自然感;
-
无障碍增强建议:可为 .rectangle 添加 role="button" 和 aria-expanded="false",并在 JS 中同步更新 aria-expanded 属性,提升屏幕阅读器兼容性;
-
移动端适配:配合 @media (max-width: 600px) 可进一步缩小字体、调整内边距,确保小屏体验一致。
该方案摒弃了“伪弹性”绝对定位,拥抱现代 CSS 布局能力,在保持代码简洁的同时,交付专业级的交互体验与长期可维护性。