notebook/examples/widgets/Part 4 - Styles.ipynb
Jonathan Frederic 8502b2c182 Remove init_widget_js, use require.js for everything
Updated examples
Fixed bug with message throttling
2014-01-16 10:56:59 +00:00

11 KiB
Raw Blame History

In [1]:
from IPython.html import widgets # Widget definitions
from IPython.display import display # Used to display widgets in the notebook

CSS

When trying to design an attractive widget GUI, styling becomes important. Widget views are DOM (document object model) elements that can be controlled with CSS. There are two helper methods defined on widget that allow the manipulation of the widget's CSS. The first is the set_css method, whos doc string is displayed below. This method allows one or more CSS attributes to be set at once.

In [2]:
print(widgets.Widget.set_css.__doc__)
Set one or more CSS properties of the widget (shared among all of the 
        views).  This function has two signatures:
        - set_css(css_dict, [selector=''])
        - set_css(key, value, [selector=''])

        Parameters
        ----------
        css_dict : dict
            CSS key/value pairs to apply
        key: unicode
            CSS key
        value
            CSS value
        selector: unicode (optional)
            JQuery selector to use to apply the CSS key/value.
        

The second is get_css which allows CSS attributes that have been set to be read. Note that this method will only read CSS attributes that have been set using the set_css method. get_css's doc string is displayed below.

In [3]:
print(widgets.Widget.get_css.__doc__)
Get a CSS property of the widget.  Note, this function does not 
        actually request the CSS from the front-end;  Only properties that have 
        been set with set_css can be read.

        Parameters
        ----------
        key: unicode
            CSS key
        selector: unicode (optional)
            JQuery selector used when the CSS key/value was set.
        

Below is an example that applies CSS attributes to a container to emphasize text.

In [4]:
container = widgets.ContainerWidget()

# set_css used to set a single CSS attribute.
container.set_css('border', '3px solid black') # Border the container

# set_css used to set multiple CSS attributes.
container.set_css({'padding': '6px', # Add padding to the container
                   'background': 'yellow'}) # Fill the container yellow

label = widgets.StringWidget(default_view_name="LabelView", parent=container)
label.value = "<strong>ALERT: </strong> Hello World!"

display(container)

DOM Classes

In some cases it's necessary to apply DOM classes to your widgets. DOM classes allow DOM elements to be indentified by Javascript and CSS. The notebook defines its own set of classes to stylize its elements. The add_class widget method allows you to add DOM classes to your widget's definition. The add_class method's doc string can be seen below.

In [5]:
print(widgets.Widget.add_class.__doc__)
Add class[es] to a DOM element

        Parameters
        ----------
        class_name: unicode
            Class name(s) to add to the DOM element(s).  Multiple class names 
            must be space separated.
        selector: unicode (optional)
            JQuery selector to select the DOM element(s) that the class(es) will 
            be added to.
        

Since add_class if a DOM operation, it will only affect widgets that have been displayed. add_class must be called after the widget has been displayed. Extending the example above, the corners of the container can be rounded by adding the corner-all notebook class to the container (as seen below).

In [6]:
container = widgets.ContainerWidget()
container.set_css({'border': '3px solid black',
                   'padding': '6px',
                   'background': 'yellow'}) 

label = widgets.StringWidget(default_view_name="LabelView", parent=container) 
label.value = "<strong>ALERT: </strong> Hello World!"

display(container)
container.add_class('corner-all') # Must be called AFTER display

The IPython notebook uses bootstrap for styling. The example above can be simplified by using a bootstrap class (as seen below). Bootstrap documentation can be found at http://getbootstrap.com/ .

In [7]:
label = widgets.StringWidget(value = "<strong>ALERT: </strong> Hello World!")
display(label, view_name="LabelView")

# Apply twitter bootstrap alert class to the label.
label.add_class("alert")

The example below shows how bootstrap classes can be used to change button apearance.

In [8]:
# List of the bootstrap button styles
button_classes = ['Default', 'btn-primary', 'btn-info', 'btn-success', 
                  'btn-warning', 'btn-danger', 'btn-inverse', 'btn-link']

# Create each button and apply the style.  Also add margin to the buttons so they space
# themselves nicely.
for i in range(8):
    button = widgets.ButtonWidget(description=button_classes[i])
    button.set_css("margin", "5px")
    display(button)
    if i > 0: # Don't add a class the first button.
        button.add_class(button_classes[i])
    

It's also useful to be able to remove DOM classes from widgets. The remove_class widget method allows you to remove classes from widgets that have been displayed. Like add_widget, it must be called after the widget has been displayed. The doc string of remove_class can be seen below.

In [9]:
print(widgets.Widget.remove_class.__doc__)
Remove class[es] from a DOM element

        Parameters
        ----------
        class_name: unicode
            Class name(s) to remove from  the DOM element(s).  Multiple class 
            names must be space separated.
        selector: unicode (optional)
            JQuery selector to select the DOM element(s) that the class(es) will 
            be removed from.
        

The example below animates an alert using different bootstrap styles.

In [10]:
import time
label = widgets.StringWidget(value = "<strong>ALERT: </strong> Hello World!")
display(label, view_name="LabelView")

# Apply twitter bootstrap alert class to the label.
label.add_class("alert")

# Animate through additional bootstrap label styles 3 times
additional_alert_styles = ['alert-error', 'alert-info', 'alert-success']
for i in range(3 * len(additional_alert_styles)):
    label.add_class(additional_alert_styles[i % 3])
    label.remove_class(additional_alert_styles[(i-1) % 3])
    time.sleep(1)