Skip to content

Split ​

Split divides a container into multiple resizable areas and supports horizontal, vertical, collapsible, and lazy update layouts.

Basic Usage ​

When size is not specified, the remaining space is automatically distributed across unspecified panels.

Navigation
Content
<template>
  <b-split class="split-demo">
    <b-split-panel size="30%">
      <div class="split-panel is-soft">Navigation</div>
    </b-split-panel>
    <b-split-panel :min="220">
      <div class="split-panel is-warm">Content</div>
    </b-split-panel>
  </b-split>
</template>

<style scoped>
.split-demo {
  height: 280px;
  border: 1px solid #e8edf4;
  border-radius: 14px;
  background: #fff;
}

.split-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 15px;
  font-weight: 600;
  color: #31415c;
}

.split-panel.is-soft {
  background: linear-gradient(135deg, #f7fbff 0%, #eef5ff 100%);
}

.split-panel.is-warm {
  background: linear-gradient(135deg, #fffaf2 0%, #fff3df 100%);
}
</style>

Vertical Layout ​

Use layout="vertical" to switch to a top-bottom layout.

Top Area
Bottom Area
<template>
  <b-split class="split-demo" layout="vertical">
    <b-split-panel size="38%">
      <div class="split-panel is-soft">Top Area</div>
    </b-split-panel>
    <b-split-panel :min="120">
      <div class="split-panel is-cool">Bottom Area</div>
    </b-split-panel>
  </b-split>
</template>

<style scoped>
.split-demo {
  height: 280px;
  border: 1px solid #e8edf4;
  border-radius: 14px;
  background: #fff;
}

.split-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 15px;
  font-weight: 600;
  color: #31415c;
}

.split-panel.is-soft {
  background: linear-gradient(180deg, #f7fbff 0%, #eef5ff 100%);
}

.split-panel.is-cool {
  background: linear-gradient(180deg, #f3fbf8 0%, #e7f7f1 100%);
}
</style>

Collapsible Panels ​

Set collapsible on a panel to quickly collapse or restore it from the split bar buttons.

Outline
Editor
Preview
<template>
  <b-split class="split-demo">
    <b-split-panel size="180" collapsible min="80">
      <div class="split-panel is-soft">Outline</div>
    </b-split-panel>
    <b-split-panel collapsible>
      <div class="split-panel is-cool">Editor</div>
    </b-split-panel>
    <b-split-panel size="24%">
      <div class="split-panel is-warm">Preview</div>
    </b-split-panel>
  </b-split>
</template>

<style scoped>
.split-demo {
  height: 280px;
  border: 1px solid #e8edf4;
  border-radius: 14px;
  background: #fff;
}

.split-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 15px;
  font-weight: 600;
  color: #31415c;
}

.split-panel.is-soft {
  background: linear-gradient(135deg, #f7fbff 0%, #eef5ff 100%);
}

.split-panel.is-cool {
  background: linear-gradient(135deg, #f3fbf8 0%, #e7f7f1 100%);
}

.split-panel.is-warm {
  background: linear-gradient(135deg, #fffaf2 0%, #fff3df 100%);
}
</style>

Panel Size ​

size accepts numbers, px, or percentages. You can also read the current size with v-model:size.

Assets
160px
Workspace
<template>
  <b-split class="split-demo" @resize-end="handleResizeEnd">
    <b-split-panel>
      <div class="split-panel is-soft">Assets</div>
    </b-split-panel>
    <b-split-panel v-model:size="size" :min="120" :max="240">
      <div class="split-panel is-cool">{{ size }}px</div>
    </b-split-panel>
    <b-split-panel>
      <div class="split-panel is-warm">Workspace</div>
    </b-split-panel>
  </b-split>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const size = ref(160)

const handleResizeEnd = (_index: number, sizes: number[]) => {
  size.value = Math.round(sizes[1] || 0)
}
</script>

<style scoped>
.split-demo {
  height: 280px;
  border: 1px solid #e8edf4;
  border-radius: 14px;
  background: #fff;
}

.split-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 15px;
  font-weight: 600;
  color: #31415c;
}

.split-panel.is-soft {
  background: linear-gradient(135deg, #f7fbff 0%, #eef5ff 100%);
}

.split-panel.is-cool {
  background: linear-gradient(135deg, #f3fbf8 0%, #e7f7f1 100%);
}

.split-panel.is-warm {
  background: linear-gradient(135deg, #fffaf2 0%, #fff3df 100%);
}
</style>

Lazy Update ​

When lazy is enabled, only the drag bar moves during dragging. Panel sizes are committed after the drag ends.

The middle panel size updates after dragging ends.

Sidebar
Current width: 180px
Details
<template>
  <div>
    <p class="split-tip">The middle panel size updates after dragging ends.</p>
    <b-split class="split-demo" lazy>
      <b-split-panel size="25%" collapsible>
        <div class="split-panel is-soft">Sidebar</div>
      </b-split-panel>
      <b-split-panel v-model:size="size" :min="120">
        <div class="split-panel is-cool">Current width: {{ size }}px</div>
      </b-split-panel>
      <b-split-panel collapsible>
        <div class="split-panel is-warm">Details</div>
      </b-split-panel>
    </b-split>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const size = ref(180)
</script>

<style scoped>
.split-tip {
  margin-bottom: 10px;
  color: #5b6b88;
}

.split-demo {
  height: 280px;
  border: 1px solid #e8edf4;
  border-radius: 14px;
  background: #fff;
}

.split-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 15px;
  font-weight: 600;
  color: #31415c;
}

.split-panel.is-soft {
  background: linear-gradient(135deg, #f7fbff 0%, #eef5ff 100%);
}

.split-panel.is-cool {
  background: linear-gradient(135deg, #f3fbf8 0%, #e7f7f1 100%);
}

.split-panel.is-warm {
  background: linear-gradient(135deg, #fffaf2 0%, #fff3df 100%);
}
</style>

Disable Dragging ​

If either adjacent panel sets resizable="false", the related split bar becomes non-draggable.

Resizable
Fixed Width
Content
<template>
  <b-split class="split-demo">
    <b-split-panel size="28%">
      <div class="split-panel is-soft">Resizable</div>
    </b-split-panel>
    <b-split-panel :resizable="false" size="180">
      <div class="split-panel is-cool">Fixed Width</div>
    </b-split-panel>
    <b-split-panel>
      <div class="split-panel is-warm">Content</div>
    </b-split-panel>
  </b-split>
</template>

<style scoped>
.split-demo {
  height: 280px;
  border: 1px solid #e8edf4;
  border-radius: 14px;
  background: #fff;
}

.split-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 15px;
  font-weight: 600;
  color: #31415c;
}

.split-panel.is-soft {
  background: linear-gradient(135deg, #f7fbff 0%, #eef5ff 100%);
}

.split-panel.is-cool {
  background: linear-gradient(135deg, #f3fbf8 0%, #e7f7f1 100%);
}

.split-panel.is-warm {
  background: linear-gradient(135deg, #fffaf2 0%, #fff3df 100%);
}
</style>

Multiple Panels ​

Split supports layouts with more than two panels.

A
B
C
D
<template>
  <b-split class="split-demo">
    <b-split-panel size="18%">
      <div class="split-panel is-soft">A</div>
    </b-split-panel>
    <b-split-panel size="22%" collapsible>
      <div class="split-panel is-cool">B</div>
    </b-split-panel>
    <b-split-panel :min="140">
      <div class="split-panel is-warm">C</div>
    </b-split-panel>
    <b-split-panel size="20%">
      <div class="split-panel is-deep">D</div>
    </b-split-panel>
  </b-split>
</template>

<style scoped>
.split-demo {
  height: 280px;
  border: 1px solid #e8edf4;
  border-radius: 14px;
  background: #fff;
}

.split-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 15px;
  font-weight: 600;
  color: #31415c;
}

.split-panel.is-soft {
  background: linear-gradient(135deg, #f7fbff 0%, #eef5ff 100%);
}

.split-panel.is-cool {
  background: linear-gradient(135deg, #f3fbf8 0%, #e7f7f1 100%);
}

.split-panel.is-warm {
  background: linear-gradient(135deg, #fffaf2 0%, #fff3df 100%);
}

.split-panel.is-deep {
  background: linear-gradient(135deg, #f6f3ff 0%, #ece7ff 100%);
}
</style>

Split Props ​

ParameterDescriptionTypeOptionsDefault
layoutPanel layout directionString'horizontal' | 'vertical'horizontal
lazyWhether to enable lazy updatesBoolean—false

Split Events ​

EventDescriptionReturn Value
resize-startTriggered when dragging starts(index: number, sizes: number[])
resizeTriggered while dragging(index: number, sizes: number[])
resize-endTriggered when dragging ends(index: number, sizes: number[])
collapseTriggered when a collapse button is clicked(index: number, type: 'start' | 'end', sizes: number[])

SplitPanel Props ​

ParameterDescriptionTypeDefault
sizePanel size, supports numbers, px, or percentagesString / Number—
minMinimum panel size, supports numbers, px, or percentagesString / Number—
maxMaximum panel size, supports numbers, px, or percentagesString / Number—
resizableWhether the panel can be resizedBooleantrue
collapsibleWhether collapse controls are enabled. Supports boolean or directional objectBoolean / { start?: boolean; end?: boolean }false

SplitPanel Events ​

EventDescriptionReturn Value
update:sizeTriggered when panel size changes(size: string | number)

SplitPanel Slots ​

NameDescription
defaultDefault panel content
start-collapsibleCustom start-side collapse trigger
end-collapsibleCustom end-side collapse trigger