Skip to content
+

Focus visible

Apply an outline or inset keyboard focus across Material UI components.

Starting from v9.4, Material UI provides built-in support for visual keyboard focus indicator through CSS. The demos on this page opt out of the ripple to show only the focus visible indicator.

Usage

Set focusVisible: true on the theme to render a default focus indicator on every ButtonBase-derived component when it receives keyboard focus:

import { createTheme } from '@mui/material/styles';

const theme = createTheme({ focusVisible: true });

The default focus indicator is a two-pixel solid outline with palette.primary.main color, offset by two pixels:

Press Tab to move keyboard focus — the ring appears on focus.

Press Enter to start editing

Inner focus indicator

Some components, for example Tab, render the focus indicator from the inside to avoid overflow-clipped container or overlapping with other elements.

Press Tab, then use the arrow keys — the ring insets so the Tabs scroller cannot clip it.

Press Enter to start editing

To see the full list of components that show inner focus indicator, check out the full demo below.

Colored surface container

Components that support keyboard focus visible will show another layer of box-shadow indicator when they render within AppBar, Alert, and SnackbarContent. This comes by default when the focus visible feature is enabled, unless a custom box-shadow is provided.

Press Tab — a background-colored box-shadow renders behind the outline so the ring stays visible on the colored surface.

Title

Customization

The focusVisible can be customized by passing a CSS object to merge with the default styles.

Changing the outline color

To customize the outline, for example changing the color, pass an object with specified outline color to the focusVisible node to merge with the default outline styles:

// Recolor only; width and offset stay at the curated 2px.
createTheme({ focusVisible: { outlineColor: '#9c27b0' } });
Press Enter to start editing

Use box-shadow as a second layer

A boxShadow can be additive on top of the outline. This is useful for a two-color ring (WCAG technique C40) that stays visible on any background. Material UI insets the box-shadow automatically on the inner focus indicator components, so a plain single-layer value works everywhere:

createTheme({
  focusVisible: {
    /* inner indicator */
    outlineColor: '#F9F9F9',
    outlineOffset: 0,
    /* outer indicator */
    boxShadow: '0 0 0 4px #193146',
  },
});

Press Tab — the light outline or the dark box-shadow keeps contrast on either background.

Replace outline with box-shadow

To replace the outline entirely with a box-shadow indicator, hide the outline with outlineColor: 'transparent':

createTheme({
  focusVisible: {
    outlineColor: 'transparent',
    boxShadow: '0 0 0 3px #1976d2',
  },
});

Full focus visible demo

The complete set of components that render the focus indicator when focusVisible is enabled. Use the keyboard (Tab and arrow keys) to move focus and reveal the ring.

outer-ringThe ring renders fully outside the component.

Button

IconButton

ButtonGroup

ToggleButton

Fab

Chip

Clickable
Deletable

Checkbox

Radio

Switch

Pagination

ButtonBase

AccordionSummary

Details

TableSortLabel

NameSize
file.txt12 KB

Slider

Link

Breadcrumbs

Rating

Stepper


inner-ringInside a scrollable or overflow-clipped container — the ring is inset (outlineOffset -2) so it cannot be clipped.

Tab

MenuItem

ListItemButton

    List item button 1
    List item button 2

BottomNavigation

CardActionArea

Select

Autocomplete

Caveats

Checkbox and Radio custom icons must be SVG

The Checkbox and Radio attach the focus indicator to the first <svg> element inside the component. When customizing them with the icon and checkedIcon props, the custom icon must render an <svg> element — icons rendered as other elements, such as font icons or <img>, do not receive the focus indicator.

The indicator hugs whatever box the svg renders at, so smaller replacement icons get a proportionally tighter ring with no extra tuning.

Press Tab — the ring hugs the 16px svg icons.

Settings

Component focus-visible styles are replaced by the theme

Some components indicate keyboard focus with a translucent background or overlay by default — the Chip, MenuItem, ListItemButton, AccordionSummary, PaginationItem, CardActionArea, Autocomplete options, and the Slider thumb. When focusVisible is enabled, these component focus-visible styles are removed so that the theme's indicator is the only one, consistent across all components — hover, selected, and active styles are unchanged.

Recomposing a theme with a palette change

Spreading a created theme into createTheme() while changing the palette keeps the indicator color resolved from the original palette. Re-pass focusVisible in the same call so the color re-derives from the new palette:

const base = createTheme({ focusVisible: true });

// ✅ re-pass focusVisible to re-derive the color from the new palette
createTheme({
  ...base,
  palette: { primary: { main: '#2e7d32' } },
  focusVisible: true,
});