图片画廊与灯箱系统
目的
图片画廊与灯箱系统为在网页上展示媒体集合提供了一种严谨的设计方法论。它构建了如何在静态网格(画廊)中呈现一组图片或视频,以及如何将这些资源过渡到高冲击力、无干扰的全屏覆盖层(灯箱)。该系统确保视觉作品集、电商产品缩放和案例研究保持高度响应性、深度无障碍合规(WCAG AA),并通过触摸滑动手势、键盘控制和焦点陷阱支持物理设备。
使用场景
- 展示摄影、艺术作品、建筑设计或案例研究的作品集网站。
- 需要大规模详细图片探索的电商产品详情页(PDP)。
- 文章包含交互式图片画廊的富媒体内容网站。
- 展示活动摄影或客户评价日志的活动页面和营销落地页。
- 以高分辨率室内外导览展示房产的房地产网站。
何时不使用
- 单一背景或内联媒体: 对于独立的、非分组的背景图像或简单的内联文章图解,这些不需要缩放或轮播式交互。
- 数据密集型仪表盘视图: 当主要任务是排序或分析结构化数据点(例如表格或图表)时,全屏覆盖会中断工作区。应改用
data-table-ui-system。 - 复杂文档或 PDF: 当用户需要阅读多页文本文档时;灯箱针对视觉媒体进行了优化,不适合阅读密集型资源。
- 独立上下文模态框: 当对话框包含表单输入、设置或丰富的交互式应用程序,而非结构化媒体时。应改用
overlay-and-dialog-system或settings-interface-system。
输入
- 媒体库存: 高分辨率源资源及相应的低分辨率或压缩缩略图变体。
- 上下文元数据: 标题、描述、版权信息、标题和必要的无障碍替代文本(
alt文本)。 - 响应式间距规则: 基于站点已建立的
responsive-grid-system和fluid-spacing-system的目标网格间距、外边距和布局列规则。 - 交互式对比色板: 满足 WCAG 4.5:1 最小对比度的控件覆盖层、关闭按钮和分页点的无障碍文本和图标颜色规范。
输出
- 画廊网格规范: 定义的列布局、图片宽高比、悬停状态和焦点保留规则。
- 灯箱结构蓝图: 全屏覆盖层的结构,详述控件(上一张、下一张、关闭)、标题位置和缩略图条布局。
- 手势与键盘规范: 完整的交互矩阵,映射键盘事件、点击/触摸区域和拖拽/滑动行为。
- 无障碍地标图: 逻辑角色(
dialog、group)、标签(aria-label)、焦点捕获规则和实时状态声明。
工作流程
1. 构建画廊网格基础
从结构化的主页面画廊开始,平衡浏览与屏幕空间:
- 宽高比标准化: 使用统一的宽高比(例如 1:1 正方形或 4:3 标准)对画廊缩略图进行分组,以建立有序的节奏。使用 CSS 的
aspect-ratio属性防止布局偏移。 - 间隙与间距: 使用
fluid-spacing-system的 token(通常是--space-s或--space-m)作为网格间距。 - 悬停/聚焦提示: 应用
interactive-state-system约定。当用户悬停或聚焦某个缩略图时,触发微妙的视觉变化(例如缩放、柔和覆盖层对比、自定义搜索/缩放光标),以提示该项目可点击。 - 语义化 HTML: 使用列表包装器(
<ul>/<li>)构建画廊,缩略图标记为button元素(如果需要进行索引或深层链接,则使用链接),以确保键盘可达性。
2. 设计全屏灯箱背景
灯箱背景必须将观看者与页面其余部分分离:
- 遮罩层: 覆盖一个实色或半透明背景(例如
#0a0a0a搭配 95% 不透明度或带有背景模糊的暗色遮罩),以消除周边干扰。 - 宽高比保持: 将活动图像定位在视口的绝对中心。确保容器使用
max-width: 90vw和max-height: 80vh动态缩放,以适应任何视口,同时不裁剪或裁切来源的宽高比。 - 加载状态: 构建一个居中的视觉指示器(旋转器、加载骨架或进度环),该指示器需支持 ARIA(
aria-busy="true"),确保用户知道正在下载高分辨率资源。
3. 建立导航控件和标题覆盖层
定位和设计覆盖元素,以优化桌面和移动设备上的人体工学:
- 关闭目标: 将关闭按钮放置在右上角。它必须具有清晰的视觉边界,满足最小触摸目标尺寸 48x48px(或根据 WCAG 为 44x44px),并保持清晰的键盘聚焦环。
- 上一张和下一张箭头: 将导航箭头垂直居中放置在左右边距上。在移动设备上,隐藏这些箭头或将其略微内嵌,以将焦点完全集中在触摸滑动操作上。
- 标题与索引指示器: 在容器底部放置语义化的标题和索引(例如“图片 3 / 12”)。使用
aria-live容器在索引更新时通知屏幕阅读器变更事件。 - 缩略图条: 在主图像下方,显示一行可滚动的缩略图。使用高对比度的粗边框和独特的
:focus轮廓高亮显示活动项。
4. 连接键盘与手势机制
灯箱必须同样优雅地处理桌面外设和移动手势交互:
- 键盘映射: 确保立即支持按键控制:
Escape关闭灯箱,ArrowRight/ArrowDown触发“下一张”,ArrowLeft/ArrowUp触发“上一张”。 - 焦点捕获: 当灯箱打开时,将键盘焦点限制在其中。用户不能 Tab 回到背景页面。第一个聚焦的元素应该是主对话框容器或关闭按钮。
- 焦点恢复: 当灯箱关闭时,立即将焦点恢复到触发它的特定缩略图按钮。
- 滑动导航: 支持流畅的触摸屏左滑和右滑手势。
- 滑动关闭: 允许垂直(向上或向下)拖拽或滑动以快速关闭灯箱,复制原生移动操作系统模式。
5. 最终确定无障碍与文档大纲
应用高级 ARIA 声明以保证符合 WCAG AA 标准的屏幕阅读器体验:
- 角色与标签: 使用
role="dialog"、aria-modal="true"标记灯箱包装器,并使用引用标题/说明的aria-label或aria-labelledby对其进行标记。 - 背景遮挡: 当灯箱激活时,对主页面包装器(
<main>或#app-root)应用aria-hidden="true",以保持屏幕阅读器扫描范围仅限于覆盖层内。 - 实时更新: 确保图像标题/说明的更改通过将其放置在或引用到
aria-live="polite"区域内来进行声明。
决策规则
- 分辨率拆分: 画廊网格中的缩略图必须经过高度压缩并适当调整大小(例如最大宽度 600px)。灯箱必须加载主高分辨率变体,但仅按需加载(延迟加载下一张和上一张幻灯片)以节省移动带宽。
- 键盘 vs 触摸优先级: 在移动视口(宽度 < 768px)上,优先为图像提供屏幕空间。隐藏桌面 UI 控件(上一张/下一张箭头),以支持触摸滑动手势,但始终保留一个高度可见的“关闭”按钮。
- 无限循环 vs 硬停止:
- 使用无限循环(轮播在最后一项后循环回到 1):当展示创意作品集、客户评价或产品,且希望进行流畅扫描时。
- 使用硬停止(最后一项上禁用下一张箭头):用于分步式顺序教程、指令集或时间顺序时间线,其中方向性至关重要。
- 标题 vs 覆盖层空间: 如果图像有较长的描述,不要将其覆盖在图像本身上。将其放置在图像边界下方专用的底部栏中,允许文本在超出垂直屏幕空间时独立滚动。
- 桌面光标提示: 动态更改桌面光标:
- 悬停画廊缩略图:
cursor: zoom-in - 活动灯箱图像(可缩放):
cursor: zoom-in(点击展开至全分辨率,光标变为cursor: zoom-out用于平移)。 - 悬停灯箱背景:
cursor: pointer(点击关闭覆盖层)。
- 悬停画廊缩略图:
约束条件
- 响应式: 图像在灯箱内绝不能变形或失去其宽高比。容器必须使用灵活的视口单位(
vw/vh)和 CSS 的object-fit: contain,以严格保持在所有设备方向上的屏幕边界内。 - 对比度: 关闭、导航和缩略图交互控件的对比度必须至少达到 4.5:1(与背景和图像覆盖层相比)。
- 焦点状态: 每个活动导航元素都必须有一个可见的
:focus-visible环。焦点指示器绝不能因边界框或相邻元素而被裁剪。 - 触摸目标: 移动设备上的点击目标必须满足 WCAG 2.2 SC 2.5.8(至少 24x24px,但对于关闭和导航等主要操作,强烈建议使用 44x44px)。
常见失败模式
- “无限 Tab 陷阱”: 从打开的灯箱中 Tab 到背景页面,导致屏幕阅读器读取不可见内容并打破键盘导航。
- “图像越界”: 过高的纵向图像超出移动视口的顶部或底部,使导航箭头或关闭按钮完全无法触及。
- 焦点丢失: 静态画廊中的缩略图因绝对居中裁剪而裁切了核心主体(例如人物的头部)。使用
object-position或自定义响应式裁剪来解决。 - “无法退出”: 忘记连接
Escape键,导致仅使用键盘的用户被困在模态覆盖层中,没有直观的方式关闭它。 - 打开时布局偏移: 灯箱打开时浏览器滚动条消失,导致整个背景页面布局抖动或侧移。通过添加匹配的间距或滚动锁定内边距来解决。
- 无焦点恢复: 关闭灯箱会将焦点重置到站点地图顶部或 body,强制键盘用户再次 Tab 遍历整个标题导航才能回到之前的位置。
验证标准
- 画廊缩略图使用标准化宽高比,并具有清晰的悬停/聚焦指示器。
- 活动灯箱图像保持其宽高比,并完美适应视口限制(
max-width: 90vw和max-height: 80vh)。 - 关闭按钮和箭头与背景层之间的对比度至少达到 4.5:1。
- 键盘导航已激活:
Escape关闭,ArrowRight前进,ArrowLeft后退。 - 灯箱打开时焦点被捕获在内部,关闭时完美恢复到触发它的画廊元素。
- 触摸手势已启用:左/右滑动导航,上/下滑动在移动视口上关闭。
- 当灯箱模态框激活时,主页面包装器标记为
aria-hidden="true"。 - 加载高分辨率资源时,加载状态旋转器可见并标记为
aria-busy="true"。