keep-a-changelog 窄屏语言/版本选择器重设计:从无标签弹层到带标签的全宽 Sheet 实现解析
文档【免费下载链接】keep-a-changelogIf you build software, keep a changelog.项目地址https://gitcode.com/gh_mirrors/ke/keep-a-changelog点击查看免费下载本篇技术指南围绕 keep-a-changelog 项目 v2 设计中针对手机窄屏narrow-screen重构语言/版本选择器的完整方案展开它对应 PR #729 的界面重设计把原先“点地球图标弹出的紧凑 popover 两个裸下拉”替换为“齿轮按钮向下展开的全宽带标签 Sheet”。读完本文你将掌握该方案在 共享 Partial 源码、窄屏断点样式 与 选择器交互脚本 三处的具体实现如何组织字段标签、如何用(n/a)标记缺失翻译、如何把主题切换并入同一展开区以及整个交互在可访问性上的取舍。一、问题背景旧的窄屏选择器为什么失败在 v2 之前的窄屏设计中语言选择器由页面右上角的一颗地球图标globe触发点击后弹出的是一个紧凑的 popover里面是两个没有任何可见标签的原生版本下拉。正如原文档所记录的痛点“点击地球一个语言暗示却落到了一堆没有解释的版本号上”——用户看到的只是 1.1、1.0、0.3 这样光秃秃的版本选项无从得知哪个是语言、哪个是版本也没有主题切换入口。从可访问性角度看旧实现的问题更为根本两个select缺乏与字段含义绑定的可见标签屏幕阅读器与普通用户都无法快速理解“这个下拉框是什么”。这正是 PR #729 决定整体重做该交互的动机。二、新设计核心齿轮按钮 向下展开的全宽带标签 Sheet新方案彻底改变了交互范式收起态只有一个齿轮按钮窄屏下版本、语言、主题三个设置全部收敛到头部右侧的一枚齿轮gear按钮后面头部保持单行不再有悬浮弹层。展开态是“头部向下延伸”的全宽 Sheet点击齿轮后头部向下展开一块覆盖整个视口宽度的面板里面每个字段都有自己的可见标签标签之上是通栏full-width的select。与旧版“悬浮于内容之上的 popover”不同新 Sheet 在视觉上被刻意做成“头部的一部分”它锚定在头部本身而不是导航条上使用与头部相同的表面色、延续头部的底部细线hairline并用一道阴影与下方的 hero 区域分离。对应样式见 v2.css 的窄屏媒体查询media (max-width: 48rem) { .locales-toggle { display: inline-flex; } /* 仅窄屏显示齿轮 */ .locale-fields { display: none; } /* 字段默认隐藏 */ .locales[data-open] .locale-fields { display: flex; flex-direction: column; position: absolute; inset-block-start: 100%; inset-inline: 0; z-index: 20; background: var(--surface); border-block-end: 1px solid var(--rule); box-shadow: 0 14px 24px -14px rgba(0, 0, 0, 0.5); } }断点阈值为48rem约 768px样式注释说明插页页面上“品牌标识 文字标 两个下拉 主题切换”最宽需要约 45rem任何更窄的视口都会启用齿轮折叠。展开状态下标签文本从“仅屏幕阅读器可见”的裁剪状态恢复为小号加粗标题两个下拉铺满整行宽度主题按钮也获得更大的触控尺寸2.6rem × 2.2rem见 v2.css#L441-L467。三个字段的标记结构展开区由共享 Partial source/partials/_locale_nav.html.haml 渲染核心标记如下%button.locales-toggle{ type: button, aria-expanded: false, aria-controls: locale-fields, aria-label: Show settings menu, title: Settings } .locale-fields#locale-fields %label.locale-field{ for: version-select } %span.locales-text Version %select.locale-select{ name: version, id: version-select, aria-label: Choose a version } - selectable_versions.reverse_each do |v| - available version_available?(language_code, v) - label available ? display_version(v) : #{display_version(v)} (n/a) %option{ value: #{language_code}/#{v}/, selected: (v current_version), label: label, title: hint, data-available: available.to_s } %label.locale-field{ for: language-select } %span.locales-text Language (#{$languages.count}) %select.locale-select{ name: language, id: language-select, aria-label: Choose a language } - $languages.each do |code, meta| %option{ value: #{code}/#{current_version}/, selected: (code language_code), label: label, title: hint, data-available: available.to_s } - if defined?(theme_switch) theme_switch .locale-field.locale-field-theme %span.locales-text#theme-label Theme .theme-switch{ role: group, aria-labelledby: theme-label } %button.theme-btn{ type: button, data-set-theme: system, aria-pressed: true, ... } %button.theme-btn{ type: button, data-set-theme: light, ... } %button.theme-btn{ type: button, data-set-theme: dark, ... }关键设计点标签双形态Version/Language的标签文本.locales-text在宽屏下是裁剪为 1px 的“仅屏幕阅读器”文本见 v2.css#L298-L307在窄屏展开的 Sheet 中则恢复为可见的字段标题——同一份标记两种布局。主题切换作为第三个字段Partial 接收theme_switch局部变量v2 设计传true于是主题按钮组以rolegrouparia-labelledbytheme-label的方式成为 Sheet 里的第三个字段旧版设计不传该变量按钮组整体省略。选项即路由每个option的value都是语言/版本/形式的路径切换任意一个下拉都只是“导航到该路径”见 all.js#L12-L22var selects document.querySelectorAll(.locales select); Array.prototype.forEach.call(selects, function(select){ select.addEventListener(change, function(event){ var target event.currentTarget.selectedOptions[0].value; window.location.replace(window.location.origin / target); }); });三、(n/a)标记与缺失翻译路由永远不出现 404新设计刻意没有隐藏缺失的翻译组合而是采用全网格可选项 紧凑标记的策略版本下拉始终列出全部版本、语言下拉始终列出全部语言任何“我们还没有的组合”用括号标记(n/a)标注同时该option仍保持可选data-availablefalse选中它会跳转到自动生成的缺失翻译插页而不是 404详细原因放进option的title提示中如 “Version 1.1.0 isnt translated into French yet”样式层对option[data-availablefalse]降饱和处理见 v2.css#L292-L295Firefox、Chromium 会尊重 option 颜色其余浏览器则依赖(n/a)文本兜底。缺失翻译插页由 source/missing.html.haml 实现。其注释说明该页面在 config.rb 中为每个缺失的语言, 版本组合生成代理页并传入language_code与version两个局部变量页面会本地化插页文案、在存在英文版时提供 “Read in English” 入口、在存在最新翻译时提供 “Read latest” 入口并引导用户参与翻译贡献。插页与常规页共享同一个 Partial这正是原文档最后一张截图强调的复用关系常规页面布局 layout.html.haml 与插页 missing.html.haml 都渲染partial partials/locale_nav因此窄屏下的展开 Sheet、齿轮折叠、(n/a)标记行为在两个页面上完全一致无需维护两套 UI。四、展开/收起的交互与可访问性实现Sheet 的开合由 all.js#L24-L54 驱动核心是给.locales设置/移除data-open属性CSS 依据该属性切换字段的显隐var setLocalesOpen function(open){ if (open) { locales.setAttribute(data-open, ); } else { locales.removeAttribute(data-open); } localesToggle.setAttribute(aria-expanded, String(open)); }; localesToggle.addEventListener(click, function(){ setLocalesOpen(!locales.hasAttribute(data-open)); });交互细节与可访问性设计ARIA 状态同步齿轮按钮声明aria-expanded、aria-controlslocale-fields和aria-labelShow settings menu展开时 CSS 还会让齿轮呈现高亮激活态v2.css#L356-L365并让指示箭头旋转 180°明确“可再点击收起”。焦点刻意留在齿轮上脚本注释解释了这一反直觉设计的缘由——如果展开后把焦点移入 Sheet 的selectiOS 会立即弹出系统的 picker wheel劫持用户第一次点击。因此焦点保持在齿轮用户自行决定是否触碰下拉。双重关闭路径按Escape关闭并让焦点回到齿轮点击 Sheet 外部任意区域也会关闭。宽屏下是空操作宽屏48rem时齿轮display:none、字段内联展示事件绑定依然存在但不产生可见影响代码无需按视口分支。五、主题切换与 Sheet 合并的设置项v2 设计把主题切换从独立的明暗按钮组并入同一展开区窄屏下用户只需要面对一个齿轮即可切换全部三项设置。三个按钮分别对应system跟随操作系统、light、dark其状态与持久化逻辑在 all.js#L56-L85var STORAGE_KEY kac-theme; buttons.forEach(function(button){ button.addEventListener(click, function(){ var theme button.getAttribute(data-set-theme); if (theme system) { localStorage.removeItem(STORAGE_KEY); } else { localStorage.setItem(STORAGE_KEY, theme); } if (theme system) { root.removeAttribute(data-theme); } else { root.setAttribute(data-theme, theme); } syncPressed(); }); });配套机制首屏前防闪烁v2 页面在head内联一段脚本在首次绘制前从localStorage读取kac-theme并设置html>赞分享文档【免费下载链接】keep-a-changelogIf you build software, keep a changelog.项目地址https://gitcode.com/gh_mirrors/ke/keep-a-changelog点击查看免费下载相关推荐鸣潮游戏自动化工具深度解析如何用智能辅助解放你的双手鸣潮游戏自动化工具深度解析如何用智能辅助解放你的双手 还在为《鸣潮》中那些重复枯燥的日常任务感到疲惫吗每天花几个小时刷副本、收集资源、做日常不仅消耗宝贵时GUI 自动化计算机视觉RPA人工智能CANN/AMCT示例代码Introduction This project provides calling samples for different scenarios. Afte人工智能大模型模型量化模型压缩模型优化Ascendreact-native-bottom-sheet无障碍标签实现提升屏幕阅读器兼容性react native bottom sheet无障碍标签实现提升屏幕阅读器兼容性 在移动应用开发中无障碍设计Accessibility是确保所有用户前端移动开发UI组件跨平台上一篇如何彻底卸载 Windows Defenderwindows-defender-remover 实战指南下一篇PotPlayer字幕翻译插件指南3分钟装好免费实时中文字幕外语片当晚就能看懂创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Midway 全栈工作区:src/server 与 src/web 的目录约定、引用边界与自定义方案

Midway 全栈工作区:src/server 与 src/web 的目录约定、引用边界与自定义方案

后端微服务云原生 【免费下载链接】midway 🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate w…

2026/10/12 9:20:14 阅读更多 →
ESP32+GY-30光照传感器:I2C通信与低功耗环境光检测实践

ESP32+GY-30光照传感器:I2C通信与低功耗环境光检测实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 9:20:18 阅读更多 →
全固态电池界面电阻直接建模:从“差10个数量级“到“差2个以内“的破局之路

全固态电池界面电阻直接建模:从“差10个数量级“到“差2个以内“的破局之路

全固态电池(ASSB)界面电阻的"算测鸿沟"—理论预测与实验实测相差10个以上数量级—长期困扰领域发展。 2026年7月,上海大学在 Advanced Materials 发表论文,通过梳理~29,000篇文献中的310组界面体系,将配体场…

2026/10/12 9:20:22 阅读更多 →

最新新闻

纯Python实现猜数字游戏:从零到避坑的完整指南

纯Python实现猜数字游戏:从零到避坑的完整指南

猜数字游戏大概是很多人的第一个编程项目。它不像计算器那样枯燥,也不需要复杂的界面,但一套完整流程走下来,变量、输入输出、条件判断、循环、异常处理这些编程入门核心概念全部能练到。我最近又把这个小项目从头写了一遍,用最基…

2026/10/14 6:39:29 阅读更多 →
Vibe Coding工具链选型四步框架:效率提升27%与成本控制24倍

Vibe Coding工具链选型四步框架:效率提升27%与成本控制24倍

1. 效率提升27%背后的真实账本先把结论摆出来:同样一个中等复杂度的业务模块,用对工具链和用错工具链,交付效率差距能拉到27%左右,而综合成本差距可以到24倍。这个数字不是拍脑袋来的,是我在三个不同类型的项目里反复测…

2026/10/14 6:39:29 阅读更多 →
两个模型同价,真正拉开成本的是那个默认值

两个模型同价,真正拉开成本的是那个默认值

📋 目录 一、两个模型,一个价二、纠错一:跑量模型不等于更便宜三、纠错二:贵的是 quality,而且它默认不贵四、逐档成本表,和一个反直觉的发现五、纠错三:分辨率不是按像素收费六、参考图才是隐…

2026/10/14 6:39:29 阅读更多 →
Vibe Coding工具选型与四步实施框架:效率提升27%与成本差24倍背后的工程实践

Vibe Coding工具选型与四步实施框架:效率提升27%与成本差24倍背后的工程实践

1. 效率数字背后的真实账本先把标题里两个数字拆开看。效率提升27%这个量级,放在任何研发团队里都算得上可观,但它不是凭空冒出来的——它通常来自编码环节中重复劳动被压缩、上下文切换次数减少、以及试错周期缩短这三块的叠加。而成本差24倍这个说法&a…

2026/10/14 6:39:29 阅读更多 →
新手入门3D视觉(一)WSL2+Ubuntu22.04+PCL环境配置

新手入门3D视觉(一)WSL2+Ubuntu22.04+PCL环境配置

「零基础转行工业 3D 视觉」系列第一篇。 本文记录我用 WorkBuddy 把第 1 周环境搭起来的完整过程:3 个步骤,手动敲的命令不超过 3 条。 全程用到的 3 个脚本放在文末附件里,可以直接下载复用。开始之前:一条最重要的提醒不要装 V…

2026/10/14 6:39:29 阅读更多 →
深度学习损失函数选型实战:从MSE到Focal Loss的原理与踩坑

深度学习损失函数选型实战:从MSE到Focal Loss的原理与踩坑

损失函数这玩意儿,说起来是深度学习里最基础的组件之一,但恰恰是很多同学在实战里翻车最频繁的地方。我带项目的时候经常看到有人模型结构抄得挺像样,学习率调度也配了一堆,可训练出来的结果就是不对,Loss 曲线跟心电图…

2026/10/14 6:38:29 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →