Skip to content
BigBang

Popular

    ↑↓Navigate↵OpenEscClose
    TR

    Patterns

    Disabled and read-only

    The difference between disabled and read-only, and when to use each.

    Disabled and read-only say different things. Disabled says “unavailable right now”; read-only says “you can see this value but not change it”. This pattern keeps the two apart.

    • When an action or field is temporarily unavailable: disabled.
    • When the user may see and copy a value but not change it: read-only.
    • Do not show a control the user can never use; hide it.
    Property Disabled Read-only
    Focusable No Yes
    Submitted with the form No Yes
    Copyable No Yes
    Screen reader Announced as dimmed or unavailable Announced as “read only”
    Contrast requirement Exempt Normal
    When to use A temporarily unavailable action or field A value the user may see but not change

    Tab through the example: the read-only input and the explained button take focus; the disabled input does not. The same data also appears as a view page below.

    Live example, StorybookOpen in Storybook

    Read-only and disabled field

    Disabled action and setting

    Off because no team is added. Add people on the Team page first.

    The same data on a view page

    Project code
    PRJ-1024
    Owner
    Team A
    Records
    12
    import { Button, DescriptionList, Heading, Stack, Switch, TextInput, Tooltip } from '@bigbang/ui';
    import { type Lang, LangProvider } from '../lang';
    const copy = {
    tr: {
    readOnlyTitle: 'Salt okunur ve devre dışı alan',
    readOnly: 'Salt okunur',
    disabled: 'Devre dışı',
    value: 'PRJ-1024',
    actionTitle: 'Devre dışı eylem ve ayar',
    publish: 'Yayımla',
    publishReason: 'Yayımlamak için önce bir başlık ekleyin',
    notify: 'Ekibe bildirim gönder',
    notifyReason: 'Ekip eklenmediği için kapalı. Önce Ekip sayfasından kişi ekleyin.',
    viewTitle: 'Görüntüleme sayfasında aynı veri',
    items: [
    { term: 'Proje kodu', details: 'PRJ-1024' },
    { term: 'Sahibi', details: 'Ekip A' },
    { term: 'Kayıt sayısı', details: '12' },
    ],
    },
    en: {
    readOnlyTitle: 'Read-only and disabled field',
    readOnly: 'Read only',
    disabled: 'Disabled',
    value: 'PRJ-1024',
    actionTitle: 'Disabled action and setting',
    publish: 'Publish',
    publishReason: 'Add a title before you publish',
    notify: 'Notify the team',
    notifyReason: 'Off because no team is added. Add people on the Team page first.',
    viewTitle: 'The same data on a view page',
    items: [
    { term: 'Project code', details: 'PRJ-1024' },
    { term: 'Owner', details: 'Team A' },
    { term: 'Records', details: '12' },
    ],
    },
    };
    /**
    * Read-only keeps the value in the tab order, copyable and submitted; disabled removes it from all three.
    * A disabled action explains why: a focusable Button with a Tooltip, or a Switch with a description.
    */
    export function StateComparison({ lang = 'tr' }: { lang?: Lang }) {
    const t = copy[lang];
    return (
    <LangProvider lang={lang}>
    <div className="w-full max-w-md">
    <Stack gap="2xl">
    <Stack gap="md">
    <Heading level={3} size="sm">
    {t.readOnlyTitle}
    </Heading>
    <TextInput label={t.readOnly} name="code-readonly" readOnly defaultValue={t.value} />
    <TextInput label={t.disabled} name="code-disabled" disabled defaultValue={t.value} />
    </Stack>
    <Stack gap="md">
    <Heading level={3} size="sm">
    {t.actionTitle}
    </Heading>
    <div>
    <Tooltip content={t.publishReason}>
    <Button disabled focusableWhenDisabled>
    {t.publish}
    </Button>
    </Tooltip>
    </div>
    <Switch label={t.notify} description={t.notifyReason} disabled />
    </Stack>
    <Stack gap="md">
    <Heading level={3} size="sm">
    {t.viewTitle}
    </Heading>
    <DescriptionList items={t.items} dividers />
    </Stack>
    </Stack>
    </div>
    </LangProvider>
    );
    }
    Rule Value
    A control the user can never use Do not disable it; hide it.
    A disabled action Say why: a focusableWhenDisabled Button with a Tooltip giving the reason, or text next to it.
    Submit button Never disabled to signal validation. See Forms and validation.
    View pages Show read-only values as a DescriptionList, not as read-only inputs.
    Disabled Switch Write the reason in description.
    Contrast A disabled item is exempt; a read-only value is read at normal contrast (4.5:1).
    DoThe disabled button takes focus and says why.
    Don'tA silent disabled button gives no reason and cannot take focus.
    1. The user reaches a disabled control. If it is a button that takes focus, the Tooltip shows the reason.
    2. When the reason goes away, for example after a title is added, the control becomes enabled; no extra announcement is needed.
    3. A read-only field takes focus, can be selected and copied; typing does not change the value.
    4. A read-only field is submitted with the form; a disabled field is not. If the value must be sent, use read-only.
    • A focusableWhenDisabled Button has aria-disabled="true" and stays in the tab order; the Tooltip links the reason with aria-describedby.
    • A read-only field has readonly and is announced as “read only” by screen readers.
    • A disabled field has disabled and leaves the tab order. The reason should not live only in a Tooltip; add text next to it when needed.
    • Disabled items are exempt from the WCAG 1.4.3 contrast requirement, so never carry important information in them.
    • The Tooltip opens on keyboard focus as well as on hover.
    • The reason is short and points to a fix: “Add a title before you publish”.
    • Do not write text that repeats the state, such as “Disabled” or “Unavailable”; write the reason.
    • A Switch description gives the state and the way out: “Off because no team is added. Add people on the Team page first.”
    Item Motion Preset
    Field border and fill 110 ms colour change motion.field
    Tooltip 150 ms open, 110 ms close motion.tooltip
    Button 0.97 scale on press when enabled; no motion when disabled motion.press

    With reduced motion, movement is removed and only the fade stays.

    TextInput, Button, Tooltip, Switch, DescriptionList. Related pattern: Forms and validation.