- 即时通讯
- 桌面应用
【免费下载链接】community-edition
Free and Open Source messaging and emailing app that combines common web applications into one.
本篇技术指南以 Sencha Ext JS 无障碍支持包ext-aria的 sass 目录说明 为骨架,结合本仓库(community-edition / Rambox,一个基于 Ext JS 的开源消息聚合应用)中 ext-aria 与 ext-theme-aria 两个包的源码,系统讲解 Ext JS 主题系统中 SASS 文件的组织约定(etc/src/var三目录职责)、变量与样式规则的层级关系,以及如何为应用构建符合 ARIA / Section 508 要求的无障碍主题。读完本文,你将掌握 ext-aria 包样式目录的定位与用途、每个实际 SCSS 文件的底层作用,并能在自己的项目中通过sencha generate theme+requires声明或build.properties注入等方式复现一套具备高对比度与键盘焦点指示的 ARIA 主题。
一、ext-aria 包是什么
从 package.json 可以看到,ext-aria是 Sencha 出品的type: "code"代码包,官方描述为:
summary:Ext JS Accessibility SupportdetailedDescription:Core support for Accessibility, ARIA and Section 508 for Ext JS
也就是说,它是 Ext JS 面向无障碍访问(Accessibility)、ARIA(Accessible Rich Internet Applications)与 Section 508 标准的核心支持包,版本为 5.0.0。它的实现分两条线:
- JS 线:位于 overrides 目录,通过
Ext.define(..., { override: '...' })的方式覆写大量 Ext JS 组件类(Button、表单字段、Grid、Window、Menu 等),为其注入role、aria-label、aria-labelledby等属性以及键盘导航逻辑,并在包被引用时自动被 require 加载。 - SASS 线:即 sass 目录,为本篇主题,提供配套的样式变量与规则,保证上述 ARIA 行为在视觉上有明确的呈现(高对比、焦点环等)。
二、ext-aria/sass 三层目录结构(原文档核心内容)
ext-aria/sass/Readme.md 的全文指出:本目录包含多种类型的 SASS 文件,按如下子目录组织:
ext-aria/sass/etc ext-aria/sass/src ext-aria/sass/var这套etc/src/var划分并非 ext-aria 独有,而是Sencha Ext JS 主题与包的标准 SASS 约定,本项目根目录的 app.json 中"sass": { "namespace": "Rambox" }的配置注释也印证了这一点:*.scss文件会按类名映射到sass/src与sass/var对应路径。三个目录的分工如下。
1.var/—— 变量声明目录
var/Readme.md 说明:该目录存放按组件类命名的变量声明文件("variable declaration files named by their component class")。例如:
var/Component.scss—— 全局组件变量var/form/FieldSet.scss—— FieldSet 组件变量var/grid/header/Container.scss—— 网格表头容器变量var/panel/Tool.scss—— 面板工具(Tool)变量
这些文件只声明 SCSS 变量(通常带!default默认值标记),不产出直接的 CSS 规则,是主题可定制性的入口。
2.src/—— 组件层级样式源目录
src/Readme.md 说明:该目录存放模仿组件类层级结构的 SASS 源文件("SASS sources that mimic the component-class hierarchy"),构建时根据构建实际用到的类被收集进 CSS 产物("gathered in to a build of the CSS based on classes that are used by the build")。也就是说:
- 文件路径即类名映射:
src/form/Labelable.scss对应Ext.form.Labelable,src/grid/header/Container.scss对应Ext.grid.header.Container; - 只有应用真正使用到的组件类,其对应 SCSS 才会进入最终构建,避免冗余样式。
3.etc/—— 杂项 / 需显式引入的样式目录
etc/Readme.md 说明:该目录存放杂项 SASS 文件,与src/不同,这些文件需要被显式使用("Unlikeext-aria/sass/etc, these files need to be used explicitly",结合上下文推断,此处应为与自动收集的src/相对比)。当前 etc/all.scss 为空占位文件;对照 ext-theme-aria/sass/etc/all.scss,etc目录也常用于放置像ext-all-access.scss这类整包入口样式,需在构建配置中显式指定。
附:构建配置config.rb
三个子目录之上,config.rb 是 Compass 风格的 SASS 编译配置:
cur_dir = File.dirname(__FILE__) output_style = :nested其中output_style = :nested指定编译输出采用嵌套(nested)格式的 CSS,便于开发阶段阅读;实际生产构建由 Sencha Cmd 接管并压缩。该文件与 ext-theme-base/sass/config.rb 内容一致,属于包级 SASS 的标准配置。
三、var/实际变量:独立构建默认值与主题级变量体系
ext-aria 作为独立代码包构建时,由于不依赖具体主题,其var/中的变量都提供了独立构建兜底默认值,注释均标明"when ext-aria is built standalone":
- var/Component.scss:
$base-color: #000 !default;—— 独立构建时基色默认为黑; - var/grid/header/Container.scss:
$grid-cell-selected-background-color: #000 !default;并派生出$grid-header-selected-cell-background-color: $grid-cell-selected-background-color !default;—— 网格单元格/表头选中背景; - var/panel/Tool.scss:
$tool-focus-background-color: transparent !default;—— 工具按钮聚焦背景默认为透明; - var/form/FieldSet.scss:
$fieldset-collapse-tool-margin: 2px 3px 0 0 !default;—— FieldSet 折叠工具外边距。
这些!default声明意味着:当 ext-aria 被并入真实主题(如 ext-theme-aria)构建时,主题侧定义的同名变量会覆盖这些兜底值。这正是"代码包只提供默认、主题负责视觉决策"的分层设计——对比 ext-theme-aria/sass/var/panel/Tool.scss 中$tool-focus-background-color: $orange !default;即可看到覆盖关系。
四、src/实际规则:面向屏幕阅读器的关键样式
ext-aria 的src/规则是 ARIA 无障碍在视觉层的直接体现,每个文件都对应一个明确的无障碍问题。
1. 表单错误消息:屏幕外定位而非隐藏
src/form/Labelable.scss:
/* override css for field error messages; * instead of display:none which makes * them unreadable to screen readers, * position them off screen */ .#{$prefix}form-invalid-icon ul { display: block; position: absolute; left: -10000px; top: -10000px; }注释明确说明了设计动机:display: none会让屏幕阅读器完全读不到错误消息,因此改为display: block并将元素绝对定位到屏幕外(left/top: -10000px)。这样既有视觉上的"不可见",又能保证辅助技术可以朗读到校验错误内容。其中$prefix变量来自同目录 src/Component.scss 的声明:
// When ext-aria package is built standalone, $prefix is not defined $prefix: 'x-' !default;即独立构建时 CSS 类前缀兜底为x-(与 Ext JS 默认Ext.baseCSSPrefix一致),保证.#{$prefix}form-invalid-icon能正确编译为.x-form-invalid-icon。
2. 网格表头选中单元格
src/grid/header/Container.scss:
.#{$prefix}grid-header-ct .#{$prefix}grid-cell-selected { background-color: $grid-header-selected-cell-background-color; }为键盘导航模式下选中的表头单元格提供高亮背景(颜色变量由var/定义,主题可覆盖)。
3. 面板 / 窗口工具按钮的焦点指示
src/panel/Panel.scss 与 src/window/Window.scss 内容一致:
.#{$prefix}panel-header .#{$prefix}tool.#{$prefix}focus .#{$prefix}tool-img { background-color: $tool-focus-background-color; } .#{$prefix}window-header .#{$prefix}tool.#{$prefix}focus .#{$prefix}tool-img { background-color: $tool-focus-background-color; }当工具按钮获得键盘焦点(.x-focus类)时,为其图标提供背景色,构成"焦点环"式视觉反馈。这与此前所述 FocusManager 的职责之一"Provide a visual cue for focused components"(见 overrides/FocusManager.js 的类注释)严格对应。
五、把 ARIA 做到极致:ext-theme-aria 的高对比度变量体系
仅靠 ext-aria 包本身,视觉层面只有上述少量兜底规则。完整的无障碍体验由基于 ext-theme-neptune 的高对比度主题 ext-theme-aria提供。其 package.json 声明:
{ "name": "ext-theme-aria", "type": "theme", "requires": ["ext-aria"], "extend": "ext-theme-neptune", "summary": "ARIA Theme", "detailedDescription": "A high-contrast accessibility theme based on Neptune" }主题通过"requires": ["ext-aria"]自动拉取 JS 覆盖,通过"extend": "ext-theme-neptune"继承 Neptune 视觉底座。其 sass/var/Component.scss 定义了高对比配色核心:
$body-background-color: #000 !default; $base-color: #3f4757 !default; $base-highlight-color: mix(#fff, $base-color, 15%) !default; $base-light-color: mix(#fff, $base-color, 65%) !default; $base-dark-color: mix(#000, $base-color, 14%) !default; $orange: #ed9200 !default; $focus-color: $orange !default; $color: #fff !default; $font-size: 15px !default; $css-shadow-background-color: #000000 !default; $include-shadow-images: false !default;要点:
$orange: #ed9200是全局焦点色锚点,被大量组件变量引用(见下文);- 文本主色
$color: #fff配黑色系背景,构成高对比度(WCAG 意义上的明暗对比); $font-size: 15px放大基准字号,提升可读性;$include-shadow-images: false关闭阴影贴图,简化渲染并利于对比度。
各组件变量围绕$orange/$base-color展开(节选自 ext-theme-aria/sass/var):
| 文件 | 关键变量 | 无障碍意图 |
|---|---|---|
| button/Button.scss | $button-default-base-color: #2a3142、$button-default-base-color-over: $orange、$button-default-border-color-focus: $orange、$button-default-color: #fff | 悬停/聚焦以橙色凸显,白字高对比 |
| form/field/Base.scss | $form-field-border-width: 2px、$form-field-focus-border-color: #ff9c33、$form-field-invalid-border-color: #C30 | 2px 粗边框、聚焦橙边框、无效红色标识 |
| grid/header/Container.scss | $grid-header-selected-cell-background-color: $orange | 键盘选中的表头单元格高亮 |
| panel/Tool.scss | $tool-focus-background-color: $orange、$tool-include-hover-icons: true、$tool-opacity: 1 | 工具图标全不透明,聚焦橙底 |
| menu/Menu.scss | $menu-item-active-background-color: $orange、$menu-text-color: #fff | 菜单项激活态橙色高亮 |
| tab/Bar.scss | $tabbar-strip-background-color: $orange | 标签条强调色 |
| window/Window.scss | $window-body-background-color: #1f2833、$window-body-color: #fff | 窗口体深底白字 |
| panel/Panel.scss | $panel-header-background-color: #3a4155、$panel-body-color: #fff | 面板深底白字 |
| slider/Multi.scss | 滑块拇指 16×16px | 增大滑块抓取区域 |
可见,ext-aria 的src/规则消费了$tool-focus-background-color等变量,而 ext-theme-aria 的var/用$orange赋予其高对比取值——三层目录由此贯通成完整的主题管线:var/定值 →src/产规则 → 构建输出 CSS。
六、让 ARIA 生效的两条构建路径
ext-aria 包的 Readme 给出了官方推荐的启用方式,与本仓库 Ext JS 应用的 app.json 构建配置("theme": "rambox-default-theme"+"requires": ["ext-locale"]+sencha app build流程)完全同构,可直接套用。
路径 A:直接使用 ext-theme-aria(推荐)
- 在应用
app.json的"theme"字段设置为ext-theme-aria(或基于它扩展自己的主题); - 因主题
"requires": ["ext-aria"],JS 覆盖与 SASS 资源都会被自动纳入; - 运行
sencha app build产出含 ARIA 特性的 JavaScript 与 CSS 文件。
路径 B:自定义主题 + requires 引入 ext-aria
若不想整体切换主题(例如需要保留原有品牌色与图片资源),官方给出了"在不动颜色和图片的前提下引入 ARIA 能力"的方案:
sencha generate theme custom-aria-theme编辑新主题的package.json:
{ "name": "custom-aria-theme", ... "requires": ["ext-aria"], "extend": "ext-theme-neptune" }然后运行sencha app build。此时 ext-aria 的 JS 覆盖(含 FocusManager 键盘导航)与 SASS 默认样式(含$tool-focus-background-color等兜底变量)都会并入构建。
路径 C:不用 Sencha Cmd,手动注入 JS 覆盖
如果不使用 Sencha Cmd 构建应用,可在自定义主题的.sencha/package/build.properties中追加:
build.operations=include \ -tag=package-ext-aria随后在主题目录执行sencha package build,产出包含 ext-aria JavaScript 类的主题构建产物。需要留意 Readme 的提示:此种方式下 JS 来自 ext-aria 包,但 CSS 仍是你自己的主题,因此可能需要手动调整 SASS 变量,为按钮等聚焦组件提供足够对比度(正是前文$tool-focus-background-color、$button-*-focus-*一类变量的用武之地)。
FocusManager:键盘导航的总开关
无论走哪条路径,ARIA 的键盘导航都依赖 FocusManager(定义于 overrides/FocusManager.js,被 overrides/Component.jsrequires)。其职责按 WAI-ARIA 实践包括:组件焦点管理、键盘导航、为聚焦组件提供视觉提示(焦点环/框)。初始化规则:
- 应用使用了 Viewport(如 overrides/container/Viewport.js 所覆写的
Ext.container.Viewport):FocusManager 在Ext.onReady时自动启用; - 未使用 Viewport:需手动调用
Ext.FocusManager.enable();。
启用后,F6键会在多个打开的窗口间循环切换焦点(见toggleWindow逻辑),表单字段获得焦点时通过aria-labelledby关联 label,网格通过role="gridcell"、aria-selected、aria-activedescendant等属性通告选中状态(见 overrides/view/Table.js),Window 自动注入 move / resize 工具按钮并绑定方向键移动/缩放(见 overrides/window/Window.js)。这些 JS 行为与src/中$tool-focus-background-color、$grid-header-selected-cell-background-color等视觉规则一一配对,共同构成"读得出、看得到、键盘可操作"的完整无障碍闭环。
七、组件级 ARIA 配置速查(与样式配套使用)
在应用代码中,可直接通过组件配置项声明无障碍语义(定义于 overrides/Component.js):
| 配置项 | 说明 |
|---|---|
ariaRole | 组件的 ARIA role,如region、presentation;未设置时不输出其他 ARIA 属性 |
ariaLabel | 直接指定aria-label(与ariaLabelledBy互斥) |
ariaLabelledBy | 通过选择器引用标签元素,输出aria-labelledby;#id可跨组件引用 |
ariaDescribedBy | 通过选择器引用描述元素,输出aria-describedby |
ariaAttributes | 附加 ARIA 属性对象,用于状态无法推导的场景,如aria-live、aria-flowto |
组件隐藏、禁用、显示、启用时,onHide/onShow/onDisable/onEnable会自动同步aria-hidden、aria-disabled;表单字段另通过 overrides/form/field/Base.js 维护aria-readonly、aria-invalid(markInvalid/clearInvalid时联动),其错误提示默认msgTarget: 'side',配合src/form/Labelable.scss的屏幕外定位规则确保朗读器可感知校验失败。调试时留意 overrides/button/Button.js 的 WAI-ARIA 冲突检测:带菜单的按钮若同时配置 toggle/href/handler,会输出Ext.log.error提示,避免"菜单按钮"与切换、链接、点击处理行为冲突。
八、总结
ext-aria/sass的三目录结构是 Ext JS 无障碍主题的最小骨架,却也是整套体系的枢纽:
var/定义可被主题覆盖的变量默认值(独立构建兜底);src/按组件类产出面向屏幕阅读器与焦点可见性的 CSS 规则;etc/存放需显式引入的杂项/整包样式;config.rb以nested输出风格驱动 Compass 编译。
当它与ext-theme-aria的高对比度变量体系($orange焦点色、2px 粗边框、深底白字)以及 JS 层的 ARIA 覆盖(FocusManager、role/aria-*属性注入)组合后,便形成从"变量定制 → 规则生成 → 构建集成 → 运行时无障碍"的完整链路。要在自己的 Ext JS 应用中复现,只需记住两条核心命令:sencha generate theme custom-aria-theme创建主题并在package.json中声明"requires": ["ext-aria"],随后sencha app build或(非 Cmd 场景)在build.properties中追加-tag=package-ext-aria后执行sencha package build。
- 即时通讯
- 桌面应用
【免费下载链接】community-edition
Free and Open Source messaging and emailing app that combines common web applications into one.
相关推荐
ext-theme-classic 主题 Sass 目录结构详解:从 etc、src、var 理解 Ext JS 主题定制体系
ext theme classic 主题 Sass 目录结构详解:从 etc、src、var 理解 Ext JS 主题定制体系 导读 在 community e
即时通讯桌面应用Ext JS 主题 Sass 目录结构实战指南:以 community-edition 中 ext-theme-crisp-touch 的 etc/src/var 三层组织为例
Ext JS 主题 Sass 目录结构实战指南:以 community edition 中 ext theme crisp touch 的 etc/src/va
即时通讯桌面应用深入解读 Ext JS 主题体系中的 sass/var 变量声明目录:从命名约定到编译机制
深入解读 Ext JS 主题体系中的 sass/var 变量声明目录:从命名约定到编译机制 导读 ext theme base/sass/var 是 Ext J
即时通讯桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考