Skip to content
# Checkbox ## Description BitCheckbox turns a yes/no decision into a small clickable box with a label - check it to say yes, clear it to say no. It is backed by a real native checkbox input, so it is part of the tab order, toggles with Space, submits with forms and is announced correctly by screen readers. Beyond the two plain states it offers an indeterminate state for partially selected lists and an opt-in three-state cycle for questions whose honest third answer is no answer; each of the three states can render its own icon. The label can sit on any side of the box, a second line can explain what checking it commits to, changes can be cancelled before they land or shown as still in flight, and read-only and required modes plus form validation cover the form scenarios. ## Parameters | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | AllowDisabledFocus | `bool` | false | Keeps the disabled checkbox in the tab order and announced as disabled through aria-disabled instead of the native disabled attribute, with its toggling suppressed either way. | | AriaControls | `string?` | null | The id of the element the checkbox controls - the list a select-all checkbox governs - rendered as aria-controls on the checkbox input. | | AriaDescribedby | `string?` | null | The ids of the elements that describe the checkbox, rendered into aria-describedby beside the ids Description and AriaDescription contribute. | | AriaDescription | `string?` | null | Detailed description of the checkbox for the benefit of screen readers, rendered as a visually hidden element that the checkbox input points to via aria-describedby. | | AriaLabelledby | `string?` | null | ID for element that contains label information for the checkbox. | | AriaPositionInSet | `int?` | null | The position in the parent set (if in a set) for aria-posinset. | | AriaSetSize | `int?` | null | The total size of the parent set (if in a set) for aria-setsize. | | AutoFocus | `bool` | false | If true, the checkbox input automatically receives focus when the page renders. | | AutoLoading | `bool` | false | Turns the checkbox busy by itself for as long as the awaited callbacks behind a change are still running. A Loading set from the outside still applies on top of it. | | CheckIcon | `BitIconInfo?` | null | The check icon using custom CSS classes for external icon libraries. Takes precedence over CheckIconName when both are set. Use BitIconInfo.Bi(), BitIconInfo.Fa(), or BitIconInfo.Css() for Bootstrap Icons, FontAwesome, or custom CSS. | | CheckIconName | `string?` | Accept | The name of the built-in icon to render as the check mark inside the checkbox. | | CheckIconAriaLabel | `string?` | null | Exposes the glyph inside the box as an image with this name. It is hidden from assistive technologies by default, since the state it stands for is already announced by the input itself. | | ChildContent | `RenderFragment?` | null | Used to customize the content of checkbox(Label and Box). | | Classes | `BitCheckboxClassStyles?` | null | Custom CSS classes for different parts of the BitCheckbox. | | Color | `BitColor?` | null | The general color of the checkbox. An explicit value wins over the --bit-Checkbox-* color variables (checked, indeterminate, focus and disabled colors); left unset, the checkbox is primary unless they say otherwise. | | DefaultIndeterminate | `bool?` | null | Default indeterminate visual state for checkbox. | | DefaultValue | `bool?` | null | The default value of the checkbox to be used in uncontrolled mode (i.e. when the Value is not bound). | | Description | `string?` | null | A visible explanation of what checking the box means, rendered on a line of its own under it and announced after the name of the checkbox through aria-describedby. | | DescriptionTemplate | `RenderFragment?` | null | Custom description of the checkbox, replacing Description with arbitrary markup. | | FullWidth | `bool` | false | Stretches the checkbox across the full available width, pushing the box and the label to opposite edges. Applies to the single-line label placements only. | | Indeterminate | `bool` | false | An indeterminate visual state for checkbox. The indeterminate state takes visual precedence over the checked state but does not affect the Value. | | IndeterminateIcon | `BitIconInfo?` | null | The icon to render in the indeterminate state using custom CSS classes for external icon libraries, replacing the default filled square. Takes precedence over IndeterminateIconName when both are set. | | IndeterminateIconName | `string?` | null | The name of the built-in icon to render in the indeterminate state, replacing the default filled square. | | Label | `string?` | null | Descriptive label for the checkbox. | | LabelPlacement | `BitPlacement?` | null | The position of the label in regards to the checkbox box. Takes precedence over Reversed when both are set. Only Top, Bottom, Start and End are honoured; any other value leaves the layout as it is with this unset. | | LabelTemplate | `RenderFragment?` | null | Used to customize the label for the checkbox. | | Loading | `bool` | false | Turns the checkbox busy: the glyph becomes a spinner, clicks are turned away and the checkbox is announced as busy, while it keeps the state it is in and stays focusable. | | Name | `string?` | null | Name for the checkbox input. This is intended for use with forms and NOT displayed in the UI. | | NoWrap | `bool` | false | Keeps the label of the checkbox on a single line and ends it with an ellipsis where it does not fit. Pair it with a Title so the part that was cut off is still reachable. | | OnBlur | `EventCallback<FocusEventArgs>` | | Callback for when the checkbox loses focus. | | OnChange | `EventCallback<bool>` | | Callback for when the checkbox value changes, once the new state is committed. | | OnChanging | `EventCallback<BitCheckboxChangeArgs>` | | Callback invoked before the state of the checkbox changes, letting the change be cancelled by setting Cancel on its arguments. | | OnClick | `EventCallback<MouseEventArgs>` | | Callback for when the checkbox clicked. | | OnFocus | `EventCallback<FocusEventArgs>` | | Callback for when the checkbox receives focus. | | OnFocusIn | `EventCallback<FocusEventArgs>` | | Callback for when the focus moves into the checkbox. | | OnFocusOut | `EventCallback<FocusEventArgs>` | | Callback for when the focus moves out of the checkbox. | | ReadOnly | `bool` | false | Makes the checkbox read-only: it stays focusable and gets announced by screen readers, but user interaction no longer changes its state. | | Required | `bool` | false | Makes the checkbox required, rendering the native required attribute on its input and an asterisk next to its label. | | Reversed | `bool` | false | Reverses the label and checkbox location. | | Size | `BitSize?` | null | The size of the checkbox. An explicit value wins over --bit-Checkbox-box-size, --bit-Checkbox-font-size and --bit-Checkbox-description-font-size; left unset, the checkbox is medium unless they say otherwise. | | StopPropagation | `bool` | false | If true, stops the click event from bubbling up to the parent elements. | | Styles | `BitCheckboxClassStyles?` | null | Custom CSS styles for different parts of the BitCheckbox. | | ThreeState | `bool` | false | Enables cycling through the unchecked, checked and indeterminate states on each click, instead of the indeterminate state being reachable only programmatically. | | Title | `string?` | null | Title text applied to the label container of the checkbox. | | UncheckedIcon | `BitIconInfo?` | null | The icon to render in the unchecked state using custom CSS classes for external icon libraries. Takes precedence over UncheckedIconName when both are set. | | UncheckedIconName | `string?` | null | The name of the built-in icon to render in the unchecked state. By default the unchecked box is empty and previews the check icon on hover. | | DefaultValue | `TValue?` | null | The default value of the input to be used in uncontrolled mode (i.e. when the Value is not bound), typically used alongside the OnChange callback. | | DisplayName | `string?` | null | Gets or sets the display name for this field. | | InputHtmlAttributes | `IReadOnlyDictionary<string, object>?` | null | Gets or sets a collection of additional attributes that will be applied to the created element. | | Name | `string?` | null | Gets or sets the name of the element. Allows access by name from the associated form. | | NoValidate | `bool` | false | Disables the validation of the input. | | OnChange | `EventCallback<TValue?>` | | Callback for when the input value changes. | | ReadOnly | `bool` | false | Makes the input read-only. | | Required | `bool` | false | Makes the input required. | | Value | `TValue?` | null | Gets or sets the value of the input. This should be used with two-way binding. | | AriaLabel | `string?` | null | Gets or sets the accessible label for the component, used by assistive technologies. | | Class | `string?` | null | Gets or sets the CSS class name(s) to apply to the rendered element. | | Dir | `BitDir?` | null | Gets or sets the text directionality for the component's content. | | Disabled | `bool` | false | Gets or sets a value indicating whether the component is disabled and cannot respond to user interaction. | | ForceAnimation | `bool` | false | Gets or sets a value indicating whether the component's animations play at their full duration even when reduced motion is requested. | | HtmlAttributes | `Dictionary<string, object>` | new Dictionary<string, object>() | Captures additional HTML attributes to be applied to the rendered element, in addition to the component's parameters. An attribute written on the component wins over an entry of the same name. | | Id | `string?` | null | Gets or sets the unique identifier for the component's root element. | | Style | `string?` | null | Gets or sets the CSS style string to apply to the rendered element. | | TabIndex | `string?` | null | Gets or sets the tab order index for the component when navigating with the keyboard. | | Visibility | `BitVisibility` | BitVisibility.Visible | Gets or sets the visibility state (visible, hidden, or collapsed) of the component. | ## Public Members | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | InputElement | `ElementReference` | | The ElementReference of the input element. | | FocusAsync() | `() => ValueTask` | | Gives focus to the input element. | | FocusAsync(bool preventScroll) | `(bool preventScroll) => ValueTask` | | Gives focus to the input element. | | UniqueId | `Guid` | Guid.NewGuid() | Gets the readonly unique identifier for the component's root element, assigned when the component instance is constructed. | | RootElement | `ElementReference` | | Gets the reference to the root HTML element associated with this component. | ## Enums ### BitColor Enum | Name | Value | Description | | :--- | :--- | :---------- | | Primary | 0 | Primary general color. | | Secondary | 1 | Secondary general color. | | Tertiary | 2 | Tertiary general color. | | Info | 3 | Info general color. | | Success | 4 | Success general color. | | Warning | 5 | Warning general color. | | SevereWarning | 6 | SevereWarning general color. | | Error | 7 | Error general color. | | PrimaryBackground | 8 | Primary background color. | | SecondaryBackground | 9 | Secondary background color. | | TertiaryBackground | 10 | Tertiary background color. | | PrimaryForeground | 11 | Primary foreground color. | | SecondaryForeground | 12 | Secondary foreground color. | | TertiaryForeground | 13 | Tertiary foreground color. | | PrimaryBorder | 14 | Primary border color. | | SecondaryBorder | 15 | Secondary border color. | | TertiaryBorder | 16 | Tertiary border color. | ### BitPlacement Enum | Name | Value | Description | | :--- | :--- | :---------- | | Top | 0 | The top edge. | | Bottom | 1 | The bottom edge. | | Start | 2 | The edge the reading direction starts from - the left in LTR, the right in RTL. On the vertical axis, which does not turn around, it is the top. | | End | 3 | The edge the reading direction ends at - the right in LTR, the left in RTL. On the vertical axis, which does not turn around, it is the bottom. | | Left | 4 | The left edge, in both reading directions. | | Right | 5 | The right edge, in both reading directions. | | Center | 6 | The middle of the axis, against neither edge. | | TopAndBottom | 7 | Both edges of the block axis at once. | | StartAndEnd | 8 | Both edges of the inline axis at once, following the reading direction the way Start and End do. | ### BitSize Enum | Name | Value | Description | | :--- | :--- | :---------- | | Small | 0 | The small size. | | Medium | 1 | The medium size. | | Large | 2 | The large size. | ### BitVisibility Enum | Name | Value | Description | | :--- | :--- | :---------- | | Visible | 0 | The content of the component is visible. | | Hidden | 1 | The content of the component is hidden, but the space it takes on the page remains (visibility:hidden). | | Collapsed | 2 | The component is hidden (display:none). | ### BitDir Enum | Name | Value | Description | | :--- | :--- | :---------- | | Ltr | 0 | Ltr (left to right) is to be used for languages that are written from the left to the right (like English). | | Rtl | 1 | Rtl (right to left) is to be used for languages that are written from the right to the left (like Arabic). | | Auto | 2 | Auto lets the user agent decide. It uses a basic algorithm as it parses the characters inside the element until it finds a character with a strong directionality, then applies that directionality to the whole element. | ## Sub Classes ### BitCheckboxClassStyles Properties | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | Root | `string?` | null | Custom CSS classes/styles for the root element of the BitCheckBox. | | Container | `string?` | null | Custom CSS classes/styles for the container of the BitCheckbox. | | Checked | `string?` | null | Custom CSS classes/styles for the checked state of the BitCheckbox. | | Description | `string?` | null | Custom CSS classes/styles for the description of the BitCheckbox. | | Indeterminate | `string?` | null | Custom CSS classes/styles for the indeterminate state of the BitCheckbox. | | Box | `string?` | null | Custom CSS classes/styles for the box element of the BitCheckbox. | | Icon | `string?` | null | Custom CSS classes/styles for the icon of the BitCheckbox. | | Label | `string?` | null | Custom CSS classes/styles for the label of the BitCheckbox. | | Spinner | `string?` | null | Custom CSS classes/styles for the spinner rendered inside the box while the BitCheckbox is busy. | ### BitCheckboxChangeArgs Properties The arguments of the OnChanging callback of the BitCheckbox. | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | Value | `bool` | false | The checked state the checkbox is about to move to. | | Indeterminate | `bool` | false | The indeterminate state the checkbox is about to move to. | | Cancel | `bool` | false | Set to true to cancel the change and keep the current state of the checkbox. | ## CSS Variables Public CSS custom properties read off the component's root. Set one on `:root` to restyle every instance, on any ancestor to restyle the ones inside it, or on the `Style` of one instance to restyle it and every instance nested inside it, which inherits the value too - a parameter changes one alone, as does the real CSS property on its `Style` / `Styles` when that property does not inherit (`opacity`); an inherited one (`color`, `font-family`) reaches the nested instances that do not set it themselves. | Name | Default Value | Description | | :--- | :------------ | :---------- | | `--bit-Checkbox-color` | Inherited from the page | Color of the label text. Left unset the label takes the color of whatever it sits in, which is what keeps a checkbox legible on any surface. | | `--bit-Checkbox-description-color` | --bit-clr-fg-sec | Color of the Description line under the label. | | `--bit-Checkbox-disabled-color` | --bit-clr-pri-dis | Stroke and fill of the box when Disabled is true; also the focus ring color of a disabled checkbox kept focusable with AllowDisabledFocus. The Color parameter wins over it. | | `--bit-Checkbox-disabled-text-color` | --bit-clr-pri-dis-text | Color of the label, the description and the glyph when Disabled is true. The Color parameter wins over it. | | `--bit-Checkbox-focus-color` | --bit-clr-pri-focus | Color of the keyboard focus ring, drawn around the box - or around the whole face of a checkbox given a ChildContent. The Color parameter wins over it. While it is unset, the focus ring is the library's own --bit-shd-focus-ring, so replacing that token re-shapes it too. | | `--bit-Checkbox-required-color` | --bit-clr-req | Color of the asterisk that marks a required checkbox. | | `--bit-Checkbox-background` | transparent | Fill of the box while unchecked, which the indeterminate state keeps. | | `--bit-Checkbox-border-color` | --bit-clr-brd-pri | Stroke of the box while unchecked. | | `--bit-Checkbox-hover-background` | --bit-Checkbox-background | Fill of the box while unchecked and hovered (pointer devices only). | | `--bit-Checkbox-hover-border-color` | --bit-Checkbox-border-color | Stroke of the box while unchecked and hovered (pointer devices only). | | `--bit-Checkbox-checked-background` | --bit-clr-pri | Fill of the box while checked. The Color parameter wins over it. | | `--bit-Checkbox-checked-hover-background` | --bit-clr-pri-hover | Fill of the box while checked and hovered (pointer devices only). The Color parameter wins over it. | | `--bit-Checkbox-checked-border-color` | --bit-Checkbox-checked-background | Stroke of the box while checked. Set it apart from the fill for the Material-style outlined box. The Color parameter wins over it. | | `--bit-Checkbox-check-color` | --bit-clr-pri-text | Color of the glyph drawn on the checked box. The Color parameter wins over it. | | `--bit-Checkbox-indeterminate-color` | --bit-clr-pri | Color of the mark of the mixed state - the filled square or a custom IndeterminateIcon - and of the box stroke around it. The Color parameter wins over it. | | `--bit-Checkbox-indeterminate-size` | Half the box | Side of the filled square the mixed state draws in the middle of the box. It follows the box size on its own, so set it only to change that proportion. It has no effect where an IndeterminateIcon replaces the square. | | `--bit-Checkbox-box-size` | --bit-siz-sel-md | Side of the box, and the one number the rest of the face follows: the glyph, the filled square of the mixed state and the indent that keeps the description lined up with the label all scale with it. The Size parameter wins over it. | | `--bit-Checkbox-icon-size` | 9/16 of the box | Font size of the glyph inside the box. It follows the box size on its own, so set it only for a glyph that needs more or less room than a check mark - a wide external icon, say. | | `--bit-Checkbox-border-width` | --bit-shp-brd-width | Thickness of the box stroke. | | `--bit-Checkbox-radius` | --bit-shp-radius-selection | Corner radius of the box, which the filled square of the mixed state follows. Set it to 50% for a round box. | | `--bit-Checkbox-gap` | spacing(1) | Room between the box and the label. | | `--bit-Checkbox-font-size` | --bit-tpg-fs-sm | Font size of the label. The Size parameter wins over it. | | `--bit-Checkbox-font-weight` | --bit-tpg-fw-regular | Font weight of the label. | | `--bit-Checkbox-description-font-size` | --bit-tpg-fs-xs | Font size of the description, one step below the label on the type ramp. The Size parameter wins over it. | | `--bit-Checkbox-description-gap` | spacing(0.25) | Room between the label and the description under it. | | `--bit-Checkbox-min-height` | The box size, never below spacing(3) | Smallest height and width of the click target, which is the label rather than the box. It is what keeps every size above the 24px minimum pointer target of WCAG 2.2 (SC 2.5.8), and it is a floor rather than a size: a wrapped label still grows the row. Set it to 0 for a checkbox that has to sit on the line of the running text around it. | ## Examples \n**Basic**: ```razor ``` \n**Icons**: ```razor ``` \n**Label placement**: ```razor ``` \n**FullWidth & NoWrap**: ```razor
``` \n**Description**: ```razor
Read the full agreement before you agree. ``` \n**Indeterminate & three-state**: ```razor
Value: @threeStateValue, Indeterminate: @threeStateIndeterminate
subscribed: @(subscribed?.ToString() ?? "null")
``` ```csharp private bool basicIndeterminate = true; private bool apple; private bool banana; private bool orange; private bool selectAll; private bool selectAllIndeterminate; private void HandleSelectAllChange(bool value) { selectAll = value; selectAllIndeterminate = false; apple = banana = orange = value; } private void RefreshSelectAll() { var checkedCount = (apple ? 1 : 0) + (banana ? 1 : 0) + (orange ? 1 : 0); selectAll = checkedCount == 3; selectAllIndeterminate = checkedCount is > 0 and < 3; } private bool threeStateValue; private bool threeStateIndeterminate; private bool? subscribed = false; // A click reports the mixed state before the value, so the mixed one has the last word: the value that // follows a "no answer" is not an answer either, which is what keeps the null from being overwritten // with the false underneath it. private void HandleSubscribedIndeterminateChanged(bool indeterminate) => subscribed = indeterminate ? null : subscribed is true; private void HandleSubscribedValueChanged(bool value) => subscribed = subscribed is null ? null : value; ``` \n**Binding**: ```razor ``` ```csharp private bool oneWayValue; private bool twoWayValue; private bool oneWayIndeterminate = true; private bool twoWayIndeterminate = true; ``` \n**Templates**: ```razor Label Template Custom basic checkbox Custom indeterminate checkbox Make Indeterminate ``` ```csharp private bool customCheckboxValue; private bool customContentValue; private bool customContentIndeterminate = true; ``` \n**Events**: ```razor
@(string.IsNullOrEmpty(eventsLog) ? "No clicks yet." : eventsLog)
Cancelled attempts: @cancelledCounter
Container clicks: @containerClickCounter
``` ```csharp private string eventsLog = string.Empty; private bool eventsCycleEnded; private int cancelledCounter; private int containerClickCounter; private bool allowChange; private void LogOnClick() => AppendEventLog("OnClick"); private void LogOnChanging(BitCheckboxChangeArgs args) => AppendEventLog($"OnChanging({args.Value})"); private void LogOnChange(bool value) { AppendEventLog($"OnChange({value})"); eventsCycleEnded = true; } private void LogOnFocus() => AppendEventLog("OnFocus"); private void LogOnFocusIn() => AppendEventLog("OnFocusIn"); private void LogOnFocusOut() => AppendEventLog("OnFocusOut"); private void LogOnBlur() => AppendEventLog("OnBlur"); // Every callback appends, so the log is the order they actually fired in - the focus arriving is still // on the line when the click that follows it is written. Only the first one after a completed click // starts the line over, which is what keeps a second click from being read as part of the first. private void AppendEventLog(string name) { if (eventsCycleEnded) { eventsLog = string.Empty; eventsCycleEnded = false; } eventsLog += eventsLog.Length == 0 ? name : $" → {name}"; } private void HandleOnChanging(BitCheckboxChangeArgs args) { if (allowChange) return; args.Cancel = true; cancelledCounter++; } ``` \n**Read-only & Required**: ```razor I accept the terms ``` ```csharp private bool readOnlyValue; ``` \n**Validation**: ```razor @if (string.IsNullOrEmpty(SuccessMessage)) {
Submit
} else { @SuccessMessage } ``` ```csharp private string SuccessMessage = string.Empty; private BitCheckboxValidationModel validationModel = new(); public class BitCheckboxValidationModel { [Range(typeof(bool), "true", "true", ErrorMessage = "You must agree to the terms and conditions.")] public bool TermsAgreement { get; set; } } private async Task HandleValidSubmit() { SuccessMessage = "Form Submitted Successfully!"; await Task.Delay(3000); SuccessMessage = string.Empty; StateHasChanged(); } private void HandleInvalidSubmit() { SuccessMessage = string.Empty; } ``` \n**Accessibility**: ```razor Focus the checkbox Weekly newsletter
``` ```csharp private BitCheckbox checkboxRef = default!; private async Task FocusTheCheckbox() => await checkboxRef.FocusAsync(); ``` \n**Loading**: ```razor
Saved: @savedCount time(s)
``` ```csharp private int savedCount; private async Task HandleSlowChanging(BitCheckboxChangeArgs args) { await Task.Delay(2000); savedCount++; } ``` \n**Cascading parameters**: ```razor
``` ```csharp private readonly BitCheckboxParams[] checkboxParams = [ new() { FullWidth = true, Reversed = true, CheckIconName = BitIconName.Heart, } ]; ``` \n**Color**: ```razor
``` \n**External Icons**: ```razor ``` \n**Size**: ```razor ``` \n**Style & Class**: ```razor
``` \n**RTL**: ```razor ```