element-plus/element-plus
Reviewed against Rams quality heuristics: accessibility, color, typography, spacing, components, motion, UX, and craft.
30 files reviewed·August 1, 2026
More findings
Verdict
Alert.vue nails the announcement semantics but ships two broken dismiss controls: one div can't be tabbed to, one icon button has no name. Screen reader and keyboard users literally cannot close the alert, a basic failure sitting right next to otherwise careful styling.
Files Rams reviewed
packages/components/affix/src/affix.vue
packages/components/alert/src/alert.vue
packages/components/anchor/src/anchor-link.vue
packages/components/anchor/src/anchor.vue
packages/components/autocomplete/src/autocomplete.vue
packages/components/avatar/src/avatar-group.tsx
packages/components/avatar/src/avatar.vue
packages/components/backtop/src/backtop.vue
packages/components/badge/src/badge.vue
packages/components/breadcrumb/src/breadcrumb-item.vue
packages/components/button/src/button.vue
packages/components/calendar/src/calendar.vue
packages/components/calendar/src/date-table.vue
packages/components/calendar/src/select-controller.vue
packages/components/card/src/card.vue
packages/components/carousel/src/carousel-item.vue
packages/components/carousel/src/carousel.vue
packages/components/cascader-panel/src/index.vue
packages/components/cascader-panel/src/menu.vue
packages/components/cascader-panel/src/node-content.tsx
packages/components/cascader-panel/src/node.vue
packages/components/checkbox/src/checkbox-button.vue
packages/components/checkbox/src/checkbox-group.vue
packages/components/checkbox/src/checkbox.vue
packages/components/col/src/col.vue
packages/components/collapse-transition/src/collapse-transition.vue
packages/components/collapse/src/collapse-item.vue
packages/components/color-picker-panel/src/color-picker-panel.vue
packages/components/color-picker-panel/src/components/alpha-slider.vue
packages/components/color-picker-panel/src/components/hue-slider.vue
Accessibility
packages/components/alert/src/alert.vue:29
Custom close button div is unreachable by keyboard users
In alert.vue, when `closeText` is set the dismiss control renders as a plain `<div class="[ns.e('close-btn'), ns.is('customed')]" @click="close">{{ closeText }}</div>` instead of a `<button>`. It has no tabindex, no keydown handler, and no ARIA role, so it never enters the tab order and Enter/Space do nothing even when focus lands on it another way.
Why it matters
Keyboard-only and switch-device users cannot dismiss the alert at all when a custom close label is used, locking them out of a control that mouse users can operate freely.
Fix
Render the custom close control as a native `<button type="button">` so it inherits focusability and keyboard activation for free.
<div
v-if="closeText"
:class="[ns.e('close-btn'), ns.is('customed')]"
@click="close"
>
{{ closeText }}
</div><button
v-if="closeText"
type="button"
:class="[ns.e('close-btn'), ns.is('customed')]"
@click="close"
>
{{ closeText }}
</button>packages/components/alert/src/alert.vue:37
Icon-only close button has no accessible name for screen readers
The default dismiss control, `<el-icon v-else :class="ns.e('close-btn')" @click="close"><Close /></el-icon>`, renders only a Close icon with no `aria-label`, `aria-labelledby`, or visible text. This is the path taken whenever `closeText` is not supplied, which is the common case.
Why it matters
Screen reader users hear nothing actionable when they reach this control, so they can't identify or trigger the dismiss action, effectively locking them out of closing the alert.
Fix
Add an aria-label (e.g. localized 'close') to the icon-only close control so assistive tech announces its purpose.
<el-icon v-else :class="ns.e('close-btn')" @click="close">
<Close />
</el-icon><el-icon
v-else
:class="ns.e('close-btn')"
aria-label="close"
role="button"
@click="close"
>
<Close />
</el-icon>Typography
Color
Spacing
Components
Motion
UX
Craft
Working well
- Active/is-customed state styling is driven through ns.is('customed') rather than inline styles, keeping the close-button variant inside the component's design-system namespace instead of ad hoc CSS.
- The root alert div carries role="alert", giving it an implicit live region so title and description text is announced automatically when the alert mounts, no extra ARIA wiring needed.
Scored August 1, 2026 with Rams Engine v0.0.3 · Engine changelog
First scored July 29, 2026: 59/100. This rescore on v0.0.3: 59/100.
This page is an automated design review of element-plus/element-plus’s UI code: 30 files read against 291 versioned rules covering accessibility, color, typography, spacing, components, UX, motion, and craft. The score is out of 100; confirmed criticals cap it — one at 59, two at 49, three or more at 39.
Score your own repo.
Free on public repos, no account. The same engine that scored this page reads your UI code and mints a score page like this one.
Public repos only. The full engine reviews the UI code and mints a public score page — we email you the link too. Already-scored repos open instantly.