制作一张易于使用的揭示卡
关于“按钮内部嵌套按钮的可访问性”的回答
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
最近,我突然很想创作一些有趣的东西。于是我坐下来浏览Dribbble,看看有没有什么我想做的。我偶然发现了一张卡片,滑动卡片后会显示一些操作按钮,点击即可开始操作。
正如你可能已经猜到的,我将在这篇文章中制作一张揭示卡(我不知道它是否有正式名称),但我必须先声明,我并非无障碍设计专家。我自认为对无障碍设计略知一二,但很可能有些地方出错。如果你发现任何错误,或者想询问我为什么这样做,请随时留言,我会尽快回复。
这就是我要制作的东西。它支持鼠标、触摸和键盘操作,我希望屏幕阅读器也能正确读取它的内容。
结构
对于我们稍后将在 HTML 中描述的结构,我们需要一个可以通过 Tab 键切换到的基础层,一个用于选项(在本例中为按钮)的图层,以及一个位于选项上方的信息卡,它会遮挡住选项,直到我们将其滑开。
为了实现无障碍设计,我认为基础部分也应该aria-expanded标明该部分可以展开,按钮aria-hidden上也应该有标签或包装器,以防止屏幕阅读器读取它们。
我觉得类似这样的设计符合我的描述,但目前看起来还不太理想。这就自然而然地引出了造型设计这个话题。
外观
外观方面,我将采用典型的 Material Design 设计风格,这意味着我们会使用 Open Sans 字体,按钮是透明圆形,鼠标悬停时会变成半透明,并且整个元素都会添加阴影效果。这样解释起来是不是很简单?以下是 SCSS 代码:
虽然现在看起来勉强过得去,但还有一些问题需要考虑:卡片是白色的,但它的背景也需要颜色,我们真的应该让潜在用户从几种颜色中进行选择;默认轮廓还可以,但在不同的浏览器中显示效果不同,看起来不太好;最后,除了光标变化之外,没有其他任何迹象表明面板是滑动的。
添加变体
您可能已经注意到,在上面的 SCSS 代码中,我使用了BEM,它只是一种样式指南。在 BEM 中,添加变体时,您需要使用 `<variant>` 标签,--后跟变体名称。所以,让我们添加 `success`、`info` 和 `warn` 这三个颜色变体。
因为我们使用的是SCSS,material-slide所以我们可以像这样轻松地将变体添加到我们的样式中。
.material-slide {
position: relative;
margin: 0.8em 0;
border-radius: 4px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
overflow: hidden;
&--success {
background-color: #1B5E20;
color: #fefefe;
}
&--info {
background-color: #0D47A1;
color: #fefefe;
}
&--warn {
background-color: #B71C1C;
color: #fefefe;
}
}
我已经指定了背景颜色和文本颜色,所以如果有人想在代码中添加新的变体,他们可以遵循这个模式,并在需要时添加对比度更高的颜色。
轮廓优美
这是一个相当有趣的话题,很多无障碍设计纯粹主义者认为应该保留默认轮廓,很长一段时间以来我也同意这种观点,但这些年来我考虑过其他方案,我认为只要让用户知道他们关注的是你的元素,稍微冒险一点也无妨。
我一直以来使用的方法是在 after 中使用 box shadow,不过在这种情况下,我不得不使用 div,它的不透明度为 0,直到元素被选中focus-visible。
我们再次将此添加到material-slide样式中。
// inside .material-slide
& .material-slide__outline {
content: '';
z-index: 2;
border-radius: 4px;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
pointer-events: none;
box-shadow: inset 0 0 0 1px #fefefe, inset 0 0 0 3px #01579B, inset 0 0 0 4px #fefefe;
opacity: 0;
}
// inside .material-slide__options
&:focus-visible {
outline: none;
& ~ .material-slide__outline {
opacity: 1;
}
}
轮廓由三条线组成,两条白线夹着一条蓝线,这样有助于在不同颜色上保持轮廓的可见性。
手势提示
最后说说样式方面,我觉得即使光标变成“抓取”状态,用户也很难一眼看出卡片可以拖动。我仔细考虑了一下,决定当鼠标悬停在卡片上时,卡片应该移动 5 像素,以此来表明卡片可以移动。
为此,我只需添加一个变换,使鼠标悬停在内部即可material-slide__info。
&:hover:not(.material-slide__options--user-control) {
transform: translatex(-5px);
}
你还会注意到,material-slide__options--user-control我们将使用 JS 添加一个类,所以现在让我们继续添加它。
功能
我们已经到了最后一步,添加一些 JavaScript 代码来实现整个功能。这部分主要涉及事件监听器和少量状态管理。我们需要监听键盘事件、鼠标事件和触摸事件。
国家管理
为此,我只需要创建一个包含所有必要变量的对象,然后根据需要更新和检查该对象。
const state = {
isActive: false,
isOpen: false,
isOpenLast: false,
startPos: null,
currentPos: null,
}
事件监听器
我需要监听鼠标按下、移动、离开和抬起事件,以便追踪卡片的拖动距离。我还决定添加双击打开和关闭功能,幸运的是,双击事件已经存在。对于键盘操作,我只需要监听按键抬起事件;对于触摸操作,我需要监听触摸开始、移动、结束和取消事件,这些事件与鼠标操作基本相同,但略有不同(因为支持多点触控)。
搁笔
好了,我们做到了。我们制作了一个很棒的小型滑动面板,可以把按钮隐藏在后面。我们让它既方便键盘用户使用,也方便屏幕阅读器读取。
我在考虑是否可以制作这个系列的另一部分,将其转换为 React 组件并发布到 Git/NPM 上,大家对此有兴趣吗?
感谢您阅读到最后,希望您能从中有所收获。正如我在文章开头所说,欢迎留下任何评论,或者来推特上和我交流。
再次感谢🧠🧙♂️❤️🦄🧠🦄❤️🧠🧙♂️🧠🧙♂️
文章来源:https://dev.to/link2twenty/building-an-accessible-reveal-card-3c56
