# Custom CSS in Jupyter (Lab) Notebook

**URL:** <https://discourse.bokeh.org/t/custom-css-in-jupyter-lab-notebook/12393>\
**Category:** Community Support\
**Tags:** jupyter, bokeh\
**Created:** [April 4, 2025, 11:48am UTC](https://discourse.bokeh.org/t/custom-css-in-jupyter-lab-notebook/12393 "2025-04-04T11:48:04Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![johank](https://discourse.bokeh.org/letter_avatar_proxy/v4/letter/j/e9bcb4/32.png) [@johank](https://discourse.bokeh.org/u/johank)\
**Post date:** [April 4, 2025, 11:48am UTC](https://discourse.bokeh.org/t/custom-css-in-jupyter-lab-notebook/12393/1 "2025-04-04T11:48:04Z")

</div>

Hi,

I’m trying to apply custom CSS to bokeh widgets displayed in a jupyter(lab) notebook. Motivation: Since bokeh ~3.4ish, widget font colors have not played nice with the jupyterlab dark theme - text often renders white on white background.

I’ve added a custom.css in the `~/.jupyter/config/custom` directory:

```auto
bokeh_widget {
    font-weight: bold;
    color: black;
}

```

Example ipynb with Widget:

```auto
import pandas as pd

from bokeh.layouts import row 
from bokeh.models.widgets import Select
from bokeh.io import show, output_notebook

output_notebook()

months = list(pd.date_range(start='2024-01-01', periods=12, 
                                            freq='ME').strftime('%b'))

sel_month = Select(title='Select Month:', value='All', 
                      options=['All']+months, css_classes=['bokeh_widget'])

def pl(doc):

    doc.add_root(
            row(sel_month)
            )
        
    return pl

show(pl)

```

Output with jupyterlab 4.3.5 & dark theme:

 ![2025-04-04 13_41_37-bokeh_custom… (2) - JupyterLab](https://discourse-uploads.bokeh.org/original/2X/3/3fb42093b6370a6662cec7bf29487b6d25c36f8b.png)

Unfortunately I know next to nothing about HTML & CSS - problem #1. Suspect/hope there’s an easy solution - patient guidance much appreciated 🙂

Thanks!

---

<div class="post-metadata">

**Author:** ![Bryan](https://discourse.bokeh.org/user_avatar/discourse.bokeh.org/bryan/32/3625_2.png) [@Bryan](https://discourse.bokeh.org/u/Bryan)\
**Post date:** [April 4, 2025, 4:17pm UTC](https://discourse.bokeh.org/t/custom-css-in-jupyter-lab-notebook/12393/2 "2025-04-04T16:17:33Z")

</div>

Bokeh elements all live in a shadow DOM so need e.g. `:host` to target. Here is an example you can follow (I would suggest using Bokeh’s various stylesheet options as in that example)

[bokeh/examples/styling/dom/css\_classes.py at branch-3.8 · bokeh/bokeh · GitHub](https://github.com/bokeh/bokeh/blob/branch-3.8/examples/styling/dom/css_classes.py)

---

<div class="post-metadata">

**Author:** ![johank](https://discourse.bokeh.org/letter_avatar_proxy/v4/letter/j/e9bcb4/32.png) [@johank](https://discourse.bokeh.org/u/johank)\
**Post date:** [May 2, 2025, 10:34am UTC](https://discourse.bokeh.org/t/custom-css-in-jupyter-lab-notebook/12393/3 "2025-05-02T10:34:53Z")

</div>

Thank you very much Bryan! Took a minute to try this, but it ~worked with an `InlineStyleSheet` as in the example.

Just one followup question: which CSS property modifies the text color of the items in the widget (e.g. the `Select` in the example above)? `color` changes the text color of the Title, but not the items.

For a `Select`, I assume there are two properties; one for the default, one for when an item has mouse focus/is hovered over.

---

<div class="post-metadata">

**Author:** ![Bryan](https://discourse.bokeh.org/user_avatar/discourse.bokeh.org/bryan/32/3625_2.png) [@Bryan](https://discourse.bokeh.org/u/Bryan)\
**Post date:** [May 2, 2025, 11:45pm UTC](https://discourse.bokeh.org/t/custom-css-in-jupyter-lab-notebook/12393/4 "2025-05-02T23:45:08Z")

</div>

I’m afraid I don’t know. I usually open up a browser’s dev tools and use the DOM inspector when I need to hunt for CSS targets.

---

<div class="post-metadata">

**Author:** ![johank](https://discourse.bokeh.org/letter_avatar_proxy/v4/letter/j/e9bcb4/32.png) [@johank](https://discourse.bokeh.org/u/johank)\
**Post date:** [May 5, 2025, 9:15pm UTC](https://discourse.bokeh.org/t/custom-css-in-jupyter-lab-notebook/12393/5 "2025-05-05T21:15:13Z")

</div>

Got it, thanks -

This ended up working for me:

```auto
months = list(pd.date_range(start='2024-01-01', periods=12, 
                                            freq='ME').strftime('%b'))

sel_month = Select(title='Select Month:', value='All', 
                      options=['All']+months, css_classes=['bokeh_widget'])

stylesheet = InlineStyleSheet(css='''
:host(.custom) {
    .bk-input {
        color: black;
        };
''')

sel_month.css_classes = ['custom']
sel_month.stylesheets = [stylesheet]

layout = row(sel_month)

```

Output now:

 ![2025-05-05 23_10_48-bokeh_custom… (3) - JupyterLab](https://discourse-uploads.bokeh.org/original/2X/b/b872660acce3df910616b539ac8a5b1b322121ee.png)

Yay!

Is there an easy way to add this custom CSS to **all** input widgets, or must that be done one-by-one?

Thanks!

---

<div class="post-metadata">

**Author:** ![Bryan](https://discourse.bokeh.org/user_avatar/discourse.bokeh.org/bryan/32/3625_2.png) [@Bryan](https://discourse.bokeh.org/u/Bryan)\
**Post date:** [May 7, 2025, 2:54am UTC](https://discourse.bokeh.org/t/custom-css-in-jupyter-lab-notebook/12393/6 "2025-05-07T02:54:42Z")

</div>

I believe that using `GlobalInlineStyleSheet` instead of `InlineStyleSheet` should accomplish that.

---

<div class="post-metadata">

**Author:** ![johank](https://discourse.bokeh.org/letter_avatar_proxy/v4/letter/j/e9bcb4/32.png) [@johank](https://discourse.bokeh.org/u/johank)\
**Post date:** [May 7, 2025, 1:34pm UTC](https://discourse.bokeh.org/t/custom-css-in-jupyter-lab-notebook/12393/7 "2025-05-07T13:34:53Z")

</div>

Thanks Bryan - that seems like it’s exactly what I’d want, but I could not get it to work.

Based on [this post](https://discourse.bokeh.org/t/help-to-understand-how-css-styling-is-applied-in-bokeh/11056), it sounds like `GlobalInlineStyleSheet` may not work…

Best workaround I’ve been able to come up with is to define a collection of widgets and then loop through those with a function that sets the `stylesheets` and `css_classes` properties of each widget. Bit clunky, but does the trick…

(I also again tried to define something in jupyter’s custom\_css, but that also didn’t work - probably because of the `:host` thingy 🤷‍♂️)

Thanks again for all your help!

---

<div class="post-metadata">

**Author:** ![Bryan](https://discourse.bokeh.org/user_avatar/discourse.bokeh.org/bryan/32/3625_2.png) [@Bryan](https://discourse.bokeh.org/u/Bryan)\
**Post date:** [May 7, 2025, 5:33pm UTC](https://discourse.bokeh.org/t/custom-css-in-jupyter-lab-notebook/12393/8 "2025-05-07T17:33:54Z")

</div>

> Based on [this post](https://discourse.bokeh.org/t/help-to-understand-how-css-styling-is-applied-in-bokeh/11056), it sounds like `GlobalInlineStyleSheet` may not work…

Well, `GlobalInlineStyleSheet` normally appends to `<head>` I can imagine there could be some problem in the context of a Jupyter notebook, specifically. I’d suggest trying things outside the notebook with plain HTML (i.e. `output_file`) output. Then submitting a [GitHub Issue](https://github.com/bokeh/bokeh/issues) with details.

---

<div class="post-metadata">

**Author:** ![system](https://discourse-uploads.bokeh.org/original/2X/1/14eb24f9e10e4e9b78e3f10f66c04ffa96446e5a.svg) [@system](https://discourse.bokeh.org/u/system)\
**Post date:** [August 5, 2025, 5:34pm UTC](https://discourse.bokeh.org/t/custom-css-in-jupyter-lab-notebook/12393/9 "2025-08-05T17:34:20Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
