Tab键导航选中div元素时按Enter键无法触发onClick事件
问题根因
键盘按下Enter触发点击事件的必要前提是当前焦点落在绑定了交互事件的元素上。
代码中tabIndex被错误绑定在了外层无任何事件响应的Card容器上,Tab导航时焦点会直接停留在这个外层容器上,而实际绑定了onClick逻辑、内置了键盘Enter/空格触发响应的CardActionArea组件拿不到焦点,自然无法触发选中逻辑。
MUI的CardActionArea组件本身已经完成了基础无障碍适配,默认自带可聚焦能力、键盘交互响应,手动给外层Card加tabIndex的操作反而打断了默认的正确焦点链路。
修复方案
- 移除两个外层
Card组件上写死的tabIndex属性,恢复CardActionArea默认的聚焦逻辑 - 给容器和选项补充单选场景对应的ARIA语义属性,方便读屏设备正确识别组件类型和选中状态
- 若需要自定义Tab切换顺序,将
tabIndex属性直接绑定在CardActionArea上即可,不要挂载到无交互能力的外层容器
修复后完整代码
import { Stack, Typography, Card, CardContent, CardActionArea, } from "@mui/material"; import { useState } from "react"; import { AddOutlined, SyncOutlined } from "@mui/icons-material"; export default function CreateAssignment() { const [type, setType] = useState<"create" | "assign">("create"); return ( <Stack direction={"row"} alignItems={"center"} justifyContent={"center"} spacing={4} marginY={6} role="radiogroup" > <Card sx={(theme) => ({ width: 200, border: type === "create" ? "5px solid " + theme.palette.secondary.main : "5px solid white", borderRadius: 6, })} > <CardActionArea onClick={() => setType("create")} role="radio" aria-checked={type === "create"} > <CardContent> <AddOutlined style={{ fontSize: 48 }} /> <Typography gutterBottom variant="body1" fontSize={20}> Create A New Device To Assign </Typography> </CardContent> </CardActionArea> </Card> <Card sx={(theme) => ({ width: 200, border: type === "assign" ? "5px solid " + theme.palette.secondary.main : "5px solid white", borderRadius: 6, })} > <CardActionArea onClick={() => setType("assign")} role="radio" aria-checked={type === "assign"} > <CardContent> <div> <SyncOutlined style={{ fontSize: 48 }} /> </div> <Typography gutterBottom variant="body1" fontSize={20}> Reassign Existing Device </Typography> </CardContent> </CardActionArea> </Card> </Stack> ); }
修复完成后,Tab键可正常在两个卡片选项间切换聚焦,按下Enter或空格键都能正常触发选中状态切换,同时满足读屏设备的识别要求,符合无障碍访问规范。
内容的提问来源于stack exchange,提问作者Abir Taheer
相关产品推荐
相关产品推荐

