Search code examples
pythonipywidgets

Styling ipywidgets.Accordion panels, individually


Is there a way to apply some styling (e.g. with CSS) on an Accordion widget? For example, I'd like to style a single pane in the Accordion to make the background color light yellow.

Note that setting a layout on the Accordion itself will style the container that holds the individual panes, while applying a layout to the children of the Accordion will style the contents of the panes, but not the panes themselves. How can I apply a style to the panes themselves? Ideally this would be at the individual level, but applying a style to all panes in an Accordion could be made to serve my purposes.


Solution

  • While ipywidgets' own styling system is still in active development, here is a somewhat hacky way to do it.

    ipywidgets provides add_class method to allow you add a custom class to a widget, and you can use ipython's HTML method to add custom HTML to your notebook, so combine them together you can add any css to your widgets.

    import ipywidgets as widgets
    from IPython.display import display, HTML
    
    #Create an accordion and add mystyle class on its first child widget
    accordion = widgets.Accordion(children=[widgets.IntSlider(), widgets.Text()], titles=('Slider', 'Text')).add_class("parentstyle")
    #Add a custom style tag to the notebook, you can use dev tool to inspect the class names
    display(HTML("<style>.parentstyle > .p-Accordion-child > .p-Collapse-header{background-color:yellow}</style>"))
    #Now the background of the title bars become yellow
    display(accordion)
    

    If you only want to add style to the open panel, you can use display(HTML("<style>.parentstyle > .p-Collapse-open > .p-Collapse-header{background-color:yellow}</style>")) instead of the css above, which will select the open panel.

    Unfortunately, css :has pseudoclass is not widely available right now, so more fine grained control of the style isn't available.