Split Panel
<wa-split-panel>
Split panels display two adjacent panels, allowing the user to reposition them.
<wa-split-panel> <div slot="start" style="height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden;" > Start </div> <div slot="end" style="height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden;" > End </div> </wa-split-panel>
Examples
Jump to heading
Initial Position
Jump to heading
To set the initial position, use the position attribute. If no position is provided, it will default to 50% of the available space.
<wa-split-panel position="75"> <div slot="start" style=" height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden; " > Start </div> <div slot="end" style=" height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden; " > End </div> </wa-split-panel>
Initial Position in Pixels
Jump to heading
To set the initial position in pixels instead of a percentage, use the position-in-pixels attribute.
<wa-split-panel position-in-pixels="150"> <div slot="start" style="height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden;" > Start </div> <div slot="end" style="height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden;" > End </div> </wa-split-panel>
Orientation
Jump to heading
Set the orientation attribute to vertical and provide a height to render the split panel in a vertical orientation where the start and end panels are stacked.
<wa-split-panel orientation="vertical" style="height: 400px;"> <div slot="start" style="height: 100%; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden;" > Start </div> <div slot="end" style="height: 100%; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden;" > End </div> </wa-split-panel>
Snapping
Jump to heading
To snap panels at specific positions while dragging, add the snap attribute with one or more space-separated values. Values must be in pixels or percentages. For example, to snap the panel at 100px and 50%, use snap="100px 50%". You can also customize how close the divider must be before snapping with the snap-threshold attribute.
<div class="split-panel-snapping"> <wa-split-panel snap="100px 50%"> <div slot="start" style="height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden;" > Start </div> <div slot="end" style="height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden;" > End </div> </wa-split-panel> <div class="split-panel-snapping-dots"></div> </div> <style> .split-panel-snapping { position: relative; } .split-panel-snapping-dots::before, .split-panel-snapping-dots::after { content: ''; position: absolute; bottom: -12px; width: 6px; height: 6px; border-radius: 50%; background: var(--wa-color-neutral-fill-loud); transform: translateX(-3px); } .split-panel-snapping-dots::before { left: 100px; } .split-panel-snapping-dots::after { left: 50%; } </style>
Disabled
Jump to heading
Add the disabled attribute to prevent the divider from being repositioned.
<wa-split-panel disabled> <div slot="start" style="height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden;" > Start </div> <div slot="end" style="height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden;" > End </div> </wa-split-panel>
Setting the Primary Panel
Jump to heading
By default, both panels will grow or shrink proportionally when the host element is resized. If a primary panel is designated, it will maintain its size and the secondary panel will grow or shrink to fit the remaining space. You can set the primary panel to start or end using the primary attribute.
Try resizing the example below with each option and notice how the panels respond.
<div class="split-panel-primary"> <wa-split-panel> <div slot="start" style="height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden;" > Start </div> <div slot="end" style="height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden;" > End </div> </wa-split-panel> <wa-select label="Primary Panel" value="" style="max-width: 200px; margin-top: 1rem;"> <wa-option value="">None</wa-option> <wa-option value="start">Start</wa-option> <wa-option value="end">End</wa-option> </wa-select> </div> <script> const container = document.querySelector('.split-panel-primary'); const splitPanel = container.querySelector('wa-split-panel'); const select = container.querySelector('wa-select'); select.addEventListener('change', () => (splitPanel.primary = select.value)); </script>
Min & Max
Jump to heading
To set a minimum or maximum size of the primary panel, use the --min and --max custom properties. Since the secondary panel is flexible, size constraints can only be applied to the primary panel. If no primary panel is designated, these constraints will be applied to the start panel.
This examples demonstrates how you can ensure both panels are at least 150px using --min, --max, and the calc() function.
<wa-split-panel style="--min: 150px; --max: calc(100% - 150px);"> <div slot="start" style="height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden;" > Start </div> <div slot="end" style="height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden;" > End </div> </wa-split-panel>
Nested Split Panels
Jump to heading
Create complex layouts that can be repositioned independently by nesting split panels.
<wa-split-panel> <div slot="start" style="height: 400px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden" > Start </div> <div slot="end"> <wa-split-panel orientation="vertical" style="height: 400px;"> <div slot="start" style="height: 100%; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden" > Top </div> <div slot="end" style="height: 100%; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden" > Bottom </div> </wa-split-panel> </div> </wa-split-panel>
Customizing the Divider
Jump to heading
You can target the divider part to apply CSS properties to the divider. To add a custom handle, slot an icon into the divider slot. When customizing the divider, make sure to think about focus styles for keyboard users.
<wa-split-panel style="--divider-width: 20px;"> <wa-icon slot="divider" name="grip-vertical" variant="solid"></wa-icon> <div slot="start" style=" height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden; " > Start </div> <div slot="end" style=" height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden; " > End </div> </wa-split-panel>
Here's a more elaborate example that changes the divider's color and width and adds a styled handle.
<div class="split-panel-divider"> <wa-split-panel> <wa-icon slot="divider" name="grip-vertical" variant="solid"></wa-icon> <div slot="start" style=" height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden; " > Start </div> <div slot="end" style=" height: 200px; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden; " > End </div> </wa-split-panel> </div> <style> .split-panel-divider wa-split-panel { --divider-width: 4px; } .split-panel-divider wa-split-panel::part(divider) { background-color: var(--wa-color-red-50); } .split-panel-divider wa-icon { position: absolute; border-radius: var(--wa-border-radius-l); background: var(--wa-color-red-50); color: white; padding: 0.5rem 0.25rem; } .split-panel-divider wa-split-panel::part(divider):focus-visible { background-color: var(--wa-color-blue-50); } .split-panel-divider wa-split-panel:focus-within wa-icon { background-color: var(--wa-color-blue-50); color: white; } </style>
Slots
Jump to heading
Learn more about using slots.
| Name | Description |
|---|---|
start
|
Content to place in the start panel. |
end
|
Content to place in the end panel. |
divider
|
The divider. Useful for slotting in a custom icon that renders as a handle. |
Attributes & Properties
Jump to heading
Learn more about attributes and properties.
| Name | Description | Reflects | |
|---|---|---|---|
positionposition |
The current position of the divider from the primary panel's edge as a percentage 0-100. Defaults to 50% of the
container's initial size.
Type
numberDefault
50 |
|
|
positionInPixelsposition-in-pixels |
The current position of the divider from the primary panel's edge in pixels.
Type
number |
||
orientationorientation |
Sets the split panel's orientation.
Type
'horizontal' | 'vertical'Default
'horizontal' |
|
|
disableddisabled |
Disables resizing. Note that the position may still change as a result of resizing the host element.
Type
booleanDefault
false |
|
|
primaryprimary |
If no primary panel is designated, both panels will resize proportionally when the host element is resized. If a
primary panel is designated, it will maintain its size and the other panel will grow or shrink as needed when the
host element is resized.
Type
'start' | 'end' | undefined |
||
snapsnap |
One or more space-separated values at which the divider should snap. Values can be in pixels or percentages, e.g.
"100px 50%".Type
string | undefined |
||
snapThresholdsnap-threshold |
How close the divider must be to a snap point until snapping occurs.
Type
numberDefault
12 |
Events
Jump to heading
Learn more about events.
| Name | Description |
|---|---|
wa-reposition |
Emitted when the divider's position changes. |
CSS custom properties
Jump to heading
Learn more about CSS custom properties.
| Name | Description |
|---|---|
--divider-width |
The width of the visible divider.
Default
4px
|
--divider-hit-area |
The invisible region around the divider where dragging can occur. This is usually wider than the divider to facilitate easier dragging.
Default
12px
|
--min |
The minimum allowed size of the primary panel.
Default
0
|
--max |
The maximum allowed size of the primary panel.
Default
100%
|
CSS parts
Jump to heading
Learn more about CSS parts.
| Name | Description | CSS selector |
|---|---|---|
start |
The start panel. |
::part(start)
|
end |
The end panel. |
::part(end)
|
panel |
Targets both the start and end panels. |
::part(panel)
|
divider |
The divider that separates the start and end panels. |
::part(divider)
|
Importing
Jump to heading
Autoloading components via projects is the recommended way to import components. If you prefer to do it manually, use one of the following code snippets.
Let your project code do the work! Sign up for free to use a project with your very own CDN — it's the fastest and easiest way to use Web Awesome.
To manually import this component from NPM, use the following code.
import '@awesome.me/webawesome/dist/components/split-panel/split-panel.js';
To manually import this component from React, use the following code.
import WaSplitPanel from '@awesome.me/webawesome/dist/react/split-panel';