Set Canvas/root elem CSS in python - eg change background of root/parent that holds the widgets

Hello hidara, welcome to Bokeh Discourse.

In the future, please provide a minimal, reproducible, self contained and working example, see MRE.
The code starts with the imports and usually ends with show(layout), or curdoc().add_root(layout) if there are Python callbacks.
That way, the reader can run the code quickly and the probability you get an answer is higher.

About your question:
You might already had a look at following links:

The background of the app can be setup by providing your own HMTL template.
So I recommend to use the directory format for your app. A simple hierarchy could be:

myapp
   |
   + - main.py
   + - templates
        + - index.html
   + - theme.yaml

So in words: In the directory called myapp, place a main.py file containing your code, and a subdirectory called templates containing a file index.html.
Optionally, instead of using the built-in theme dark_minimal, you could add your own custom theme as a theme.yaml file to your directory.

As a compact example, the code in main.py could be:

from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.models import  InlineStyleSheet, Slider
from bokeh.layouts import Column
from bokeh.themes import Theme
import os

# Preconfiguration to get the relative path of the theme.yaml:
dirname = os.path.dirname(__file__)

# Prepare some data
x = [1, 2, 3, 4, 5]
y = [6, 7, 2, 4, 5]

# Create a new plot
p = figure(x_axis_label="x", y_axis_label="y", height=200)

# Add renderer:
line = p.line(x, y)

# Prepare CSS formatting for the title color of the slider:
stylesheet = InlineStyleSheet(css=".bk-slider-title { color: white; }")

# Create slider:
slider = Slider(start=0,
                end=10,
                value=5,
                step=1,
                title="Select number",
                bar_color="#20262B",
                stylesheets=[stylesheet]
                )

# Create layout:
layout = Column(slider, p)

# Define layout of the elements:
# Either with a built-in theme:
curdoc().theme = 'dark_minimal' # <-- Toggle the comments to test
# Or by using a custom theme defined in the theme.yaml file in your app directory:
# curdoc().theme = Theme(filename=os.path.join(dirname, 'theme.yaml')) # <-- Toggle the comments to test

curdoc().add_root(layout)

The HMTL template is given in the index.html file and could be:

<!DOCTYPE html>
<html lang="en">
    <head>
        <style>
            body { background: #15191C; }
        </style>
        <meta charset="utf-8">
        {{ bokeh_css }}
        {{ bokeh_js }}
    </head>
    <body>
        {{ plot_div|indent(8) }}
        {{ plot_script|indent(8) }}
    </body>
</html>

For a seamless appearance, I set in the HTML template the background color to #15191C, which is the same as in the border_fill_color in the dark_minimal theme, as you can see here: https://github.com/bokeh/bokeh/blob/branch-3.4/src/bokeh/themes/_dark_minimal.py

To change the title color of the slider, you will have to use CSS, see here: python - slider text color change in bokeh lib - Stack Overflow
That is why you will find following line in the code:
stylesheet = InlineStyleSheet(css=".bk-slider-title { color: white; }")
and then stylesheets=[stylesheet] in the arguments of the slider definition.

In the theme.yaml, you could have following content:

attrs:
    Slider:
        bar_color: '#3A1F04'
    Plot:
        background_fill_color: '#3A1F04'
        border_fill_color: '#4B3A26'
        outline_line_color: '#444444'
    Axis:
        axis_line_color: !!null
    Grid:
        grid_line_dash: [6, 4]
        grid_line_alpha: .3
    Title:
        text_color: "white"

I use here brown colors to differentiate from the dark_minimal theme.
Note that the slider bar color (left from the selector) is defined here, but it will be overridden by the argument bar_color="#20262B" in the arguments of the slider definition.

At last, start the app with:
bokeh serve --show directory_name

With the dark_minimal theme, I get this:
dark minimal
After switching the comments to use the custom brown theme:
brown

1 Like