Files
outlookEmailPlus/static/css/layout.css
T
胡绍康andClaude Opus 4.6 0ab50db85f feat: 实现可调整布局系统
- 新增布局管理器支持拖拽调整面板宽度
- 新增状态管理器实现布局持久化
- 重构前端页面结构优化四栏式布局
- 新增 Jest 测试框架和完整测试用例
- 完善项目文档(PRD/FD/TDD/TODO/LOG)
- 清理 Python 缓存文件并更新 .gitignore

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 14:49:36 +08:00

231 lines
6.8 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 可调整布局系统(基础样式)
*
* 说明:
* - 使用 CSS Grid + CSS 变量控制三列侧边栏宽度(分组/账号/邮件列表)与详情区域自适应。
* - resizer / 折叠相关样式在此文件集中管理,避免污染现有 main.css。
* - 该文件将被在 main.css 之后引入,以覆盖旧的 flex 固定宽度布局。
*/
:root {
/* ===================== 面板默认宽度 ===================== */
--group-panel-width: 200px;
--account-panel-width: 260px;
--email-list-panel-width: 380px;
/* ===================== 折叠相关宽度 ===================== */
--panel-collapsed-width: 0px;
--panel-collapsed-indicator-width: 48px;
/* ===================== 宽度限制(用于 Grid 与 JS 计算) ===================== */
--group-panel-min-width: 150px;
--group-panel-max-width: 400px;
--account-panel-min-width: 180px;
--account-panel-max-width: 500px;
--email-list-panel-min-width: 280px;
--email-list-panel-max-width: 600px;
--email-detail-panel-min-width: 400px;
/* ===================== Grid 生效宽度(折叠时可被置为 0,保存宽度不丢失) ===================== */
--group-panel-layout-width: var(--group-panel-width);
--account-panel-layout-width: var(--account-panel-width);
--email-list-panel-layout-width: var(--email-list-panel-width);
--group-panel-layout-min-width: var(--group-panel-min-width);
--account-panel-layout-min-width: var(--account-panel-min-width);
--email-list-panel-layout-min-width: var(--email-list-panel-min-width);
/* ===================== 交互与动画 ===================== */
--resizer-width: 4px;
--panel-transition-duration: 200ms;
--panel-transition-timing-function: ease;
--collapsed-indicator-width: var(--panel-collapsed-indicator-width);
}
/* ===================== Grid 布局(覆盖 main.css) ===================== */
.main-container {
display: grid;
grid-template-columns:
minmax(var(--group-panel-layout-min-width), var(--group-panel-layout-width))
minmax(var(--account-panel-layout-min-width), var(--account-panel-layout-width))
minmax(var(--email-list-panel-layout-min-width), var(--email-list-panel-layout-width))
minmax(var(--email-detail-panel-min-width), 1fr);
grid-template-rows: 1fr;
/* 防止折叠时面板内容溢出把 body 撑出滚动条(会导致“指示器高度异常/过长”观感) */
overflow: hidden;
transition: grid-template-columns var(--panel-transition-duration)
var(--panel-transition-timing-function);
will-change: grid-template-columns;
}
/* ===================== 状态恢复时禁用动画(避免闪烁) ===================== */
.layout-no-transition .main-container {
transition: none !important;
}
.layout-no-transition .resizable-panel > :not(.collapsed-indicator) {
transition: none !important;
}
/* 让 Grid 子项允许收缩,避免内容撑破布局 */
.main-container > * {
min-width: 0;
min-height: 0;
}
/* ===================== Resizable 面板基础样式 ===================== */
.resizable-panel {
position: relative;
/* 默认层级:保持低于 modal 等全局浮层 */
z-index: 1;
}
/* ===================== Resizer 样式 ===================== */
.resizer {
position: absolute;
top: 0;
right: 0;
width: var(--resizer-width);
height: 100%;
cursor: col-resize;
z-index: 20;
touch-action: none;
}
.resizer:hover,
.resizer:focus,
.resizer.active {
background-color: rgba(26, 26, 26, 0.1);
box-shadow: inset 0 0 0 2px #1a1a1a;
}
.resizer:focus-visible {
outline: 2px solid #1a1a1a;
outline-offset: 2px;
}
/* ===================== 折叠状态(基础) ===================== */
.resizable-panel {
will-change: opacity;
}
/* 折叠时仅隐藏面板内容,指示器仍需可见 */
.resizable-panel > :not(.collapsed-indicator) {
transition: opacity var(--panel-transition-duration)
var(--panel-transition-timing-function);
}
.resizable-panel.collapsed > :not(.collapsed-indicator) {
opacity: 0;
pointer-events: none;
/*
* 关键修复:
* - 折叠时列宽为 0,若仅用 opacity 隐藏,面板内文本/控件会在 0 宽下强制换行,
* 仍参与布局计算并可能把页面撑出滚动条,导致指示器“看起来过长”。
* - 直接 display:none 让隐藏内容不参与布局与滚动高度计算。
*/
display: none;
}
.resizable-panel.collapsed {
overflow: visible;
/*
* 关键修复:
* - 折叠后 Grid 列宽会变为 0,指示器需要“溢出”到右侧可见区域。
* - 由于 Grid 子项的绘制顺序受 DOM 影响(后面的面板会盖住前面的面板),
* 当多面板折叠时,指示器可能被邮件详情面板覆盖导致“消失且无法展开”。
* - 提升折叠面板的 z-index,并强制其宽度为 0,确保指示器可见且不挡住右侧交互。
*/
z-index: 200;
width: 0 !important;
min-width: 0 !important;
max-width: 0 !important;
}
.resizable-panel.collapsed .resizer {
display: none;
pointer-events: none;
}
/* ===================== 折叠指示器(48px,竖排文字) ===================== */
.collapsed-indicator {
display: none;
position: absolute;
top: 0;
left: 0;
width: var(--collapsed-indicator-width);
height: 100%;
background-color: #fafafa;
border: 1px solid #e5e5e5;
box-sizing: border-box;
cursor: pointer;
z-index: 30;
align-items: center;
justify-content: center;
transform: translateX(var(--collapsed-indicator-offset, 0px));
}
.resizable-panel.collapsed .collapsed-indicator {
display: flex;
}
.collapsed-indicator:hover,
.collapsed-indicator:focus {
background-color: #f0f0f0;
}
.collapsed-indicator:focus-visible {
outline: 2px solid #1a1a1a;
outline-offset: 2px;
}
.collapsed-indicator .indicator-text {
writing-mode: vertical-rl;
font-size: 14px;
color: #666;
user-select: none;
}
/* 折叠按钮:先复用 main.css 的 .panel-action-btn 基础样式,仅补充可访问性样式 */
.collapse-btn:focus-visible {
outline: 2px solid #1a1a1a;
outline-offset: 2px;
}
/* ===================== 拖动中全局反馈 ===================== */
.layout-resizing,
.layout-resizing * {
cursor: col-resize !important;
}
.layout-resizing {
user-select: none;
-webkit-user-select: none;
}
/* ===================== F3:恢复默认布局(确认对话框细节) ===================== */
#resetLayoutModal .text-muted {
color: #999;
font-size: 12px;
margin-top: 6px;
}
/* ===================== F3:恢复默认布局(按钮) ===================== */
.reset-layout-btn {
width: 32px;
height: 32px;
padding: 0;
display: inline-flex;
align-items: center;
justify-content: center;
}
.reset-layout-btn svg {
width: 16px;
height: 16px;
}
/* 重置动画:临时将布局过渡时长提升到 300ms(FD F3.4) */
.layout-resetting {
--panel-transition-duration: 300ms;
}