Styling of Jupyter widgets#

This notebook presents how to style Jupyter interactive widgets to build rich and reactive widget-based applications.

You can jump directly to these sections:

Predefined styles#

If you wish the styling of widgets to make use of colors and styles defined by the environment (to be consistent with e.g. a notebook theme), many widgets enable choosing in a list of pre-defined styles.

For example, the Button widget has a button_style attribute that may take 5 different values:

  • 'primary'

  • 'success'

  • 'info'

  • 'warning'

  • 'danger'

besides the default empty string ‘’.

from ipywidgets import Button

Button(description='Danger Button', button_style='danger')

The style attribute#

While the layout attribute only exposes layout-related CSS properties for the top-level DOM element of widgets, the
style attribute is used to expose non-layout related styling attributes of widgets.

However, the properties of the style attribute are specific to each widget type.

b1 = Button(description='Custom color')
b1.style.button_color = 'lightgreen'
b1

You can get a list of the style attributes for a widget with the keys property.

b1.style.keys
['_model_module',
 '_model_module_version',
 '_model_name',
 '_view_count',
 '_view_module',
 '_view_module_version',
 '_view_name',
 'button_color',
 'font_family',
 'font_size',
 'font_style',
 'font_variant',
 'font_weight',
 'text_color',
 'text_decoration']

Just like the layout attribute, widget styles can be assigned to other widgets.

b2 = Button()
b2.style = b1.style
b2

Widget styling attributes are specific to each widget type.

from ipywidgets import IntSlider

s1 = IntSlider(description='Blue handle')
s1.style.handle_color = 'lightblue'
s1

Styles can be given when a widget is constructed, either as a specific Style instance or as a dictionary.

b3 = Button(description='Styled button', style=dict(
    font_style='italic',
    font_weight='bold',
    font_variant="small-caps",
    text_color='red',
    text_decoration='underline'
))
b3

Current supported attributes#

Currently, the styling attributes that are supported vary from widget to widget. Here is the list of which different Style widgets are used by the various other widgets:

from collections import defaultdict
from IPython.display import HTML
import ipywidgets
from pprint import pprint
reverse_lut = defaultdict(set)
styles = set()
for export_name in dir(ipywidgets.widgets):
    export = getattr(ipywidgets.widgets, export_name)
    try:
        if issubclass(export, ipywidgets.Widget) and 'style' in export.class_trait_names():
            reverse_lut[export.style.klass.__name__].add(export.__name__)
            styles.add(export.style.klass)
    except TypeError:
        pass

html = '<ul>'
for style, widgets in reverse_lut.items():
    html = f"{html}\n<li><b>{style}:</b> {', '.join(sorted(widgets))}</li>"
html += "</ul>"
HTML(html)
  • DescriptionStyle: BoundedFloatText, BoundedIntText, ColorPicker, ColorsInput, DatePicker, DatetimePicker, Dropdown, FloatText, FloatsInput, IntText, IntsInput, NaiveDatetimePicker, Play, RadioButtons, Select, SelectMultiple, TagsInput, TimePicker, Valid
  • ButtonStyle: Button, FileUpload
  • CheckboxStyle: Checkbox
  • TextStyle: Combobox, Password, Text, Textarea
  • SliderStyle: FloatLogSlider, FloatRangeSlider, FloatSlider, IntRangeSlider, IntSlider, SelectionRangeSlider, SelectionSlider
  • ProgressStyle: FloatProgress, IntProgress
  • HTMLStyle: HTML
  • HTMLMathStyle: HTMLMath
  • LabelStyle: Label
  • ToggleButtonStyle: ToggleButton
  • ToggleButtonsStyle: ToggleButtons

And here are the different attributes that the different Style widgets support:

attributes = defaultdict(set)
base_traits = set(ipywidgets.Style.class_trait_names())

for s in styles:
    for t in s.class_trait_names():
        if not t.startswith("_") and t not in base_traits:
            attributes[s.__name__].add(t)
all_attributes = set().union(*attributes.values())

html = '<table>\n'
html = f"{html}<tr><th>Attribute</th>{ ''.join(f'<th>{s}</th>' for s in attributes.keys()) }</tr>"
for a in all_attributes:
    html = f"""{html}<tr><td>{a}</td>{ ''.join(f'<td>{"✓" if a in attribs else ""}</td>' for attribs in attributes.values()) }</tr>"""
html += "</table>"
HTML(html)
AttributeToggleButtonStyleSliderStyleDescriptionStyleToggleButtonsStyleButtonStyleCheckboxStyleHTMLStyleLabelStyleTextStyleProgressStyleHTMLMathStyle
handle_color
button_width
background
font_family
font_style
font_size
font_variant
font_weight
text_decoration
bar_color
button_color
description_width
text_color