{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Widget Styling\n", "\n", "In this lecture we will learn about the various ways to style widgets!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `style` vs. `layout`\n", "\n", "There are two ways to change the appearance of widgets in the browser. The first is through the `layout` attribute which exposes layout-related CSS properties for the top-level DOM element of widgets, such as margins and positioning. The second is through the `style` attribute which exposes non-layout related attributes like button color and font weight. While `layout` is general to all widgets and containers of widgets, `style` offers tools specific to each type of widget.\n", "\n", "Thorough understanding of all that `layout` has to offer requires knowledge of front-end web development, including HTML and CSS. This section provides a brief overview of things that can be adjusted using `layout`. However, the full set of tools are provided in the separate notebook **Advanced Widget Styling with Layout**.\n", "\n", "To learn more about web development, including HTML and CSS, check out the course [\n", "Python and Django Full Stack Web Developer Bootcamp](https://www.udemy.com/python-and-django-full-stack-web-developer-bootcamp/)\n", "\n", "Basic styling is more intuitive as it relates directly to each type of widget. Here we provide a set of helpful examples of the `style` attribute.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The `layout` attribute\n", "Jupyter interactive widgets have a `layout` attribute exposing a number of CSS properties that impact how widgets are laid out. These properties map to the values of the CSS properties of the same name (underscores being replaced with dashes), applied to the top DOM elements of the corresponding widget.\n", "\n", "#### Sizes\n", "* `height`\n", "* `width`\n", "* `max_height`\n", "* `max_width`\n", "* `min_height`\n", "* `min_width`\n", "\n", "#### Display\n", "* `visibility`\n", "* `display`\n", "* `overflow`\n", "* `overflow_x`\n", "* `overflow_y`\n", "\n", "#### Box model\n", "* `border`\n", "* `margin`\n", "* `padding`\n", "\n", "#### Positioning\n", "* `top`\n", "* `left`\n", "* `bottom`\n", "* `right`\n", "\n", "#### Flexbox\n", "* `order`\n", "* `flex_flow`\n", "* `align_items`\n", "* `flex`\n", "* `align_self`\n", "* `align_content`\n", "* `justify_content`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A quick example of `layout`\n", "\n", "We've already seen what a slider looks like without any layout adjustments:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import ipywidgets as widgets\n", "from IPython.display import display\n", "\n", "w = widgets.IntSlider()\n", "display(w)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's say we wanted to change two of the properties of this widget: `margin` and `height`. We want to center the slider in the output area and increase its height. This can be done by adding `layout` attributes to **w**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "w.layout.margin = 'auto'\n", "w.layout.height = '75px'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that the slider changed positions on the page immediately!\n", "\n", "\n", "Layout settings can be passed from one widget to another widget of the same type. Let's first create a new IntSlider:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = widgets.IntSlider(value=15,description='New slider')\n", "display(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now assign **w**'s layout settings to **x**:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x.layout = w.layout" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That's it! For a complete set of instructions on using `layout`, visit the **Advanced Widget Styling - Layout** notebook." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Predefined styles\n", "\n", "Before we investigate the `style` attribute, it should be noted that many widgets offer a list of pre-defined styles that can be passed as arguments during creation.\n", "\n", "For example, the `Button` widget has a `button_style` attribute that may take 5 different values:\n", "\n", "* `'primary'`\n", "* `'success'`\n", "* `'info'`\n", "* `'warning'`\n", "* `'danger'`\n", "\n", "besides the default empty string `''`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import ipywidgets as widgets\n", "\n", "widgets.Button(description='Ordinary Button', button_style='')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "widgets.Button(description='Danger Button', button_style='danger')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The `style` attribute" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "While the `layout` attribute only exposes layout-related CSS properties for the top-level DOM element of widgets, the\n", "`style` attribute is used to expose non-layout related styling attributes of widgets.\n", "\n", "However, the properties of the `style` atribute are specific to each widget type." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b1 = widgets.Button(description='Custom color')\n", "b1.style.button_color = 'lightgreen'\n", "b1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can get a list of the style attributes for a widget with the `keys` property." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b1.style.keys" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that `widgets.Button().style.keys` also works." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Just like the `layout` attribute, widget styles can be assigned to other widgets." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b2 = widgets.Button()\n", "b2.style = b1.style\n", "b2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that only the style was picked up by **b2**, not any other parameters like `description`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Widget styling attributes are specific to each widget type." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s1 = widgets.IntSlider(description='Blue handle')\n", "s1.style.handle_color = 'lightblue'\n", "s1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Widget style traits\n", "\n", "These are traits that belong to some of the more common widgets:\n", "\n", "#### Button\n", "\n", "- `button_color`\n", "- `font_weight`\n", "\n", "#### IntSlider, FloatSlider, IntRangeSlider, FloatRangeSlider\n", "\n", "- `description_width`\n", "- `handle_color`\n", "\n", "#### IntProgress, FloatProgress\n", "\n", "- `bar_color`\n", "- `description_width`\n", "\n", "Most others such as `ToggleButton`, `Checkbox`, `Dropdown`, `RadioButtons`, `Select` and `Text` only have `description_width` as an adjustable trait." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Conclusion\n", "\n", "You should now have an understanding of how to style widgets!" ] } ], "metadata": { "cell_tags": [ [ "", null ] ], "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.2" } }, "nbformat": 4, "nbformat_minor": 1 }