fix: Modal 弹窗高度约束,防止内容溢出视窗
- 添加 max-height 限制,确保弹窗始终在视窗内 - header/footer 固定不压缩,body 内容可滚动 - 兼容 iOS Safari 的 dvh 单位
This commit is contained in:
49
openspec/specs/modal-height-constraint/spec.md
Normal file
49
openspec/specs/modal-height-constraint/spec.md
Normal file
@@ -0,0 +1,49 @@
|
||||
## Purpose
|
||||
|
||||
定义 Modal 弹窗的高度约束机制,确保弹窗在各种视窗尺寸下完整显示,并提供良好的内容滚动体验。
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Modal 最大高度限制
|
||||
|
||||
Modal 弹窗 SHALL 设置最大高度,确保弹窗始终在视窗内完整显示。
|
||||
|
||||
#### Scenario: 视窗高度充足
|
||||
- **WHEN** 浏览器视窗高度大于弹窗内容高度
|
||||
- **THEN** 弹窗高度自适应内容,不显示滚动条
|
||||
|
||||
#### Scenario: 视窗高度不足
|
||||
- **WHEN** 浏览器视窗高度小于弹窗内容高度
|
||||
- **THEN** 弹窗最大高度为 `calc(100dvh - 48px)`(兼容旧浏览器使用 `calc(100vh - 48px)` fallback)
|
||||
- **THEN** 弹窗上下各预留 24px 边距
|
||||
|
||||
### Requirement: Modal 标题栏固定可见
|
||||
|
||||
Modal 标题栏(`.modal-header`)SHALL 始终可见,不被内容挤压或遮挡。
|
||||
|
||||
#### Scenario: 内容超出滚动
|
||||
- **WHEN** Modal body 内容超出高度限制
|
||||
- **THEN** 标题栏固定在弹窗顶部,高度不变
|
||||
- **THEN** 标题栏不参与滚动
|
||||
|
||||
### Requirement: Modal 底部栏固定可见
|
||||
|
||||
Modal 底部栏(`.modal-footer`,如存在)SHALL 始终可见,不被内容挤压或遮挡。
|
||||
|
||||
#### Scenario: 内容超出滚动且有 footer
|
||||
- **WHEN** Modal body 内容超出高度限制且存在 footer
|
||||
- **THEN** footer 固定在弹窗底部,高度不变
|
||||
- **THEN** footer 不参与滚动
|
||||
|
||||
### Requirement: Modal body 内容可滚动
|
||||
|
||||
Modal body(`.modal-body`)SHALL 在内容超出时支持滚动。
|
||||
|
||||
#### Scenario: 内容超出时滚动
|
||||
- **WHEN** Modal body 内容高度超过可用空间
|
||||
- **THEN** body 显示纵向滚动条
|
||||
- **THEN** 用户可滚动查看全部内容
|
||||
|
||||
#### Scenario: 内容未超出时不滚动
|
||||
- **WHEN** Modal body 内容高度未超过可用空间
|
||||
- **THEN** body 不显示滚动条
|
||||
@@ -25,6 +25,10 @@
|
||||
box-shadow: 0 8px 32px rgba(15, 23, 42, 0.16);
|
||||
width: 420px;
|
||||
max-width: 90vw;
|
||||
max-height: calc(100vh - 48px);
|
||||
max-height: calc(100dvh - 48px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
animation: modal-in 0.2s ease-out;
|
||||
}
|
||||
|
||||
@@ -47,6 +51,7 @@
|
||||
justify-content: space-between;
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid var(--color-border-2);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
@@ -79,6 +84,9 @@
|
||||
font-size: $font-size-base;
|
||||
color: var(--color-text-2);
|
||||
line-height: 1.6;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
// Element: footer
|
||||
@@ -89,4 +97,5 @@
|
||||
gap: 8px;
|
||||
padding: 12px 20px;
|
||||
border-top: 1px solid var(--color-border-2);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user