Flex

A flexbox container as a component: gap, alignment, direction and wrapping as props, with the gap sizes coming from the theme.

Accessibility

Flex is a layout container and nothing else, so everything on this page is about what the arrangement can do to the content inside it.

Flex adds no semantics

Flex renders exactly one element, a div unless component says otherwise, carrying class names and at most an inline gap and flex. It sets no role, no ARIA attribute and no tabindex, and it has no state to announce. The kit only adds values to gap and changes no markup.
So the accessibility of a Flex is entirely the accessibility of what is inside it plus the element it renders. There is no classNames object either, because there is only one part. A plain Flex cannot fail an audit by itself, but the arrangement it produces can.

Visual order is not DOM order

Flexbox lets a container paint its children in an order the document does not have. A keyboard tab sequence and a screen reader both follow the DOM, so anything that reverses or reorders the painting leaves two different orders on the same row.
  • The CSS order property, reached here through a class or a style on a child, moves the box and not the element. A reader tabbing the row will jump backwards across the screen.
  • row-reverse and column-reverse are not props on this component, but they are one className away and reverse the whole row the same way.
  • wrap="wrap-reverse" is the one that ships as a prop: the second line appears above the first while still coming after it in the document.
  • Fix it in the markup rather than in the layout. Write the children in the order they should be read, and use justify and align, which move nothing out of sequence, to place them.
  • Right to left is the exception. With direction set to rtl on ConfigProvider, the reading order flips with the painting.

component is the route to real semantics

Because the layout is a prop, the element is free to change. component turns a Flex into a landmark or a list with one word, where a class-styled div needs a rewrite.
  • A list of things should be a ul with li children. The count and the position come with it, and no ARIA is needed to get them.
  • A group of page links is a nav, a titled region is a section with a heading. These are the landmarks a screen reader user navigates by.
  • FlexProps extends the HTML attributes, so aria-label, aria-labelledby and role land on that element. Name a landmark when a page has two of the same kind.
  • Prefer the element to the role. component="nav" is stronger than role="navigation" on a div, and it is the same number of characters.

A gap is not a separator

gap is space, and space is invisible to everything that is not looking at the screen. A row whose two halves are separated only by a larger gap reads as one undifferentiated run of content.
  • If the space means "these belong together and those do not", say it in the markup: nest each group in its own Flex, or put a Divider between them.
  • The same goes for a gap standing in for a label. Proximity groups a caption with its value for a sighted reader and for nobody else. The association has to exist in the elements.
  • Do not let gap replace the spacing inside a hit target. Space between two buttons is not padding on either, and a target still needs to be big enough to hit on its own.

Nothing here manages focus

  • Flex adds no tab stop and takes none away. It is not focusable, it does not trap focus, and it does not give its children roving arrow-key movement. Tab order stays the DOM order of whatever you put inside.
  • A group of controls that should behave as one (arrow keys between them, one tab stop for the set) needs a component that builds that: Segmented, Radio.Group, Tabs. A Flex around buttons is a row of separate tab stops, which is often what you want.
  • Watch the focus ring at the edges. A ring is painted outside the element, so a tight gap or an overflow-hidden ancestor can clip it, and a clipped ring is a keyboard user who cannot tell where they are.
  • An empty Flex is hidden. A container rendered ahead of its content is not there at all until a child arrives, so nothing in it can hold or restore focus.