Skip to content
# Rating **Also known as:** Rate, Stars ## Description BitRating turns an opinion into a row of stars: hover to preview what a click would give, click to commit it. Precision splits every item into as many selectable steps as you ask for, so halves, quarters and tenths are reachable with the pointer and with the arrow keys alike, while a bound value of any precision is always drawn exactly - which is what makes the same component the read-only 4.3-out-of-5 summary beside a review count. The whole row is a single tab stop following the WAI-ARIA radiogroup pattern. ## Parameters | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | AllowClear | `bool` | false | Lets the current value be cleared, by clicking the item that is already selected or by pressing Delete or Backspace. Clearing sets the value to 0, so it also makes 0 a reachable value the same way AllowZeroStars does. | | AllowZeroStars | `bool` | false | Puts the unrated 0 in the range of the rating, so a value of 0 is kept instead of being pulled up to the smallest step and the rating can start empty. The keys that reach the ends of the range - Home and the 0 key - reach it, while the pointer always commits at least one step and Delete stays behind AllowClear. | | AriaLabelFormat | `string?` | null | Names each individual rating item - not the rating as a whole - for screen readers. Placeholder {0} is the rating that item stands for, which is its one-based position, and placeholder {1} is the max. Without it an item is named by its ItemTitles tooltip, and failing that by its position in the scale. | | AriaLabelledBy | `string?` | null | The id of an element that names the rating as a whole, for a name that is already written somewhere on the page. It wins over every other source of the name, including the visible Label. | | AutoFocus | `bool` | false | If true, the rating automatically receives focus when the page renders. | | Classes | `BitRatingClassStyles?` | null | Custom CSS classes for different parts of the BitRating. | | Color | `BitColor?` | null | The general color of the rating, applied to the filled part of the items. The unfilled part stays neutral so it reads as "not rated yet" whichever color is picked. An explicit value wins over the --bit-Rating-* color variables (the fill and its hover, active and focus colors); left unset, the rating is primary unless they say otherwise. | | Description | `string?` | null | The hint shown under the items and pointed at by aria-describedby, for the instruction a row of stars cannot give by itself. It describes the rating rather than naming it, so it is announced after the label. | | DescriptionTemplate | `RenderFragment?` | null | Replaces the Description with custom content, which is still what describes the rating for assistive technologies. | | GetAriaLabel | `Func<double, double, string>?` | null | Names the rating as a whole from its current value and the max, which arrive as the first and the second argument. It is used whenever AriaLabel is not set, and like that label it wins over the visible Label. A read-only rating has to carry its value in its name, since its items are hidden behind that single name; this is how to word it. | | GetSelectedIcon | `Func<int, BitIconInfo?>?` | null | Chooses the selected (filled) icon of each rating item separately, from the one-based position of the item. Returning null falls back to SelectedIcon / SelectedIconName. | | GetUnselectedIcon | `Func<int, BitIconInfo?>?` | null | Chooses the unselected (empty) icon of each rating item separately, from the one-based position of the item. Returning null falls back to UnselectedIcon / UnselectedIconName. | | HighlightSelectedOnly | `bool` | false | Highlights only the item matching the current value instead of every item up to it, turning the rating into a scale of standalone choices rather than a cumulative one. A fractional value still fills its own item by the fraction it covers. | | ItemTemplate | `RenderFragment<BitRatingItemContext>?` | null | Replaces the default pair of icons of every rating item with custom content. The template draws the item and nothing else: the item keeps its hit area, hover preview, keyboard handling and name, and the drawing is hidden from assistive technologies as the built-in glyphs are. | | ItemTitles | `IList<string>?` | null | The native tooltips of the rating items, in order, shown when hovering over each one, and used as the accessible name of the item unless AriaLabelFormat overrides it. Items beyond the end of the list simply get no tooltip, and the items of a read-only or disabled rating take no pointer events, so their tooltips never appear there. | | Label | `string?` | null | The visible label of the rating, which also becomes its accessible name: a row of stars carries no text of its own, so without a label - or an AriaLabel - the group is announced without saying what is being rated. A required rating marks its label with an asterisk. | | LabelPlacement | `BitPlacement?` | null | Where the label sits relative to the items: above them by default, and beside them with Start or End for the compact single-line row. | | LabelTemplate | `RenderFragment?` | null | Replaces the Label with custom content, which still names the rating for assistive technologies the same way the plain label does. | | Max | `int` | 5 | Maximum rating, which is also the number of rendered items. Values below 1 are treated as 1. | | NoHoverPreview | `bool` | false | Turns off the preview that follows the pointer over the items and shows the value that a click would commit. Only the preview the component paints stops: OnHoverChange goes on reporting the hovered value. | | OnChanging | `EventCallback<BitRatingChangeArgs>` | | Callback invoked before the value of the rating changes, letting the change be cancelled by setting Cancel on the provided args. | | OnFocusIn | `EventCallback<FocusEventArgs>` | | Callback for when the rating receives the focus. It reports the focus arriving at the rating as a whole, not at each item, so moving along the scale does not raise it again. | | OnFocusOut | `EventCallback<FocusEventArgs>` | | Callback for when the focus leaves the rating. | | OnHoverChange | `EventCallback<double?>` | | Callback for when the hovered value changes, which is the value a click would commit. It receives null when the pointer leaves the rating, and keeps reporting under NoHoverPreview. | | Precision | `double` | 1 | The smallest change of the value the user can make, as a fraction of a single item. The default of 1 only allows whole items, 0.5 adds halves, 0.1 makes every tenth selectable; anything at or above 1, and anything at or below 0, leaves the items whole. It constrains what the user can pick, not what can be displayed, and it is also the floor of the scale unless AllowZeroStars or AllowClear opens up the unrated 0. | | SelectedIcon | `BitIconInfo?` | null | Icon for selected rating elements using external icon libraries (e.g. FontAwesome, Bootstrap Icons). Takes precedence over SelectedIconName when both are set. | | SelectedIconName | `string?` | FavoriteStarFill | Custom icon name for selected rating elements (Fluent UI). For external icon libraries, use SelectedIcon instead. | | Size | `BitSize?` | null | Size of the rating, which scales the item glyphs, the label and the description together. An explicit value wins over --bit-Rating-size, --bit-Rating-label-font-size and --bit-Rating-description-font-size; left unset, the rating is medium unless they say otherwise. | | Styles | `BitRatingClassStyles?` | null | Custom CSS styles for different parts of the BitRating. | | UnselectedIcon | `BitIconInfo?` | null | Icon for unselected rating elements using external icon libraries (e.g. FontAwesome, Bootstrap Icons). Takes precedence over UnselectedIconName when both are set. | | UnselectedIconName | `string?` | FavoriteStar | Custom icon name for unselected rating elements (Fluent UI). For external icon libraries, use UnselectedIcon instead. | | ValueTextFormat | `string?` | null | The format of the spoken form of the current value, where placeholder {0} is the value and placeholder {1} is the max. It is what the live region of an interactive rating announces for a value no radio can carry, and what a read-only rating falls back to when it is given no other label. The default is "{0} of {1}". | | Vertical | `bool` | false | Stacks the rating items in a column instead of a row, filling from the bottom up so that "more" is up, the way the ArrowUp key means more. | | 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 ### BitSize Enum | Name | Value | Description | | :--- | :--- | :---------- | | Small | 0 | The small size. | | Medium | 1 | The medium size. | | Large | 2 | The large size. | ### 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. | ### 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. | ### 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 ### BitRatingClassStyles Properties The CSS classes and styles of the individual parts of the BitRating. | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | Root | `string?` | null | Custom CSS classes/styles for the root element of the rating. | | LabelContainer | `string?` | null | Custom CSS classes/styles for the container of the label of the rating. | | Label | `string?` | null | Custom CSS classes/styles for the label of the rating. | | Description | `string?` | null | Custom CSS classes/styles for the description of the rating. | | Container | `string?` | null | Custom CSS classes/styles for the container of the rating items. | | Button | `string?` | null | Custom CSS classes/styles for the button of each rating item, which is the pointer target that holds the glyphs and carries the data-is-current attribute marking the item the shown value lands in. | | IconContainer | `string?` | null | Custom CSS classes/styles for the rating icon container. | | SelectedIcon | `string?` | null | Custom CSS classes/styles for the rating selected icon. | | UnselectedIcon | `string?` | null | Custom CSS classes/styles for the rating unselected icon. | ### BitRatingChangeArgs Properties The arguments of the OnChanging callback, which runs before the value of the rating changes. | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | Value | `double` | | The rating value the component is about to move to. | | OldValue | `double` | | The rating value the component is moving away from. | | Cancel | `bool` | false | Set to true to cancel the change and keep the current value of the rating. | ### BitRatingItemContext Properties The context passed to the ItemTemplate, describing the rating item being rendered. | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | Index | `int` | | The one-based position of the item in the rating. | | Max | `int` | | The number of items the rating renders. | | Percentage | `double` | | How much of the item is filled, from 0 to 100. A partially filled item is the fractional part of the value. | | DisplayValue | `double` | | The value the item is rendered from, which is the hovered value while a hover preview is active, and the committed value otherwise. | | Value | `double` | | The committed value of the rating, regardless of any hover preview. | | IsSelected | `bool` | | Whether the item is filled at all, meaning its Percentage is greater than zero. | | IsFull | `bool` | | Whether the item is completely filled, meaning its Percentage is 100. | | IsCurrent | `bool` | | Whether this is the item the shown value lands in - the fourth of a 3.5, and the one under the pointer while a hover preview is running. It is the item being picked rather than the exact committed value. | ### BitIconInfo Properties Represents icon information for rendering icons. Supports built-in Fluent UI icons and external icon libraries (FontAwesome, Bootstrap Icons, etc.). Use BitIconInfo.Css("fa-solid fa-star"), BitIconInfo.Fa("solid star"), or BitIconInfo.Bi("star-fill") for external icons. | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | Name | `string?` | null | Gets or sets the name of the icon. | | BaseClass | `string?` | null | Gets or sets the base CSS class for the icon. For external icon libraries like FontAwesome, you might set this to "fa" or leave empty. | | Prefix | `string?` | null | Gets or sets the CSS class prefix used before the icon name. For external icon libraries, you might set this to "fa-" or leave empty. | ## 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-Rating-color` | --bit-clr-pri | Color of the filled part of the items. The Color parameter wins over it. | | `--bit-Rating-unselected-color` | --bit-clr-fg-ter | Color of the unfilled part of the items, which stays neutral whatever the Color is so that it keeps reading as "not rated yet". | | `--bit-Rating-hover-color` | --bit-clr-pri-hover | Color of the filled part while the pointer is previewing a value over the items (pointer devices only). The Color parameter wins over it. | | `--bit-Rating-active-color` | --bit-clr-pri-active | Color of the filled part while an item is being pressed, which on a touch device - where there is no hover - is the only feedback a tap gets before the new value lands. The Color parameter wins over it. | | `--bit-Rating-focus-color` | --bit-clr-pri-focus | Color of the keyboard focus ring of an item. 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-Rating-disabled-color` | --bit-clr-fg-dis | Color of both parts of the items, and of the label, when Disabled is true. | | `--bit-Rating-invalid-color` | --bit-clr-err (items), --bit-clr-err-focus (ring) | Color of both parts of the items, and of the focus ring, while the value is invalid. | | `--bit-Rating-size` | --bit-siz-icon-md | Size of the item glyphs. It does not move the label or the description, which have text sizes of their own. The Size parameter wins over it. | | `--bit-Rating-target-size` | 1.5rem | Smallest pointer target of an item on both axes, which the glyph is centred in - the 24px minimum of WCAG 2.2 (SC 2.5.8). Raise it for the roomier targets of a touch platform, or set it to 0 to shrink the items to the glyph and its padding, for a rating that has to sit inside a line of running text. | | `--bit-Rating-padding` | spacing(0.25) | Padding of an item around its glyph, which only widens the item once it exceeds the target size. | | `--bit-Rating-gap` | 0 | Extra room between the items, beyond their own padding. | | `--bit-Rating-radius` | --bit-shp-radius-control | Corner radius of an item and of its focus ring. | | `--bit-Rating-hover-scale` | 1.1 | How much the item under the pointer grows, which is the affordance that says the items are there to be pressed. A value of 1 turns it off. | | `--bit-Rating-active-scale` | 0.9 | How much the item being pressed dips - it shrinks rather than grows, since a pointer has already grown it by hovering it. A value of 1 turns it off. | | `--bit-Rating-label-color` | --bit-clr-fg-pri | Text color of the label. | | `--bit-Rating-label-font-size` | --bit-tpg-fs-sm | Text size of the label. The Size parameter wins over it. | | `--bit-Rating-label-font-weight` | --bit-tpg-field-label-font-weight | Text weight of the label. | | `--bit-Rating-label-gap` | spacing(1) | Room between the label and the items, and between the items and the description. | | `--bit-Rating-description-color` | --bit-clr-fg-sec | Text color of the description. | | `--bit-Rating-description-font-size` | --bit-tpg-fs-xs | Text size of the description. The Size parameter wins over it. | ## Examples \n**Basic**: ```razor ``` \n**Label & item titles**: ```razor Averaged over 1,034 stays, updated nightly. @ratingWords[(int)labelTemplateValue] ``` ```csharp private double labelValue = 3; private double labelTemplateValue = 4; private readonly string[] ratingWords = ["Not rated yet", "Terrible", "Bad", "Normal", "Good", "Wonderful"]; ``` \n**Max**: ```razor
4.2 · 1,034 reviews
``` \n**Vertical**: ```razor Value: @verticalValue Value: @verticalPrecisionValue ``` ```csharp private double verticalValue = 3; private double verticalPrecisionValue = 3.5; ``` \n**Precision**: ```razor Value: @halfPrecisionValue Value: @quarterPrecisionValue Value: @exactPrecisionValue ``` ```csharp private double halfPrecisionValue = 2.5; private double quarterPrecisionValue = 3.25; private double exactPrecisionValue = 3.7; ``` \n**Clearing**: ```razor Value: @noZeroValue Value: @noZeroHalfValue Value: @allowZeroValue Value: @allowClearValue ``` ```csharp private double noZeroValue; private double noZeroHalfValue; private double allowZeroValue; private double allowClearValue = 3; ``` \n**HighlightSelectedOnly**: ```razor Value: @highlightValue ``` ```csharp private double highlightValue = 3; ``` \n**Hover preview**: ```razor @ratingWords[(int)(hoverPreviewValue ?? hoverBoundValue)] @(noPreviewHoverValue is null ? $"Rated {noPreviewValue}" : $"Click for {noPreviewHoverValue}") ``` ```csharp private double hoverBoundValue = 3; private double? hoverPreviewValue; private double noPreviewValue = 2; private double? noPreviewHoverValue; private readonly string[] ratingWords = ["Not rated yet", "Terrible", "Bad", "Normal", "Good", "Wonderful"]; ``` \n**Icons**: ```razor Value: @perItemIconValue Value: @faceValue ``` ```csharp private double perItemIconValue = 4; private double faceValue = 3; private readonly string[] faceIcons = [ BitIconName.EmojiDisappointed, BitIconName.Sad, BitIconName.EmojiNeutral, BitIconName.Emoji, BitIconName.Emoji2 ]; private BitIconInfo GetFaceIcon(int index) => BitIconInfo.Bit(faceIcons[index - 1]); ``` \n**ItemTemplate**: ```razor @item.Index Value: @templateValue @moodFaces[item.Index - 1] Value: @moodValue ``` ```csharp private double templateValue = 7; private double moodValue = 4; private readonly string[] moodFaces = ["😖", "😐", "🙂", "😀", "🤩"]; ``` `BitRatingDemo.razor.scss`: ```scss // A plain badge that fills once its item does. .number-item { width: 1.75rem; height: 1.75rem; line-height: 1; font-size: 0.875rem; align-items: center; display: inline-flex; border-radius: 0.25rem; justify-content: center; color: $bit-color-foreground-tertiary; border: 1px solid $bit-color-border-primary; } .number-item-on { color: $bit-color-primary-text; border-color: $bit-color-primary; background-color: $bit-color-primary; } // IsCurrent is the item the value lands in, which is the last of the filled run rather than all of it. .number-item-current { outline: 2px solid $bit-color-primary; outline-offset: 2px; } // The mood faces, greyed out until their item is the selected one. .emoji-item { opacity: 0.4; line-height: 1; font-size: 1.75rem; display: inline-block; filter: grayscale(1); } .emoji-item-on { opacity: 1; filter: none; } ``` \n**Binding**: ```razor ``` ```csharp private double oneWayBinding = 0; private double twoWayBinding = 3; ``` \n**Events**: ```razor Changed value: @onChangeValue Value: @onChangingValue @(changeRejected ? "(lowering was rejected)" : "") @(isFocused ? "Focused" : "Not focused") ``` ```csharp private double onChangeValue; private double onChangingValue = 3; private bool changeRejected; private bool isFocused; private void HandleOnChanging(BitRatingChangeArgs args) { changeRejected = args.Value < args.OldValue; args.Cancel = changeRejected; } ``` \n**Validation**: ```razor Submit ``` ```csharp public class BitRatingDemoFormModel { [Range(typeof(double), "1", "5", ErrorMessage = "Your rate must be between {1} and {2}")] public double Value { get; set; } } public BitRatingDemoFormModel ValidationModel = new(); private void HandleValidSubmit() { } private void HandleInvalidSubmit() { } ``` `BitRatingDemo.razor.scss`: ```scss .validation-message { color: $bit-color-error; } ``` \n**Accessibility**: ```razor Value: @accessibilityValue
Overall satisfaction
``` ```csharp private double accessibilityValue = 3; private string GetRatingAriaLabel(double value, double max) => $"Rated {value} out of {max}"; ``` \n**Visibility**: ```razor Visible: [ ] Hidden: [ ] Collapsed: [ ] ``` \n**Score-based styling**: ```razor @scoreWords[(int)scoreValue] ``` ```csharp private double scoreValue = 2; private readonly string[] scoreWords = ["Unrated", "Poor", "Poor", "Okay", "Great", "Great"]; private BitColor GetScoreColor() => scoreValue switch { <= 2 => BitColor.Error, <= 3 => BitColor.Warning, _ => BitColor.Success }; private BitIconInfo GetScoreIcon(int index) => BitIconInfo.Bit(scoreValue switch { <= 2 => BitIconName.Sad, <= 3 => BitIconName.EmojiNeutral, _ => BitIconName.Emoji2 }); ``` \n**Cascading parameters**: ```razor ``` ```csharp private double cascadeValue = 3; private readonly BitRatingParams[] ratingParams = [ new() { ReadOnly = true, Precision = 0.5, Size = BitSize.Small, Color = BitColor.Warning, SelectedIconName = BitIconName.HeartFill, UnselectedIconName = BitIconName.Heart, LabelPlacement = BitPlacement.Start } ]; ``` \n**Color**: ```razor ``` \n**External Icons**: ```razor ``` \n**Size**: ```razor ``` \n**Style & Class**: ```razor
Rated by 1,034 people.
``` ```csharp private double currentItemValue = 3.5; ``` `BitRatingDemo.razor.scss`: ```scss .custom-class { margin-inline: 1rem; border-radius: 0.25rem; padding-inline: 0.5rem; border: 1px solid dodgerblue; box-shadow: dodgerblue 0 0 1rem; } .custom-label { color: dodgerblue; text-transform: uppercase; } .custom-selected { color: seagreen; } .custom-unselected { color: mediumseagreen; } // data-is-current marks the item the shown value lands in - the fourth of a 3.5, and the one // under the pointer while a hover preview is running. .ringed-item[data-is-current="true"] { outline: 1px dashed $bit-color-primary; outline-offset: -1px; } ``` \n**RTL**: ```razor ```