utilities
focus ring

Focus Ring

Style focus states with accessibility-first focus ring utilities.

Focus rings are essential for accessibility, helping users identify which element currently has keyboard focus. Bamboo provides comprehensive focus ring utilities that work with both regular focus and focus-visible states.

Focus Ring Variants

The focusRing utility applies focus styles using the &:is(:focus, [data-focus]) selector and supports four variants:

// Outside focus ring (default 2px offset)
<button className={css({ focusRing: 'outside' })}>
  Click me
</button>
 
// Inside focus ring (no offset, with border)
<button className={css({ focusRing: 'inside' })}>
  Click me
</button>
 
// Mixed focus ring (semi-transparent with border)
<button className={css({ focusRing: 'mixed' })}>
  Click me
</button>
 
// No focus ring
<button className={css({ focusRing: 'none' })}>
  Click me
</button>

Focus Visible Ring

The focusVisibleRing utility only applies focus styles during keyboard navigation using the &:is(:focus-visible, [data-focus-visible]) selector:

<button className={css({ focusVisibleRing: 'outside' })}>Only shows focus ring on keyboard navigation</button>

Focus Ring vs. Focus Visible Ring

The Focus Visible Ring functions similarly to the Focus Ring, but with a key difference: it only applies focus indicator styles when an element receives keyboard focus.

This ensures that the focus ring is visible only when navigating via keyboard, improving accessibility without affecting mouse interactions.

Customization

You can customize focus ring appearance with additional utilities:

<button
  className={css({
    focusRing: 'outside',
    focusRingColor: 'blue.500',
    focusRingWidth: '3px',
    focusRingStyle: 'dashed',
    focusRingOffset: '4px',
  })}
>
  Custom focus ring
</button>
PropCSS PropertyToken CategoryDescription
focusRingMultipleEnumFocus ring variant
focusVisibleRingMultipleEnumKeyboard-only focus ring
focusRingColor--focus-ring-color-propcolorsFocus ring color
focusRingWidth--focus-ring-widthborderWidthsFocus ring thickness
focusRingStyle--focus-ring-styleborderStylesFocus ring style
focusRingOffset--focus-ring-offsetspacingDistance from element

The four modifiers emit a custom property and nothing else. They do not style anything on their own — a focusRing or focusVisibleRing variant is what reads them. The variables inherit, so setting them on an ancestor themes the rings of its whole subtree.

Global Ring Color

You can set a global focus ring color by defining the CSS custom property:

bamboo.config.ts

import { defineConfig } from '@bamboocss/dev'
 
export default defineConfig({
  global: {
    css: {
      html: {
        '--global-color-focus-ring': '#3b82f6',
      },
    },
  },
})

This color will be used as the default for all focus rings unless overridden by the focusRingColor prop.

Examples

Basic Focus Ring

import { css } from '../styled-system/css'
 
function Button({ children }) {
  return (
    <button
      className={css({
        px: '4',
        py: '2',
        bg: 'blue.500',
        color: 'white',
        rounded: 'md',
        focusRing: 'outside',
      })}
    >
      {children}
    </button>
  )
}

Keyboard-Only Focus Ring

import { css } from '../styled-system/css'
 
function Input({ ...props }) {
  return (
    <input
      className={css({
        px: '3',
        py: '2',
        borderWidth: '1px',
        borderColor: 'gray.300',
        rounded: 'md',
        focusVisibleRing: 'outside',
        focusRingColor: 'blue.500',
      })}
      {...props}
    />
  )
}