Skip to main content
Components
Collapse
pnpm add @winkintel/bootstrap-svelte
GitHub

Collapse

Bootstrap's collapse component built with Svelte 5. Toggle the visibility of content across your project with the Collapse component.


Experiment with the Collapse component by adjusting the props below:

Interactive Playground

Controls

Preview

Code

            
            <script>
    import { collapseAria } from '@winkintel/bootstrap-svelte';

    let isExpanded = $state(false);
</script>

<Button
    {@attach collapseAria({
        ariaControls: 'collapseExample',
        ariaExpanded: isExpanded
    })}
    colorVariant="primary"
    onclick={() => isExpanded = !isExpanded}>
    {isExpanded ? 'Collapse Content' : 'Expand Content'}
</Button>

<Collapse
  id="collapseExample"
  isExpanded={false}
  onCollapse={handleCollapse}
  onCollapsed={handleCollapsed}
  onExpand={handleExpand}
  onExpanded={handleExpanded}>
  This is the collapsible content...
</Collapse>
        

Event Log

  • No events logged

Click the button below to expand and collapse the collapsible content. The isExpanded prop controls the visibility of the content.

            
            <script>
    import { collapseAria } from '@winkintel/bootstrap-svelte';

    let isBasicExpanded = $state(false);
</script>

<Button
    {@attach collapseAria({
        ariaControls: 'basicExample',
        ariaExpanded: isBasicExpanded
    })}
    colorVariant="primary"
    isExpanded={isBasicExpanded}
    onclick={() => (isBasicExpanded = !isBasicExpanded)}>
    {isBasicExpanded ? 'Collapse Content' : 'Expand Content'}
</Button>

<Collapse id="basicExample" isExpanded={isBasicExpanded}>
    This is some placeholder content for a collapsible element.
    Click the button to toggle visibility.
</Collapse>
        

The Collapse component can collapse content horizontally instead of vertically by setting the isHorizontal prop to true.

            
            <script>
    import { collapseAria } from '@winkintel/bootstrap-svelte';

    let isHorizontalCollapsed = $state(false);
</script>

<Button
    {@attach collapseAria({
        ariaControls: 'horizontalExample',
        ariaExpanded: isHorizontalCollapsed
    })}
    colorVariant="primary"
    isExpanded={isHorizontalCollapsed}
    onclick={() => isHorizontalCollapsed = !isHorizontalCollapsed}>
    {isHorizontalCollapsed ? 'Collapse Content' : 'Expand Content'}
</Button>

<div class="p-4">
    <Collapse id="horizontalExample" isExpanded={isHorizontalCollapsed} isHorizontal={true}>
        <div style="width: 300px;">
            This content collapses horizontally instead of vertically.
        </div>
    </Collapse>
</div>
        

A button can expand and collapse multiple collapsible elements by controlling the isExpanded prop of multiple Collapse components.

            
            <script>
    import { collapseAria } from '@winkintel/bootstrap-svelte';

    let isMultiCollapseExpanded1 = $state(false);
    let isMultiCollapseExpanded2 = $state(false);

    function toggleMultiCollapse(target: string) {
        if (target === 'multiCollapse1') {
            isMultiCollapseExpanded1 = !isMultiCollapseExpanded1;
        } else if (target === 'multiCollapse2') {
            isMultiCollapseExpanded2 = !isMultiCollapseExpanded2;
        } else if (target === 'both') {
            isMultiCollapseExpanded1 = !isMultiCollapseExpanded1;
            isMultiCollapseExpanded2 = !isMultiCollapseExpanded2;
        }
    }
</script>

<p>
    <Button
        {@attach collapseAria({
            ariaControls: 'multiCollapse1',
            ariaExpanded: isMultiCollapseExpanded1
        })}
        colorVariant="primary"
        onclick={() => toggleMultiCollapse('multiCollapse1')}>
        Toggle First Element
    </Button>
    <Button
        {@attach collapseAria({
            ariaControls: 'multiCollapse2',
            ariaExpanded: isMultiCollapseExpanded2
        })}
        colorVariant="secondary"
        onclick={() => toggleMultiCollapse('multiCollapse2')}>
        Toggle Second Element
    </Button>
    <Button
        {@attach collapseAria({
            ariaControls: 'multiCollapse1 multiCollapse2',
            ariaExpanded: isMultiCollapseExpanded1 && isMultiCollapseExpanded2
        })}
        colorVariant="info"
        onclick={() => toggleMultiCollapse('both')}>
        Toggle Both Elements
    </Button>
</p>

<div class="row">
    <div class="col">
        <Collapse id="multiCollapse1" isExpanded={isMultiCollapseExpanded1}>
            <div class="card card-body">
            First collapsible element content
            </div>
        </Collapse>
    </div>
    <div class="col">
        <Collapse id="multiCollapse2" isExpanded={isMultiCollapseExpanded2}>
            <div class="card card-body">
            Second collapsible element content
            </div>
        </Collapse>
    </div>
</div>
        

The Collapse component emits events when it shows and hides. You can attach event handlers with the onExpand, onExpanded, onCollapse, and onCollapsed props.

Event Log

  • No events logged
            
            <script>
    import { collapseAria } from '@winkintel/bootstrap-svelte';

    let isEventsExpanded = $state(false);
</script>

<Button
    {@attach collapseAria({
        ariaControls: 'eventsExample',
        ariaExpanded: isEventsExpanded
    })}
    colorVariant="primary"
    onclick={() => isEventsExpanded = !isEventsExpanded}>
    {isEventsExpanded ? 'Collapse Content' : 'Expand Content'}
</Button>

<Collapse
    id="eventsExample"
    isExpanded={isEventsExpanded}
    onExpand={e => console.log('onExpand event fired', e)}
    onExpanded={e => console.log('onExpanded event fired', e)}
    onCollapse={e => console.log('onCollapse event fired', e)}
    onCollapsed={e => console.log('onCollapsed event fired', e)}>
    <div class="card card-body">
        This collapse component has event handlers attached.
        Check the console to see the events as they fire.
    </div>
</Collapse>
        

Be sure to add aria-expanded to the control element. This attribute explicitly conveys the current state of the collapsible element tied to the control to screen readers and similar assistive technologies. If the collapsible element is closed by default, the attribute on the control element should have a value of aria-expanded="false". If you’ve set the collapsible element to be open by default using the show class, set aria-expanded="true" on the control instead.

The control element that targets the collapsible element should add the aria-controls attribute to the control element, containing the id of the collapsible element. Multiple collapsible elements are simply space delimited. Modern screen readers and similar assistive technologies make use of this attribute to provide users with additional shortcuts to navigate directly to the collapsible element itself.

The Collapse component provides a collapseAria attachment to easily add the necessary ARIA attributes to any control element. See the examples above for usage details.

Scrollspy Attachment

The collapseAria function creates an attachment that can be applied to an element with the {@attach ...} directive.

            
            // Type definition for CollapseAriaOptions
export type CollapseAriaOptions = {
    ariaControls: string;
    ariaExpanded: boolean;
};

// Usage example
<Button
    {@attach collapseAria({
        ariaControls: 'collapseExample',    // Single or space delimited list of the Collapse component IDs being controlled
        ariaExpanded: isExpanded            // Boolean indicating if the Collapse component is expanded (true) or collapsed (false)
    })}
    colorVariant="primary"
    onclick={() => isExpanded = !isExpanded}>
    {isExpanded ? 'Collapse Content' : 'Expand Content'}
</Button>
        

Props

NameTypeDefaultDescription
classstringundefinedAdditional CSS classes to apply to the component.
elementRefHTMLElement | nullnullReference to the DOM element
isHorizontalbooleanfalseMakes the collapse transition horizontally instead of vertically.
isExpandedbooleanfalseControls whether the collapse content is visible.

Events

NameTypeDescription
onExpandEventListenerFired when the collapse is about to expand (at the start of the transition).
onExpandedEventListenerFired when the collapse has been fully expanded (after the transition is complete).
onCollapseEventListenerFired when the collapse is about to collapse (at the start of the transition).
onCollapsedEventListenerFired when the collapse has been fully collapsed (after the transition is complete).

CSS Classes

The component applies Bootstrap's collapse classes based on the provided props:

  • collapse - Always applied as the base class
  • collapse-horizontal - Applied when isHorizontal is true
  • show - Applied when isExpanded is true