Skip to content

Surfaces

Collapse

Bit.BlazorUICollapsibleDisclosure

Collapse is the container that opens and closes a section of a page. It renders no trigger of its own, so anything can drive it - a button, a switch, a link, a piece of state - and one trigger can drive several sections at once. It animates the real size of its content rather than a guessed maximum, downwards or sideways, all the way or down to a peek that keeps the first few lines readable. The pace of the transition - one for each direction if they differ - the padding, the background and the fade are all parameters, the start and the end of each transition are reported back, the closed content is taken out of the tab order and the accessibility tree, and it can still be reached by find-in-page. Content that is expensive to build can be kept out of the DOM until the section is opened, or dropped again once it is closed.

Notes

The expand and collapse transition is motion, so it honors the reduced motion preference of the OS/browser (prefers-reduced-motion) by finishing at once instead of animating. If nothing on this page is animating, either turn the reduce motion setting off, use the ForceAnimation parameter, or turn on the ForceAnimation toggle at the top of this page. An explicit Duration - or ExpandDuration / CollapseDuration, or Delay - retunes the pace but is collapsed by the preference all the same: ForceAnimation is the one thing that opts out of it.

Usage

Every example is live. Open its code to see exactly what produced the component running underneath.

Basic

Expanded is the whole of the basic component: while it is true the content is on the page at its natural size, and while it is false the section is closed. The collapse draws no header and no chevron, so whatever flips that value - here a toggle button - lives on the page beside it, which is what lets a single trigger open several sections at once or several triggers open the same one.

The size is animated by the content itself rather than by a maximum height set in advance, so a section whose content grows, wraps or loads late still opens exactly as far as it needs to.


In the beginning, there is silence a blank canvas yearning to be filled, a quiet space where creativity waits to awaken. These words are temporary, standing in place of ideas yet to come, a glimpse into the infinite possibilities that lie ahead. Think of this text as a bridge, connecting the empty spaces of now with the vibrant narratives of tomorrow. It whispers of the stories waiting to be told, of the thoughts yet to be shaped into meaning, and the emotions ready to resonate with every reader.
In this space, potential reigns supreme. It is a moment suspended in time, where imagination dances freely and each word has the power to transform into something extraordinary. Here lies the start of something new-an opportunity to craft, inspire, and create. Whether it's a tale of adventure, a reflection of truth, or an idea that sparks change, these lines are yours to fill, to shape, and to make uniquely yours. The journey begins here, in this quiet moment where everything is possible.

Binding & control

There are three ways to drive a collapse, and they can be mixed. @bind-Expanded keeps the state on the page and lets the component write back to it; DefaultExpanded hands the state to the component for a section that only has to remember whether it is open; and the ToggleAsync, ExpandAsync and CollapseAsync methods drive it from code through a component reference. OnChange reports the changes the component itself makes, which is every change but the ones the page makes by assigning to Expanded.

A disabled collapse (IsEnabled="false") keeps whatever state it is in: the three methods above turn into no-ops rather than toggling it.


Two-way binding

The button above and the collapse share one value, so either of them can change it and both of them see it.

The bound value is currently True.



Uncontrolled with DefaultExpanded

This section starts open because DefaultExpanded is set, and nothing on the page holds its state.




Driving it from code

ExpandAsync, CollapseAsync and ToggleAsync go through the same path a bound value does, so the change is reported once through both ExpandedChanged and OnChange.

Horizontal

Horizontal turns the transition a quarter, so the section opens sideways along the inline axis instead of downwards. A horizontal collapse takes the width of its content rather than the full width of its container, and it opens from the start edge, which follows the direction of the page - so the same markup opens to the right in a left-to-right page and to the left in a right-to-left one.

This is what a collapsing sidebar, a search field that grows out of its icon, or a row of actions that slides out of a toolbar is made of.


This panel opens sideways.

Collapsed size

CollapsedSize is the size the section keeps while it is closed, as any CSS length. Instead of closing all the way it leaves a peek of the content on the page, which is exactly what a "show more" clamp is: the first few lines stay readable and the rest of them animate in.

Because a peek is still on the screen, a collapse that keeps one never fades out, is neither hidden from assistive technology nor taken out of the tab order while it is closed, and ignores the rendering parameters below - there would be nothing left in the peek to read, and nothing left to search. The value is the size of the closed section, padding included, and on a Horizontal collapse it is a width rather than a height.


In the beginning, there is silence a blank canvas yearning to be filled, a quiet space where creativity waits to awaken. These words are temporary, standing in place of ideas yet to come, a glimpse into the infinite possibilities that lie ahead. Think of this text as a bridge, connecting the empty spaces of now with the vibrant narratives of tomorrow. It whispers of the stories waiting to be told, of the thoughts yet to be shaped into meaning, and the emotions ready to resonate with every reader.
In this space, potential reigns supreme. It is a moment suspended in time, where imagination dances freely and each word has the power to transform into something extraordinary. Here lies the start of something new-an opportunity to craft, inspire, and create.

Transition

Duration, Delay and Easing retune the transition: milliseconds for the first two, any CSS timing function for the third. Leaving them unset keeps the pace of the motion theme. Either way the transition still collapses to nothing when the reader asks for reduced motion: the pace is a matter of design and the preference is not, so ForceAnimation is what a collapse whose motion carries meaning opts out with.

ExpandDuration and CollapseDuration override Duration in one direction each, for a section that opens deliberately and gets out of the way quickly - or the other way around. Whichever of them applies is also what the callbacks and the deferred behaviors below wait for.

NoFade takes the opacity out of the transition and leaves the size to do the work on its own, and NoAnimation takes the transition out altogether, so the section appears and disappears at once.


Slow, with a delay and a custom easing

A thousand milliseconds after a two hundred millisecond wait, on an easing that overshoots at both ends.



A pace for each direction

Nine hundred milliseconds to open, two hundred to close.



NoFade

The size opens and closes this section; the content never changes its opacity.



NoAnimation

There is no transition here at all, which is what a section that toggles as part of a larger change wants.

Transition events

Four callbacks bracket a change of state. OnExpanding and OnCollapsing fire as the transition starts - where a page loads what the section is about to show, or saves what it is about to put away - and OnExpanded and OnCollapsed fire at the end of it, the moment the content has reached its full size or finished leaving the screen, which is where a page scrolls the opened section into view, measures it, moves focus into it, or lets go of what the closed one was holding. All four report every change, whoever made it; OnChange, in contrast, lands the instant the state flips and only for the changes the component itself makes.

The end of the transition is a clock rather than an event from the browser, and it is timed off the duration that applies to the direction being played - so a collapse whose pace is retuned in CSS rather than through the parameters is better off setting them to the same value, and a reader who has asked for reduced motion, whose transition finished at once, still waits it out. A collapse with NoAnimation reports the start and the end together, and one that simply starts open or closed reports nothing at all: the state it begins in is not something it transitioned into.


OnChange and the -ing callback land as soon as the button is pressed; the -ed one arrives six hundred milliseconds later, when this section has stopped moving.

Padding & background

The collapse puts padding around its content so text never meets the edges of the section, and paints the primary background so nothing shows through it. NoPadding removes the first, which is what content that draws its own insets - a list, a card, an image that meets the container edge to edge - wants, and Background changes the second, with BitColorKind.Transparent letting the surface underneath through.




Default
The padding and the primary background of the component.

Secondary background
A background of the secondary color kind.

Transparent background, no padding
Content that carries its own surface and its own insets.

Overflow

The collapse clips whatever reaches past the edges of its content, which is what makes the transition read as a section opening rather than as content sliding over the page. Once the section has finished opening there is nothing left to clip and the clipping starts costing instead: a focus ring, a shadow, or a menu dropping out of a control inside it is cut off at the edge of the box.

NoClip takes the clipping off at the end of the expand transition and puts it back the moment the collapse starts closing, so the animation is unchanged and only the section that has stopped moving stops cutting things off. Like the callbacks above, it is timed off the duration of the transition.




Default
The glow around this card is cut off at the edge of the collapse.


NoClip
The same glow is drawn in full once the section has finished opening.

Rendering

By default the content of a collapse is rendered whether the section is open or not, which keeps whatever it holds - the position of a scroll, the text in a field, the frame of a video - across a close and a reopen. Two parameters trade that away for the work it costs.

LazyRender keeps the content out of the DOM until the section is expanded for the first time, so nothing inside a page full of closed sections is built, queried or measured until it is opened. UnmountOnCollapse takes it back out once the section has closed - after the transition has had time to finish, so the close still animates - and builds it again from scratch on the next open, which means anything it was holding starts over. Neither applies to a collapse that keeps a CollapsedSize or that is searchable through HiddenUntilFound: there has to be something left to show, or something left to find.


LazyRender




UnmountOnCollapse

Find in page

Text a reader cannot see is text the browser will not find, which is what makes a page of collapsed sections frustrating to search. HiddenUntilFound hands the closed content to the browser as hidden="until-found" instead: find-in-page and a navigation to a fragment inside the section reach into it, and the component answers by opening the section around the match and reporting the change through ExpandedChanged and OnChange, exactly as if the trigger had been pressed.

The attribute is only applied once the close has finished, so the collapse still animates shut, and the content has to stay in the DOM to be found at all - which is why such a collapse ignores LazyRender and UnmountOnCollapse. A browser that does not know the value simply hides the closed content, which is what a closed section looks like anyway; only the searching is lost.

Opening the section is the whole point, so a collapse that cannot open is not offered to find-in-page: a disabled one never is, and one whose Expanded is set one way, with no @bind-Expanded or ExpandedChanged to write back to, gives up on it the first time a match asks it to open and it cannot. Either way the content goes back to being hidden the ordinary way, out of the tab order and out of the accessibility tree.


The passphrase kept in this section is marmalade skies. Close the section, press Ctrl+F, search for it, and watch the browser open the collapse around the match.

Accessibility

A closed collapse is taken out of the tab order and out of the accessibility tree, so a link or a field inside it can never be reached by a keyboard or announced by a screen reader while the section is shut. What the component cannot do on its own is wire up the trigger, because the trigger is not part of it: a disclosure is a button carrying aria-expanded and aria-controls beside the section it opens.

ContentId is the id of the content element - the id of the root with -content after it - which is what aria-controls has to point at, and it can be read off a component reference for a collapse that was left to generate its own id. LabelledBy names the region from an element on the page - the trigger itself, or the heading above it - which is what turns the section into a landmark a screen reader can jump to, and AriaLabel names it from a string where no such element exists. Role overrides the default region role; set it to an empty string for content that already carries semantics of its own.

The open section is itself a tab stop, so a reader tabbing past the trigger lands on the region rather than in the middle of its content; TabIndex moves where that stop sits, and FocusAsync puts the focus there from code - paired with OnExpanded, at the moment the section has finished opening.


Orders placed before 2 pm ship the same day. Read the full policy.



Moving the focus into the section

The focus ring around this section was put here by FocusAsync at the end of the expand transition, so the reader carries on inside the section rather than back at the button.

Style & Class

Empower customization by overriding default styles and classes, allowing tailored design modifications to suit specific UI requirements. Style and Class land on the root element, while Styles and Classes reach each part of the component separately: Root, the Expanded and Collapsed states of the root, the Content region that fades and clips, and the Wrapper that carries the padding.




In the beginning, there is silence a blank canvas yearning to be filled, a quiet space where creativity waits to awaken. These words are temporary, standing in place of ideas yet to come, a glimpse into the infinite possibilities that lie ahead. Think of this text as a bridge, connecting the empty spaces of now with the vibrant narratives of tomorrow.






In this space, potential reigns supreme. It is a moment suspended in time, where imagination dances freely and each word has the power to transform into something extraordinary. Here lies the start of something new-an opportunity to craft, inspire, and create.

RTL

Use BitCollapse in right-to-left (RTL). A vertical collapse is unchanged by the direction of the page, while a horizontal one opens from the start edge, which in an RTL page is the right one.


لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد.



این بخش به سمت راست باز می شود.

API

Every parameter, public member, sub-class and enum this component exposes.

BitCollapse parameters

Name Type Default value Description
Background BitColorKind? null The color kind of the background of the collapse.
Body RenderFragment? null Alias for the ChildContent parameter.
ChildContent RenderFragment? null The content of the collapse.
Classes BitCollapseClassStyles? null Custom CSS classes for different parts of the collapse.
CollapseDuration int? null The duration of the collapse transition in ms, which overrides Duration while the collapse is closing and leaves the opening alone.
CollapsedSize string? null The size the collapse keeps while it is collapsed, as any CSS length, which leaves a peek of the content on the page instead of closing it all the way. It is a width instead of a height while Horizontal is on.
DefaultExpanded bool? null The default value of the Expanded parameter, applied once at initialization and only while Expanded itself has not been set.
Delay int? null The delay of the expand/collapse transition in ms.
Duration int? null The duration of the expand/collapse transition in ms. Leaving it unset keeps the duration of the motion theme. A value set here is still collapsed to nothing by the reduced motion preference, which only ForceAnimation opts out of. It is what OnExpanded, OnCollapsed, NoClip, HiddenUntilFound and UnmountOnCollapse wait for.
Easing string? null The timing function of the expand/collapse transition, as any CSS easing value.
ExpandDuration int? null The duration of the expand transition in ms, which overrides Duration while the collapse is opening and leaves the closing alone.
Expanded bool false Determines whether the collapse is expanded or collapsed.
ExpandedChanged EventCallback<bool> The callback of the two-way binding of the Expanded parameter, raised with the new state.
HiddenUntilFound bool false Hands the closed content to the browser as hidden="until-found", so find-in-page and a navigation to a fragment inside the section reach into it and open it. Such a collapse ignores LazyRender and UnmountOnCollapse, since the content has to stay in the DOM to be found, and one that cannot open - disabled, or with a one-way Expanded - is not offered to find-in-page at all.
Horizontal bool false Collapses the content along the inline axis instead of the block one, so it opens sideways from the start edge.
LabelledBy string? null The id of the element that names the content region of the collapse, rendered as aria-labelledby.
LazyRender bool false Keeps the content out of the DOM until the collapse is expanded for the first time. A collapse that keeps a CollapsedSize or is searchable through HiddenUntilFound ignores it.
NoAnimation bool false Removes the expand/collapse transition, so the content appears and disappears at once.
NoClip bool false Stops clipping the content once the collapse has finished opening, so a focus ring, a shadow or a menu that reaches past the edges of the section is drawn in full. The clipping is put back the moment the collapse starts closing.
NoFade bool false Removes the fade of the content, leaving the size on its own to open and close the collapse.
NoPadding bool false Removes the padding the collapse puts around its content.
OnChange EventCallback<bool> Callback that is called when the Expanded value has changed by the component itself.
OnCollapsed EventCallback Callback that is called once the collapse has finished closing, which is the end of the collapse transition.
OnCollapsing EventCallback Callback that is called as the collapse starts closing, which is the start of the collapse transition.
OnExpanded EventCallback Callback that is called once the collapse has finished opening, which is the end of the expand transition.
OnExpanding EventCallback Callback that is called as the collapse starts opening, which is the start of the expand transition.
Role string? null The ARIA role of the content region of the collapse, which is region by default. An empty string renders no role at all.
Styles BitCollapseClassStyles? null Custom CSS styles for different parts of the collapse.
UnmountOnCollapse bool false Takes the content back out of the DOM once the collapse has closed, after the transition has had time to finish. A collapse that keeps a CollapsedSize or is searchable through HiddenUntilFound ignores it.

BitCollapse public members

Name Type Default value Description
ContentId string The id of the content element of the collapse, which is the id of the root element with -content after it, so a trigger elsewhere on the page can point its aria-controls at the section it opens.
CollapseAsync Task Collapses the collapse, reporting the change through ExpandedChanged and OnChange.
ExpandAsync Task Expands the collapse, reporting the change through ExpandedChanged and OnChange.
FocusAsync ValueTask Moves the focus to the content region of the collapse, which is worth pairing with OnExpanded so the focus lands once the section has finished opening.
ToggleAsync Task Flips the collapse between expanded and collapsed, reporting the change through ExpandedChanged and OnChange.

BitComponentBase parameters

Name Type Default value Description
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.
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.
Id string? null Gets or sets the unique identifier for the component's root element.
IsEnabled bool true Gets or sets a value indicating whether the component is enabled and can respond to user interaction.
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.

BitComponentBase public members

Name Type Default value Description
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.

BitCollapseClassStyles properties

Name Type Default value Description
Root string? null Custom CSS classes/styles for the root element of the BitCollapse.
Expanded string? null Custom CSS classes/styles for the root element of the BitCollapse in the expanded state.
Collapsed string? null Custom CSS classes/styles for the root element of the BitCollapse in the collapsed state.
Content string? null Custom CSS classes/styles for the content region of the BitCollapse, which is the element that fades between the two states and clips what is outside the collapsed size.
Wrapper string? null Custom CSS classes/styles for the wrapper the BitCollapse puts around its content, which is the element that carries the padding.

BitColorKind enum

Name Value Description
Primary 0 The primary color kind.
Secondary 1 The secondary color kind.
Tertiary 2 The tertiary color kind.
Transparent 3 The transparent color kind.

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.

Feedback

Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.