news 2026/10/16 19:10:41

Ext JS ext-aria 无障碍包 SASS 体系解析:etc/src/var 目录约定与高对比度主题定制指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ext JS ext-aria 无障碍包 SASS 体系解析:etc/src/var 目录约定与高对比度主题定制指南
  • 即时通讯
  • 桌面应用

【免费下载链接】community-edition

Free and Open Source messaging and emailing app that combines common web applications into one.

项目地址:https://gitcode.com/gh_mirrors/co/community-edition
点击查看免费下载

本篇技术指南以 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。它的实现分两条线:

  1. JS 线:位于 overrides 目录,通过Ext.define(..., { override: '...' })的方式覆写大量 Ext JS 组件类(Button、表单字段、Grid、Window、Menu 等),为其注入role、aria-label、aria-labelledby等属性以及键盘导航逻辑,并在包被引用时自动被 require 加载。
  2. 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: #C302px 粗边框、聚焦橙边框、无效红色标识
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(推荐)

  1. 在应用app.json的"theme"字段设置为ext-theme-aria(或基于它扩展自己的主题);
  2. 因主题"requires": ["ext-aria"],JS 覆盖与 SASS 资源都会被自动纳入;
  3. 运行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.

项目地址:https://gitcode.com/gh_mirrors/co/community-edition
点击查看免费下载
上一篇:终极无损视频剪辑指南:如何用LosslessCut实现秒级剪辑,告别转码等待
下一篇:LosslessCut完整指南:如何实现秒级无损视频剪辑的终极教程

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 19:10:40

asc-devkit Ascend C 算子接入 PyTorch 图模式:TorchAir 转换 GE 节点样例实战

人工智能深度学习算子库CANNAscend 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。 项目地址&…

作者头像 李华
网站建设 2026/10/16 11:16:46

牙齿病变分割数据集labelme格式解析与转换避坑指南

简介:面向牙齿分割与病变检测的Labelme格式图像数据集,包含2616张jpg原图及对应json标注文件,覆盖Tooth、Caries、Cavity、Crack、calculus、inflamation六个类别,适合医学图像处理与口腔AI方向的开发者用于模型训练和算法验证。数…

作者头像 李华
网站建设 2026/10/16 19:10:41

OpenCV直方图均衡化与比较:从原理到实战的完整指南

直方图这东西,刚接触图像处理的时候我觉得它特别"反直觉"——一张图好不好看、亮不亮,跟一堆统计数字有什么关系?后来做图像检索和预处理的项目多了才发现,直方图均衡化和直方图比较这两个看似基础的操作,恰…

作者头像 李华
网站建设 2026/10/16 16:33:03

工厂设备联网有几种方式?RS485、以太网、4G网关方案对比

工厂设备联网,分为有线联网、无线联网两大类;工程上也常按接入层通信协议划分,老设备一般靠网关协议转换采集。一、有线(稳定、实时优先,车间固定设备首选) 工业以太网(现在主流) 协议:EtherCAT、PROFINET、EtherNet/IP、Modbus T…

作者头像 李华
网站建设 2026/10/16 19:10:44

使命召唤19闪退?回滚显卡驱动526.86完整排查指南

画面卡了一帧,紧接着显示器黑了一下,切回桌面,游戏已经没了。这是我在《使命召唤19》里第一次遇到闪退时的真实体验,后来我才知道,这张地图、这个点位,几乎是所有闪退玩家的共同记忆:战绩还没打…

作者头像 李华
网站建设 2026/10/16 19:10:45

WinForms状态切换实战:TextBox显示隐藏与按钮文字联动

1. 题目拆解与设计思路1.1 需求清单逐条拆解这道题看起来简单,但它的价值不在功能多少,而在它把一个很典型的“界面元素状态同步”问题压缩到了最小可运行的范围。先把需求掰开揉碎,看看一共涉及几件事:创建窗体,上面放…

作者头像 李华