Radio
Radio buttons are a common way to allow users to make a single selection from a list of options. Only one radio button within a group can be selected at a time, so each available choice is its own item / label.
Design guidance
When and how to use this
Use grouped radio buttons if the user is required to choose one and only one item from a list of 2 or more options.
When to consider something else
For cases where the user should be able to return to a “nothing is selected” state, or if the user can skip choosing an option altogether, consider using a Select instead.
Figma
Drag in a Radio Field Group from the Compositions section in the Form Controls
v2 library in your Assets pane. We provide default and error states as well as a
required attribute for the field. A Radio Field component is nested within,
which then nests an atomic Radio Button component inside. To set the checked
attribute and state on a button within the Radio Field Group, select the
nested Radio Button and use Figma's component property pane to make changes.
React
We are transitioning to a new Radio design. The large size is the new
standard and should be used for all new implementations.
The small, medium, and default sizes are deprecated and will be
removed in a future version. Please migrate existing usages to size="large".
See the Figma designs for the updated patterns.
Radio composes
Chakra's Radio. We offer
size variants that align with those in TextInput. We also offer a RadioGroup
that wraps a set of Radio components, controls their values, and distributes
some common props such as size and isDisabled, and a TileRadio that offers
a radio button wrapped in a tile-like element and offers more text styling
options.
<Stack direction="column" spacing="400">
<Radio size="large">I'm idle</Radio>
<Radio size="large" isChecked>
I'm checked
</Radio>
<Radio size="large" isDisabled>
I'm disabled
</Radio>
</Stack>| Prop | Description |
|---|---|
size | Sets the size of the Radio and its associated label. |
isChecked | if true, the Radio will be checked. You'll need to pass onChange to update its value (since it is now controlled). |
isDisabled | if true, the Radio will be disabled. |
isInvalid | if true, the Radio will be invalid and its aria-invalid will be set to true. |
Radio Group
Use a RadioGroup for most common radio button set use cases. It uses the same
props as the basic Radio and applies these across each radio button in the
group. In addition you can use the defaultValue prop on this component to set
one of the radio buttons as checked by default.
<RadioGroup size="large" defaultValue="1">
<Stack direction="column" spacing="400">
<Radio value="1">Radio 1</Radio>
<Radio value="2">Radio 2</Radio>
<Radio value="3">Radio 3</Radio>
</Stack>
</RadioGroup>Size
:::note Deprecation Notice
The small and medium sizes are deprecated. Use size="large" for all new
implementations.
:::
Radio should use size="large" for all new implementations. The size set on
RadioGroup will be distributed to child Radio components.
<RadioGroup size="large" defaultValue="1">
<Stack direction="column" spacing="400">
<Radio value="1">Large Radio 1</Radio>
<Radio value="2">Large Radio 2</Radio>
<Radio value="3">Large Radio 3</Radio>
</Stack>
</RadioGroup>Filled Variant
Radio is available in an alternative style as the filled variant. However,
the default variant should usually be used in forms, especially alongside
checkboxes.
<DesignSystemProvider attach fontsHost="/typography/">
<Stack spacing="400">
<RadioGroup size="small" defaultValue="1">
<HStack justifyContent="space-around">
<Radio variant="filled" value="1">
Small 1
</Radio>
<Radio variant="filled" value="2">
Small 2
</Radio>
<Radio variant="filled" value="3">
Small 3
</Radio>
</HStack>
</RadioGroup>
<Divider />
<RadioGroup size="medium" defaultValue="1">
<HStack justifyContent="space-around">
<Radio variant="filled" value="1">
Medium 1
</Radio>
<Radio variant="filled" value="2">
Medium 2
</Radio>
<Radio variant="filled" value="3">
Medium 3
</Radio>
</HStack>
</RadioGroup>
<Divider />
<RadioGroup size="large" defaultValue="1">
<HStack justifyContent="space-around">
<Radio variant="filled" value="1">
Large 1
</Radio>
<Radio variant="filled" value="2">
Large 2
</Radio>
<Radio variant="filled" value="3">
Large 3
</Radio>
</HStack>
</RadioGroup>
</Stack>
</DesignSystemProvider>Color mode
By default, Radio uses the color mode context to determine whether to
display a control for dark or light backgrounds. Pass colorMode to manually
force a color mode.
<RadioGroup
display="flex"
defaultValue="light"
flexDirection="column"
gap="300"
alignItems="start"
>
<HStack background="neutral.0" borderRadius="300" spacing="500" padding="500">
<Radio colorMode="light" value="light">
Light
</Radio>
<Radio colorMode="light" variant="filled" value="light-filled">
Light
</Radio>
</HStack>
<HStack background="neutral.875" borderRadius="300" spacing="500" padding="500">
<Radio colorMode="dark" value="dark">
Dark
</Radio>
<Radio colorMode="dark" variant="filled" value="dark-filled">
Dark
</Radio>
</SimpleGrid>
</RadioGroup>Radio control
The animated check control that's used in Radio is available as an independent component, for use in custom radios.
Indicator only
Note
Make sure to implement accessibility correctly when using only the indicator
from RadioControl. If the custom component rendering RadioControl is a
checkbox, use useRadio.
() => {
const [isChecked, setIsChecked] = useState(true);
return (
<HStack>
<RadioControl size="large" variant="filled" isChecked={isChecked} />
<Toggle isChecked={isChecked} onChange={() => setIsChecked(!isChecked)}>
<Code>isChecked</Code>
</Toggle>
</HStack>
);
};With input and useRadio
When using RadioControl directly in a custom radio component that uses
useRadio for its state, pass inputProps and radioProps and
RadioControl will automatically render the hidden <input type="radio"> in
the correct state.
() => {
const { getInputProps, getRadioProps, getLabelProps, getRootProps, state } =
useRadio({ value: 'custom-radio' });
return (
<HStack as="label" {...getRootProps()}>
{/* if your radio has a separate label, you'll want to pass it `getLabelProps` */}
<RadioControl
inputProps={getInputProps()}
radioProps={getRadioProps()}
size="large"
variant="filled"
/>
<Code>{JSON.stringify(state)}</Code>
</HStack>
);
};Tile Radio
TileRadio allows for both a label as in the standard Radio component,
but also offers a description prop to set secondary text in the tile. It also
offers an isSubtle prop to remove the border of the element in its default
state. You can wrap a set of TileRadio components in a RadioGroup just like
the standard Radio.
<Stack direction="column" spacing="400">
<TileRadio description="Description goes here">I'm idle</TileRadio>
<TileRadio description="Description goes here" isChecked>
I'm checked
</TileRadio>
<TileRadio description="Description goes here" isInvalid>
I'm invalid
</TileRadio>
<TileRadio description="Description goes here" isDisabled>
I'm disabled
</TileRadio>
</Stack>Bootstrap
Bootstrap provides styles for input type=”radio” and accompanying label
elements, using the .form-check-input and .form-check-label classes wrapped
in a div with the class .form-check. Wrap groups of these in a fieldset
and use the .form-label class on its legend to achieve the same effect as
the React RadioGroup.
<fieldset>
<legend class="form-label mb-6">Radio field</legend>
<div class="form-check">
<input
class="form-check-input"
type="radio"
name="exampleRadios"
id="exampleRadios1"
value="option1"
checked
/>
<label class="form-check-label" for="exampleRadios1"> First radio </label>
</div>
<div class="form-check">
<input
class="form-check-input"
type="radio"
name="exampleRadios"
id="exampleRadios2"
value="option2"
/>
<label class="form-check-label" for="exampleRadios2"> Second radio </label>
</div>
<div class="form-check">
<input
class="form-check-input"
type="radio"
name="exampleRadios"
id="exampleRadios3"
value="option3"
/>
<label class="form-check-label" for="exampleRadios3">
Third radio is third
</label>
</div>
</fieldset>| Class | Description |
|---|---|
.form-check-input and .form-check-label | Invokes Bootstrap theme styles for checkboxes and accompanying labels. |
.form-check | Required class on a wrapper div around the checkbox and label elements. |
.form-label | Invokes Bootstrap theme styles for the legend on a fieldset that wraps a .form-check div and its children, as shown above. |
React Native
Font Scaling
This component supports dynamic font scaling for accessibility, capped at 1.35x. See Typography — Font Scaling for details.