Skip to content
# Splitter **Also known as:** SplitPane, Resizable ## Description Two panels, side by side or stacked, with a gutter between them the reader drags or moves from the keyboard. Panels take sizes and limits, the split can be bound as a percentage, remembered across visits and folded away, and the gutter is a WAI-ARIA window splitter. ## Parameters | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | Classes | `BitSplitterClassStyles?` | null | Custom CSS classes for different parts of the BitSplitter. | | CollapseIcon | `BitIconInfo?` | null | The icon of the collapse button while the panel that folds is open, using BitIconInfo for external icon library support. Takes precedence over CollapseIconName when both are set. | | CollapseIconName | `string?` | null | The name of the built-in Fluent UI icon shown on the collapse button while the panel that folds is open. The default is a chevron pointing at the panel that is about to be folded away, which follows the orientation of the splitter, which panel folds and the writing direction of the page. | | Collapsed | `bool` | false | Whether the panel that folds is collapsed; bindable. A collapsed panel keeps its content in the DOM, drops to CollapsedSize past its minimum, and is made inert when that size is 0. Expanding restores the previous split. | | CollapsedSize | `int` | 0 | The size, in pixels, the folded panel is held at while it is collapsed. | | Collapsible | `bool` | false | Lets the reader fold a panel away from the gutter: Enter, Ctrl + arrow, the collapse button, or a drag that snaps it shut at its edge. | | CollapseSecondPanel | `bool` | false | Folds the second panel instead of the first - an inspector or a preview at the far end. Everything collapse-related follows it; Percent still describes the first panel. | | DefaultPercent | `double?` | null | The share of the splitter, 0 to 100, the first panel starts at and is reset to, while the reader stays free to move it. Wins over the panel sizes; Percent wins over it. | | DragStep | `int` | 0 | A pixel grid the split lands on, for the pointer and the keyboard alike. 0 is no grid. | | ExpandIcon | `BitIconInfo?` | null | The icon of the collapse button while the panel that folds is away, using BitIconInfo for external icon library support. Takes precedence over ExpandIconName when both are set. | | ExpandIconName | `string?` | null | The name of the built-in Fluent UI icon shown on the collapse button while the panel that folds is away. The default is a chevron pointing at the room the panel is about to come back into. | | FirstPanel | `RenderFragment?` | null | The content for the first panel. | | FirstPanelSize | `int?` | null | The initial size of the first panel in pixels. From the first drag on, the split is held as a percentage in Percent, which takes precedence over this and over SecondPanelSize. | | FirstPanelMaxSize | `int?` | null | The max size of the first panel in pixels. | | FirstPanelMinSize | `int?` | null | The min size of the first panel in pixels. | | GutterHitSize | `int?` | null | The smallest strip, in pixels, a press takes hold of the gutter in; it reaches past a thinner gutter without taking room from the panels. Unset, 24 (the WCAG target size), and 44 for a coarse pointer. | | GutterIcon | `BitIconInfo?` | null | The icon for the BitSplitter gutter using BitIconInfo for external icon library support. Takes precedence over GutterIconName when both are set. | | GutterIconName | `string?` | null | The name of the built-in Fluent UI icon to render in the BitSplitter gutter. Ignored when GutterIcon is also set. | | GutterSize | `int?` | null | The size of BitSplitter gutter in pixels. | | GutterTemplate | `RenderFragment?` | null | The custom content of the gutter, in place of the icon or of the default grip indicator. The gutter is the separator itself, so what goes in here is decoration rather than a control. | | KeyboardStep | `int` | 10 | How far, in pixels, an arrow key moves the gutter. Shift + arrow, Page Up and Page Down move ten steps; Home and End go to the limits. | | LazyResize | `bool` | false | Drags a line instead of the panels and lays them out once, on release - for content too heavy to lay out on every frame. | | NoResetOnDoubleClick | `bool` | false | Keeps the gutter from resetting the splitter to the sizes its parameters declare when it is double-clicked. | | OnCollapsedChange | `EventCallback<bool>` | | The callback invoked when the panel that folds is collapsed or expanded. | | OnCollapsing | `EventCallback<BitSplitterCollapseArgs>` | | The callback invoked before the panel that folds is collapsed or expanded, with what is about to happen and what asked for it. Set Cancel on the arguments to leave the panel as it is. The callback is awaited, and nothing else folds the panel while it is running. | | OnGutterDoubleClick | `EventCallback` | | The callback invoked when the gutter is double-clicked, whether or not the double-click also resets the splitter. | | OnResize | `EventCallback<double>` | | The callback invoked continuously while the gutter is being dragged, with the new share of the splitter the first panel takes up, as a percentage. It is coalesced to one call per animation frame, and a splitter with no handler for it makes no interop call at all while it is being dragged. | | OnResizeCancel | `EventCallback<double>` | | The callback invoked when a resize is abandoned rather than finished - by Escape, or by the browser taking the pointer away - with the share of the splitter the first panel is put back to. Exactly one of this and OnResizeEnd follows every OnResizeStart. | | OnResizeEnd | `EventCallback<double>` | | The callback invoked when a resize has finished, with the share of the splitter the first panel ended up taking, as a percentage. | | OnResizeStart | `EventCallback<double>` | | The callback invoked when a resize starts, with the share of the splitter the first panel takes up at that moment, as a percentage. | | PersistKey | `string?` | null | The storage key the position and the fold are remembered under, and restored from on the next visit. Unique per splitter within the origin. | | PersistInSessionStorage | `bool` | false | Keeps what PersistKey remembers in the browser's session storage rather than its local storage, so the position lasts as long as the tab and no longer. | | Percent | `double?` | null | The share of the splitter the first panel takes up, as a percentage between 0 and 100. It survives the container being resized and can be bound, so every drag, key press and collapse is reported back to the page. While it has a value it takes precedence over FirstPanelSize and SecondPanelSize. | | ReadOnly | `bool` | false | Keeps the splitter as it is: the gutter is still shown and still looks like itself, but it cannot be dragged or moved from the keyboard. | | SecondPanel | `RenderFragment?` | null | The content for the second panel. | | SecondPanelSize | `int?` | null | The initial size of the second panel in pixels. Ignored while Percent has a value, which is the case from the first drag on. | | SecondPanelMaxSize | `int?` | null | The max size of the second panel in pixels. | | SecondPanelMinSize | `int?` | null | The min size of the second panel in pixels. | | ShowCollapseButton | `bool` | false | Draws a fold/unfold button on the gutter of a Collapsible splitter. It is kept out of the tab order, since the gutter's keys do the same. | | SnapSize | `int` | 0 | How close, in pixels, to its edge a drag must leave the folding panel for it to snap shut. 0 uses half its minimum size, or a twentieth of the splitter without one. | | Styles | `BitSplitterClassStyles?` | null | Custom CSS styles for different parts of the BitSplitter. | | Vertical | `bool` | false | Sets the orientation of BitSplitter to vertical, stacking the two panels instead of placing them side by side. | | 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 | | :--- | :--- | :------------ | :---------- | | Collapse | `Task` | | Collapses the panel that folds. Does nothing if it is already collapsed. Not turned away by Collapsible, which is about what the reader may do to the gutter. | | Expand | `Task` | | Expands the panel that folds, putting the split back where it was before the fold. | | ToggleCollapse | `Task` | | Collapses the panel that folds if it is expanded and expands it if it is collapsed. | | SetPercent | `Task` | | Moves the split so that the first panel takes up the given share of the splitter, as a percentage between 0 and 100. The value is still held to the minimum and maximum sizes of both panels. | | GetPercent | `ValueTask<double?>` | | Measures the first panel's current share of the splitter - including a split nobody has moved yet, which Percent does not hold. Null before the splitter is set up or when it has no room. | | ResetSize | `Task` | | Clears Percent and hands the layout back to DefaultPercent, FirstPanelSize and SecondPanelSize - which is what a double-click on the gutter does. A Percent the page binds one way is not reset. | | FocusAsync | `ValueTask` | | Gives the focus to the gutter, which is the control a splitter is driven by. The overload taking a bool prevents the gutter from being scrolled into view. | | 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 ### BitSplitterCollapseReason Enum | Name | Value | Description | | :--- | :--- | :---------- | | Gutter | 0 | The gutter was pressed, or moved by the Enter key or Ctrl with an arrow key. | | Drag | 1 | The gutter was dragged close enough to the panel's own edge of the splitter for it to snap shut. | | Method | 2 | The Collapse, Expand or ToggleCollapse method of the splitter was called. | | Restore | 3 | The position the splitter had remembered under its PersistKey was restored. | ### 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 ### BitSplitterCollapseArgs Properties | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | IsCollapsing | `bool` | | The state the panel that folds is about to move to: true while it is being folded away, false while it is being brought back. | | Reason | `BitSplitterCollapseReason` | | What made the panel collapse or expand: the gutter, a drag that snapped it shut, a call to one of the Collapse, Expand and ToggleCollapse methods, or the remembered position being restored. | | Cancel | `bool` | false | Set to true to cancel the collapse or the expansion and leave the panel as it is. | ### BitSplitterClassStyles Properties | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | Root | `string?` | null | The custom CSS class/style for the root element of the BitSplitter. | | CollapseButton | `string?` | null | The custom CSS class/style for the collapse button on the gutter of the BitSplitter. | | CollapseButtonIcon | `string?` | null | The custom CSS class/style for the icon of the collapse button of the BitSplitter. | | FirstPanel | `string?` | null | The custom CSS class/style for the first panel of the BitSplitter. | | Gutter | `string?` | null | The custom CSS class/style for the gutter (the separator) of the BitSplitter. | | GutterIcon | `string?` | null | The custom CSS class/style for the icon rendered inside the gutter of the BitSplitter. | | GutterIndicator | `string?` | null | The custom CSS class/style for the default grip indicator rendered inside the gutter of the BitSplitter. | | Preview | `string?` | null | The custom CSS class/style for the line a lazy drag moves in place of the panels of the BitSplitter. | | SecondPanel | `string?` | null | The custom CSS class/style for the second panel of the BitSplitter. | ### BitIconInfo Properties | 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 built-in Fluent UI icons, this defaults to "bit-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 built-in Fluent UI icons, this defaults to "bit-icon--". 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-Splitter-gutter-size` | spacing(1.25) | Thickness of the gutter. GutterSize wins over it. | | `--bit-Splitter-gutter-hit-size` | spacing(3), spacing(5.5) for a coarse pointer | The smallest strip a press takes hold of the gutter in, reaching past a thinner gutter without taking room from the panels. GutterHitSize wins over it. | | `--bit-Splitter-gutter-background` | --bit-clr-brd-sec | The gutter at rest, and while it cannot be moved. | | `--bit-Splitter-gutter-hover-background` | --bit-clr-brd-pri | The gutter under the pointer. | | `--bit-Splitter-gutter-active-background` | The hover background | The gutter while it is being dragged. | | `--bit-Splitter-gutter-indicator-color` | --bit-clr-fg-sec | The default grip drawn on the gutter - what keeps a gutter at rest at 3:1 against its surroundings. | | `--bit-Splitter-gutter-icon-color` | --bit-clr-fg-sec | The icon GutterIcon or GutterIconName draws on the gutter. | | `--bit-Splitter-gutter-icon-size` | --bit-tg-fs-xs | Size of the icon drawn on the gutter. | | `--bit-Splitter-preview-background` | --bit-clr-pri | The line a LazyResize drag moves in place of the panels. | | `--bit-Splitter-collapse-button-color` | --bit-clr-fg-sec | The chevron of the collapse button. | | `--bit-Splitter-collapse-button-background` | --bit-clr-bg-pri | The collapse button at rest. | | `--bit-Splitter-collapse-button-border-color` | --bit-clr-brd-pri | The outline of the collapse button at rest. | | `--bit-Splitter-collapse-button-hover-color` | --bit-clr-pri-text | The chevron of the collapse button under the pointer. | | `--bit-Splitter-collapse-button-hover-background` | --bit-clr-pri | The collapse button and its outline under the pointer. | | `--bit-Splitter-collapse-button-radius` | --bit-shp-radius-full | Corner radius of the collapse button. | ## Examples \n**Basic**: ```razor
First panel

Once upon a time, stories wove connections between people, a symphony of voices crafting shared dreams.
Second panel

Each word carried meaning, each pause brought understanding. The spaces here are open for growth.
``` \n**Vertical**: ```razor
First panel
Second panel
``` \n**Size & limits**: ```razor
Starts at 200px, stays between 120px and 320px.
Never narrower than 100px.
Takes the rest, never under 30% (CSS).
Starts at 150px.
``` \n**Percent**: ```razor
First panel
Second panel
Starts at 30%, free to move, double-click to go back.
Second panel
``` ```csharp private double? percent = 30; private double PercentValue { get => percent ?? 50; set => percent = value; } ``` \n**Dragging**: ```razor
Stops every @dragStep pixels
@(lazyResize ? "A line moves first; the panels follow when you let go." : "The panels follow the pointer.")
``` ```csharp private double dragStep = 50; private bool lazyResize; ``` \n**Gutter**: ```razor
GutterSize
Second panel
A 1px hairline, grabbed anywhere within 16px
Second panel
GutterIconName
Second panel
GutterTemplate
Second panel
``` ```csharp private double gutterSize = 10; ``` \n**Collapsible**: ```razor
A panel that folds away
Collapsed: @isCollapsed
Folds only when dragged within 40px of the edge.
Second panel
A document that takes the whole splitter once the inspector is away
An inspector that folds to the end
``` ```csharp private bool isCollapsed; ``` \n**Collapse button**: ```razor
Press the chevron to fold this away.
Second panel
A stacked splitter folds upwards.
Second panel
CollapseIconName and ExpandIconName
An inspector with icons of its own
``` \n**Cancelling a collapse**: ```razor
Folds away only with permission
Second panel
@collapseLog
``` ```csharp private bool allowCollapse = true; private string collapseLog = "Nothing has been folded yet."; ``` \n**Events**: ```razor
First panel
Second panel
@resizeLog
Double-click the gutter
to split evenly.
``` ```csharp private string resizeLog = "No resize yet."; private double? evenPercent; ``` \n**Programmatic control**: ```razor 25% 50% 75% Toggle collapse Reset Focus the gutter Measure
First panel
Second panel
@(measured is null ? "Nothing has been measured yet." : $"The first panel takes up {measured:F1}% of the splitter.")
``` ```csharp private double? measured; private BitSplitter splitterRef = default!; ``` \n**Persistence**: ```razor
Where you left it
Second panel
``` \n**Read-only & disabled**: ```razor
Read-only
The gutter stays where it is.
Disabled
The whole splitter is dimmed.
``` \n**Nested**: ```razor
Sidebar
Editor
Preview
Terminal
``` \n**Accessibility**: ```razor Narrower Wider
In the folding panel
One arrow key moves the gutter 50px.
``` ```csharp private double? a11yPercent = 30; ``` \n**Cascading parameters**: ```razor
From the cascade
Second panel

No collapse button of its own
Second panel
Outside the cascade
Second panel
``` ```csharp private readonly BitSplitterParams[] splitterParams = [ new() { GutterSize = 12, Collapsible = true, ShowCollapseButton = true, CollapsedSize = 8, FirstPanelSize = 160, } ]; ``` \n**External Icons**: ```razor
First panel
"fa-solid fa-arrows-left-right"
First panel
BitIconInfo.Css("fa-solid fa-grip-vertical")
First panel
BitIconInfo.Fa("solid grip-lines-vertical")
First panel
GutterIcon=@@("bi bi-grip-vertical")
First panel
BitIconInfo.Bi("arrow-left-right")
``` \n**Style & Class**: ```razor
Style
Second panel
Class
Second panel
Styles
Second panel
Classes
Second panel
One splitter's Style
Hover and drag the gutter
Set on a wrapper,
the variables reach
every splitter inside it.
``` \n**RTL**: ```razor
پنل اول
پنل دوم
```