Slider#

A single-handle track for selecting a numeric value within a range.

Slider demo — light theme Slider demo — dark theme

Usage#

A slider holds a numeric value within a min_value/max_value range, always clamped to the bounds. The decision you make is when to react: on_change fires continuously as the handle moves, while on_commit fires once on release — reach for on_commit when the work per update is expensive.

Basic#

bs.Slider()
bs.Slider(50, min_value=0, max_value=100)

Accent colors#

bs.Slider(50, accent="primary")
bs.Slider(50, accent="secondary")
bs.Slider(50, accent="info")
bs.Slider(50, accent="success")
bs.Slider(50, accent="warning")
bs.Slider(50, accent="danger")
Slider accent colors — light theme Slider accent colors — dark theme

Value badge#

Set show_value=True to display a floating badge with the current value above the handle.

bs.Slider(50, show_value=True)
Slider value badge — light theme Slider value badge — dark theme

Min / max labels#

Set show_minmax=True to display the minimum and maximum values at the track ends.

bs.Slider(50, show_minmax=True)
Slider min/max labels — light theme Slider min/max labels — dark theme

Note

When tick_step is set with labels, the range ends are already labeled — show_minmax is mainly for a slider without tick marks.

Tick marks#

Use tick_step= to add major tick marks. minor_ticks= adds subdivisions between them. tick_labels=False hides the numeric labels. tick_format= controls how tick and badge labels are formatted.

bs.Slider(50, tick_step=25)
bs.Slider(50, tick_step=25, minor_ticks=4)
bs.Slider(0.5, min_value=0, max_value=1, tick_step=0.25, tick_format="{:.0%}")
Slider tick marks — light theme Slider tick marks — dark theme

Note

tick_step only draws the marks — the value still moves continuously. To make the slider snap to those increments, use step= (see Snapping to steps).

Snapping to steps#

Set step= to constrain the value to discrete increments. Click and drag values snap to the nearest multiple of step (measured from min_value), and the arrow keys move by step. It is independent of tick_step — set both for a stepped slider with matching marks, or step alone to snap without drawing ticks.

# Only 0, 5, 10, … 100 — with ticks drawn at the same increments
bs.Slider(50, min_value=0, max_value=100, step=5, tick_step=5)

When the range is not an even multiple of step, the maximum stays reachable.

Reactive binding#

Bind a Signal[float] with signal=. The slider and signal stay in sync.

volume = bs.Signal(50.0)
bs.Slider(signal=volume)
volume.subscribe(lambda v: update_volume(v))

Events#

on_change fires continuously as the handle moves; on_commit fires once when the handle is released or moved by keyboard. Reach for on_commit when the work behind the slider is expensive — a network call, a recompute, a redraw.

s = bs.Slider(50, min_value=0, max_value=100)

# Fires continuously during a drag — keep this cheap
s.on_change(lambda e: preview(e.value))

# Fires once, on release or keyboard commit
s.on_commit(lambda e: apply(e.value))

# As a Stream
s.on_change().debounce(150).listen(lambda e: save(e.value))

The handler receives a SliderEvent (on_change) or SliderCommitEvent (on_commit); event.value holds the current value.

Keyboard#

When focused, the slider responds to the arrow keys (±1, or ±``step`` when step is set), Shift + arrow (a larger jump), and Home / End (minimum / maximum). Every keyboard change also emits on_commit.

Disabled#

bs.Slider(60)
bs.Slider(60, disabled=True)
Slider disabled — light theme Slider disabled — dark theme

Widget sizing#

All widgets accept self-placement kwargs via **kwargs. The parent container determines which options apply — Column / Row parents use the layout kwargs below, grid-based parents use grid kwargs.

Column (vertical layout)

Used inside a Column, App, or any other container with a column layout. Children are arranged top-to-bottom, so horizontal aligns each child across the width and grow shares the vertical space. (vertical does not apply — the order of the children sets their top-to-bottom position.)

horizontal

Cross-axis placement of the widget: 'left', 'center', 'right', or 'stretch' to fill the available width.

grow

Claim and fill a share of the leftover vertical space (the layout direction). True or False.

margin

External spacing in pixels. Accepts an integer (equal on all sides), a 2-tuple (horizontal, vertical), or a 4-tuple (left, top, right, bottom).

margin_x

Horizontal external spacing (left and right). Accepts an integer or a 2-tuple (left, right) for asymmetric spacing. Overrides the horizontal component of margin=.

margin_y

Vertical external spacing (top and bottom). Accepts an integer or a 2-tuple (top, bottom) for asymmetric spacing. Overrides the vertical component of margin=.

Row (horizontal layout)

Used inside a Row or any other container with a row layout. Children are arranged left-to-right, so vertical aligns each child across the height and grow shares the horizontal space. (horizontal does not apply — the order of the children sets their left-to-right position.)

vertical

Cross-axis placement of the widget: 'top', 'center', 'bottom', or 'stretch' to fill the available height.

grow

Claim and fill a share of the leftover horizontal space (the layout direction). True or False.

margin

External spacing in pixels. Accepts an integer (equal on all sides), a 2-tuple (horizontal, vertical), or a 4-tuple (left, top, right, bottom).

margin_x

Horizontal external spacing (left and right). Accepts an integer or a 2-tuple (left, right) for asymmetric spacing. Overrides the horizontal component of margin=.

margin_y

Vertical external spacing (top and bottom). Accepts an integer or a 2-tuple (top, bottom) for asymmetric spacing. Overrides the vertical component of margin=.

Grid

Used inside a Grid container.

row / column

Zero-based row and column indices.

rowspan / columnspan

Number of rows or columns to span.

horizontal

Horizontal placement within the grid cell: 'left', 'center', 'right', or 'stretch' to fill the cell width.

vertical

Vertical placement within the grid cell: 'top', 'center', 'bottom', or 'stretch' to fill the cell height.

margin

External spacing in pixels. Accepts an integer, a 2-tuple (horizontal, vertical), or a 4-tuple (left, top, right, bottom).

margin_x

Horizontal external spacing. Accepts an integer or (left, right).

margin_y

Vertical external spacing. Accepts an integer or (top, bottom).

See also#

API#

The complete reference for Slider lives on the Widgets API page. At a glance:

Slider

A single-handle slider for selecting a numeric value within a range.

Full Example#

 1
 2with bs.App(title="Slider Demo", padding=20, gap=16, min_size=(400, 1)) as app:
 3
 4    # Basic
 5    bs.Label("Basic", font="heading-sm")
 6    bs.Slider(horizontal="stretch")
 7
 8    # Accent colors
 9    bs.Label("Accent Colors", font="heading-sm")
10    with bs.Column(gap=6, horizontal="stretch", horizontal_items="stretch"):
11        for accent in ("primary", "secondary", "info", "success", "warning", "danger"):
12            bs.Slider(50, accent=accent)
13
14    # Value badge
15    bs.Label("Value Badge", font="heading-sm")
16    bs.Slider(50, show_value=True, horizontal="stretch")
17
18    # Min / max labels
19    bs.Label("Min / Max Labels", font="heading-sm")
20    bs.Slider(50, show_minmax=True, horizontal="stretch")
21
22    # Tick marks
23    bs.Label("Tick Marks", font="heading-sm")
24    bs.Slider(50, tick_step=25, horizontal="stretch")
25    bs.Slider(50, tick_step=25, minor_ticks=4, horizontal="stretch")
26    bs.Slider(50, tick_step=25, show_value=True, show_minmax=True, horizontal="stretch")
27
28    # Custom tick format
29    bs.Label("Custom Tick Format", font="heading-sm")
30    bs.Slider(
31        0.5,
32        min_value=0.0,
33        max_value=1.0,
34        tick_step=0.25,
35        tick_format="{:.0%}",
36        show_value=True,
37        horizontal="stretch",
38    )
39
40    # Step snapping (only 0, 5, 10, … 100)
41    bs.Label("Step Snapping", font="heading-sm")
42    bs.Slider(50, step=5, tick_step=5, horizontal="stretch")
43
44    # Disabled
45    bs.Label("Disabled", font="heading-sm")
46    bs.Slider(30, disabled=True, horizontal="stretch")
47
48app.run()