Menu


Splitter


The line between two panes that the reader drags, or moves with the arrow keys, to give one pane more room and the other less.

Customize the preview


Choices
Show
View

Files

Preview

Options


Splitter options
ChoiceValuesDefaultWhat it does
orientationsmbk-splitter--orientation-<value>verticalhorizontalvertical
Vertical is a line between two columns side by side, moved left and right. Horizontal is a line between two stacked panes, moved up and down.

Partssmbk-splitter__linesmbk-splitter__gripsmbk-splitter__icon

Examples


Usage

A message list beside the open message. Drag the line, or focus it and press Left or Right; Home and End give the list its smallest and largest width.

  • Brand review notes
  • New logo files
  • Invoice for October
  • Launch checklist

Brand review notes

From Ana Silva, today at 9:41

The new colors read well on both themes. Two things before we ship: the focus ring on the dark header needs more room, and the footer links should match the header's.

Stacked panes

A horizontal line between an editor and its output, moved with Up and Down.

Query

Pages published this month, newest first.

Results

14 pages, the newest published yesterday.

Sizing the pane after the line

The value measures the settings panel after the line, so dragging the line left makes the settings wider.

Preview

The page as a visitor sees it, at the width the settings leave it.

Settings

Title, description and the image shown when the page is shared.

Without the grip

The two halves of the line meet; the hit area is as wide as with the grip.

  • Brand review notes
  • New logo files
  • Invoice for October
  • Launch checklist

Brand review notes

From Ana Silva, today at 9:41

The new colors read well on both themes. Two things before we ship: the focus ring on the dark header needs more room, and the footer links should match the header's.

While dragged

The line turns brand and twice as thick, and the dots turn brand, so the change is not shown by color alone.

  • Brand review notes
  • New logo files
  • Invoice for October
  • Launch checklist

Brand review notes

From Ana Silva, today at 9:41

The new colors read well on both themes. Two things before we ship: the focus ring on the dark header needs more room, and the footer links should match the header's.

Disabled

The line in the disabled color and the dots without their pill. It cannot be focused or moved.

  • Brand review notes
  • New logo files
  • Invoice for October
  • Launch checklist

Brand review notes

From Ana Silva, today at 9:41

The new colors read well on both themes. Two things before we ship: the focus ring on the dark header needs more room, and the footer links should match the header's.

Guidelines


Purpose

The line between two panes that the reader moves to give one pane more room and the other less: a list and the item it opens, a preview and its settings, an editor and its output. The reader drags it, or focuses it and uses the arrow keys. It differs from the divider, which only separates two things and cannot be moved or focused.

When to use

  • Two panes whose best share of the space depends on the reader and the task, such as a wide preview with narrow settings, or the reverse.
  • A pane the reader often wants larger for a moment: a file list, a log, an inspector.

When not to use

  • Two parts of a page that always keep the same share. Use a fixed layout, with a divider between them if they need a line.
  • A choice between a few set sizes, such as compact and wide. Use a segmented control or a button that toggles the pane.
  • A phone, or any narrow space. The panes stack there, and the splitter is not shown.

Usage rules

Do

  • Give each pane a smallest size at which its content still works, and a largest that leaves the other pane usable.
  • Name the splitter for the pane it sizes.
  • Store the size where the reader expects it kept, and pass it back the next time.

Don't

  • Use a divider where the reader should be able to move the line; it cannot be focused or dragged.
  • Hide the grip on a splitter that is hard to notice, such as one between two panes of the same color.
  • Leave a splitter in a narrow layout; stack the panes instead.
  • Brand review notes
  • New logo files
  • Invoice for October
  • Launch checklist

Brand review notes

From Ana Silva, today at 9:41

The new colors read well on both themes. Two things before we ship: the focus ring on the dark header needs more room, and the footer links should match the header's.

Do

Name the splitter for the pane it sizes, and keep the grip where the two panes share a color.

  • Brand review notes
  • New logo files
  • Invoice for October
  • Launch checklist

Brand review notes

From Ana Silva, today at 9:41

The new colors read well on both themes. Two things before we ship: the focus ring on the dark header needs more room, and the footer links should match the header's.

Don't

A divider between two panes cannot be focused or dragged, so the reader cannot give either one more room.

Anatomy

  • The block: the hit area, 24 across and as long as the panes, a separator the reader can focus. Vertical is a line between two columns side by side; horizontal is a line between two stacked panes.
  • line: the line, in two halves, one either side of the grip. Without the grip the two halves meet.
  • grip: an optional raised pill in the middle of the line, holding icon, six dots. On unless turned off.

Behavior

The page owns the panes. The splitter keeps a value, the size in pixels of the pane it measures, and reports every change; the page sizes the pane from it, and the other pane takes the rest. By default the value measures the pane before the line (the left one in a left-to-right page, the upper one of two stacked panes); it can measure the pane after it instead. The splitter stops at the pane's smallest and largest sizes, whichever way it is moved. It does not remember its value: a page that wants the size kept stores it and passes it back.

Dragging with a mouse, a pen or a finger moves the line with the pointer. While it is dragged the line turns brand and twice as thick, and the grip's dots turn brand. Under the pointer the hit area takes a light fill and the line darkens. On a touch screen the hit area reaches 44 across without widening the gap between the panes.

Where the layout is narrow the splitter is not shown, which also takes it out of the Tab order; the page stacks its two panes there itself, under the same layout switch. A disabled splitter keeps its line, in the disabled color, with the grip's dots and no pill, and cannot be focused or moved.

Accessibility


What it does for you

  • It is a separator the reader can focus, with its orientation, its value, its smallest and largest values, and the value in words. A screen reader hears "separator", its name and how far the pane is between its smallest and largest size, as a percentage, unless the page gives other words.
  • A vertical line moves with Left and Right, which follow the line on the screen in a right-to-left page too; a horizontal line moves with Up and Down. Each press moves it 16 pixels unless the page sets another step. Home gives the pane its smallest size, End its largest.
  • Dragging is not the only way to move it: the keys do it too.
  • The focus ring is drawn around the whole hit area.
  • The hit area is at least 24 across, so a pointer does not need precision to grab it.

What you must do

  • Name it for the pane it sizes, such as "Resize settings panel", and point aria-controls at that pane's id.
  • A reader who uses a pointer and cannot drag needs another way, so a page where the size matters offers set sizes beside the panes, such as a button that widens a pane.
  • In hand-written markup, give it the separator role, a Tab stop, aria-orientation, aria-valuenow, aria-valuemin, aria-valuemax and a name, and move it with script; without script it is a line that does not move.

How to test

  • Tab to it: the focus ring shows around the whole hit area, in both themes and in a forced-color mode.
  • Press the arrow keys that follow the line, then Home and End: the pane grows, shrinks and stops at its smallest and largest sizes.
  • With a screen reader, it is read as a separator by its name, with its value as a percentage.
  • On a touch screen, the line is grabbed by a hit area 44 across.
  • Check that the page offers set sizes, such as a button that widens a pane, for a reader who cannot drag.

Keyboard

Splitter keys
KeyWhat it does
Tab
Moves focus to the splitter. It is not in the Tab order where the layout is narrow and the splitter is hidden, or when it is disabled.
Left ArroworRight Arrow
On a vertical line, moves it by one step, following the line on the screen in a right-to-left page too.
Up ArroworDown Arrow
On a horizontal line, moves it by one step.
Home
Gives the pane its smallest size.
End
Gives the pane its largest size.

Source


The files the splitter is made of. Its folder on GitHub (opens in a new tab) holds them with its wrapper and its document.

Stylesheet
splitter.css
/* smbk-splitter — Splitter. Figma "Splitter" 7117:70.
 * A handle between two panes: a hit area 24 across and as long as the panes, holding a line in two halves and,
 * between them, an optional grip, a raised pill with six dots. Dragging it, or the arrow keys, give one pane more
 * room; the wrapper keeps the value and the page sizes its panes from it. Under the pointer the hit area takes the
 * ghost fill and the line the strong border; while it is dragged the line turns brand and twice as thick, so the
 * change is not shown by color alone. Focus draws the system's ring around the hit area. Where the layout is narrow
 * the page stacks its panes and the splitter is not shown, which also takes it out of the Tab order. */

.smbk-splitter {
  box-sizing: border-box;
  position: relative;
  display: flex;
  flex: none;
  flex-direction: column;
  align-items: center;
  align-self: stretch;
  width: var(--smbk-size-control-xs);
  border-radius: var(--smbk-radius-control-xs);
  cursor: col-resize;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

.smbk-splitter--orientation-horizontal {
  flex-direction: row;
  width: auto;
  height: var(--smbk-size-control-xs);
  cursor: row-resize;
}

/* The line: two halves, one either side of the grip, meeting where there is none. */
.smbk-splitter__line {
  flex: 1 1 0;
  width: var(--smbk-border-width-hairline);
  background: var(--smbk-color-border-groove-top);
}

.smbk-splitter--orientation-horizontal .smbk-splitter__line {
  width: auto;
  height: var(--smbk-border-width-hairline);
}

.smbk-splitter__grip {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: var(--smbk-size-16);
  height: var(--smbk-size-24);
  border-radius: var(--smbk-radius-full);
  background: var(--smbk-color-surface-raised);
  box-shadow: var(--smbk-elevation-control);
}

.smbk-splitter--orientation-horizontal .smbk-splitter__grip {
  width: var(--smbk-size-24);
  height: var(--smbk-size-16);
}

.smbk-splitter__icon {
  font-size: var(--smbk-size-icon-sm);
  color: var(--smbk-color-icon-subtle);
}

/* ---- states: hover, focus, dragging, disabled ---- */

@media (hover: hover) {
  .smbk-splitter:not([aria-disabled='true']):hover {
    background: var(--smbk-color-action-ghost-background-hover);
  }

  .smbk-splitter:not([aria-disabled='true']):hover .smbk-splitter__line {
    background: var(--smbk-color-border-strong);
  }
}

.smbk-splitter:focus-visible {
  outline: var(--smbk-focus-ring-width) solid var(--smbk-color-border-focus);
  outline-offset: var(--smbk-focus-ring-offset);
}

.smbk-splitter[data-dragging]:not([aria-disabled='true']) {
  background: transparent;
}

.smbk-splitter[data-dragging]:not([aria-disabled='true']) .smbk-splitter__line {
  width: var(--smbk-border-width-emphasis);
  background: var(--smbk-color-border-brand);
}

.smbk-splitter--orientation-horizontal[data-dragging]:not([aria-disabled='true']) .smbk-splitter__line {
  width: auto;
  height: var(--smbk-border-width-emphasis);
}

.smbk-splitter[data-dragging]:not([aria-disabled='true']) .smbk-splitter__icon {
  color: var(--smbk-color-icon-brand);
}

.smbk-splitter[aria-disabled='true'] {
  cursor: default;
}

.smbk-splitter[aria-disabled='true'] .smbk-splitter__line {
  background: var(--smbk-color-border-control-disabled);
}

.smbk-splitter[aria-disabled='true'] .smbk-splitter__grip {
  background: transparent;
  box-shadow: none;
}

.smbk-splitter[aria-disabled='true'] .smbk-splitter__icon {
  color: var(--smbk-color-icon-disabled);
}

/* ---- touch: the hit area reaches the comfortable target without widening the gap between the panes ---- */

@media (pointer: coarse) {
  .smbk-splitter::before {
    content: '';
    position: absolute;
    inset-block: 0;
    inset-inline: calc((var(--smbk-size-control-xs) - var(--smbk-size-target-comfortable)) / 2);
  }

  .smbk-splitter--orientation-horizontal::before {
    inset-block: calc((var(--smbk-size-control-xs) - var(--smbk-size-target-comfortable)) / 2);
    inset-inline: 0;
  }
}

/* ---- narrow: the page stacks its panes, and the splitter is not shown ---- */

@container style(--smbk-layout: narrow) {
  .smbk-splitter {
    display: none;
  }
}

/* ---- forced colors: the line and the grip's edge in the text color ---- */

@media (forced-colors: active) {
  .smbk-splitter__line {
    forced-color-adjust: none;
    background: CanvasText;
  }

  .smbk-splitter__grip {
    border: var(--smbk-border-width-hairline) solid CanvasText;
  }

  .smbk-splitter[aria-disabled='true'] .smbk-splitter__line {
    background: GrayText;
  }

  .smbk-splitter:focus-visible {
    outline-color: CanvasText;
  }
}
Tokens it reads
Splitter tokens
Token and CSSValuePreviewFoundation
size.control.xs--smbk-size-control-xs24pxSize
radius.control.xs--smbk-radius-control-xs2pxRadius
border-width.hairline--smbk-border-width-hairline1pxBorder width
color.border.groove-top--smbk-color-border-groove-toplight: #c4cdd8dark: #00000066changes with themeColor
size.16--smbk-size-1616pxSize
size.24--smbk-size-2424pxSize
radius.full--smbk-radius-full9999pxRadius
color.surface.raised--smbk-color-surface-raisedlight: #f9fafbdark: #232527changes with themeColor
elevation.control--smbk-elevation-controllight: 0px 0px 1px 0px #373d430d, 0px 1px 2px 0px #373d431a, 0px 2px 4px 0px #373d430ddark: 0px 0px 1px 0px #0000001a, 0px 1px 2px 0px #00000026, 0px 2px 4px 0px #0000001aElevation
size.icon.sm--smbk-size-icon-sm16pxSize
color.icon.subtle--smbk-color-icon-subtlelight: #4e555edark: #c4cdd8changes with themeColor
color.action.ghost.background-hover--smbk-color-action-ghost-background-hoverlight: #373d4326dark: #606a754dchanges with themeColor
color.border.strong--smbk-color-border-stronglight: #9ba5b1dark: #373d43changes with themeColor
focus.ring.width--smbk-focus-ring-width2pxFocus
color.border.focus--smbk-color-border-focuslight: #cc0d0ddark: #f34336changes with themeColor
focus.ring.offset--smbk-focus-ring-offset2pxFocus
border-width.emphasis--smbk-border-width-emphasis2pxBorder width
color.border.brand--smbk-color-border-brand#cc0d0dColor
color.icon.brand--smbk-color-icon-brandlight: #cc0d0ddark: #fe7d6dchanges with themeColor
color.border.control-disabled--smbk-color-border-control-disabledlight: #c4cdd8dark: #606a75changes with themeColor
color.icon.disabled--smbk-color-icon-disabledlight: #9ba5b1dark: #606a75changes with themeColor
size.target.comfortable--smbk-size-target-comfortable44pxSize
Manifest
splitter.manifest.json
{
  "name": "splitter",
  "block": "smbk-splitter",
  "summary": "The line between two panes that the reader drags, or moves with the arrow keys, to give one pane more room and the other less.",
  "adapt": "css",
  "axes": {
    "orientation": {
      "values": [
        "vertical",
        "horizontal"
      ],
      "default": "vertical",
      "description": "Vertical is a line between two columns side by side, moved left and right. Horizontal is a line between two stacked panes, moved up and down."
    }
  },
  "flags": {},
  "parts": [
    "line",
    "grip",
    "icon"
  ],
  "figmaNodeId": "7117:70"
}