3.0.0 CSS changes

Hey everyone,

I updated my app to bokeh 3.0.0. and I am trying to migrate everything. There are as well some changes to CSS and how it is handled. I am not an expert in that part. I used to have a global css file that handles all the styles. As I read in the migration guide, that is not possible any more. The little discription in the migration guide is not quite helpful for me. Can someone explain to me very shortly with an example how I can add css_classes to an object, for example a button?

Thanks a lot!

There’s at least one example of using Styles here:

There is also some useful comments in this issue: Sizing mode example is broken · Issue #12453 · bokeh/bokeh · GitHub

That show a few methods to apply styles, you could search examples for those usages.

@Timo wasn’t there some docs support added as well? I thought so, but I can’t find where.

how I can add css_classes to an object, for example a button?

You can add CSS classes to a Bokeh object with css_classes the same as always, but now I am actually not sure what continued purpose that serves. Hopeful @mateusz can comment about what css_classes is still useful for.

Thanks Bryan. That helped for most of the parts, but I am stil not able to change the style for a button. The global css I used looked like that:

.button button.bk.bk-btn.bk-btn-default{
  background-color: var(--themeColor);
  font-family: Arial;
  font-size: 15px;
  color: black;
  border: black;
  border-radius: 5px;
  border-style: solid;
  border-width: 1px;
  text-align: center;
  transition-duration: 0.2s;
  cursor: pointer;
  width: 100%;
  height: 100%;
  height: 40px;
}

.button button.bk.bk-btn.bk-btn-default:focus {
  background-color:  var(--focusColor);
}

.button button.bk.bk-btn.bk-btn-default:active {
  background-color:  var(--activeColor);
}

.button button.bk.bk-btn.bk-btn-default:hover {
  background-color:  var(--hoverColor);
}

How can I add styles for each state (focus, active, hover, default) to the button? And I have the issue, that the font settings I define do not have any effect on the button.
Maybe you know what I am doing wrong.

A couple of ideas but please note that I am by no means an expert in CSS. But it seems that in Bokeh version 3 the change to shadow DOM elements breaks ones old setup. Now it seems you can use stylesheets go style the bk-btn within a shadow DOM. In the example below I use

style_btn2 = """.bk-btn {
  font-family: Arial;
  font-size: 20px;
  color: red;
  border-color: red;
  background-color: grey;
  }"""

and add that to stylesheets as a list.

If you want to use an external css file it becomes complex. One needs to select the shadowRoot of the element and the style sheet to that. That is in the JS function in the code below.

from bokeh.io import save
from bokeh.models import Button
from bokeh.plotting import figure

style_btn2 = """.bk-btn {
  font-family: Arial;
  font-size: 20px;
  color: red;
  border-color: red;
  background-color: grey;
  }"""
btn1 = Button(label = "Button 1", name = "btn1")
btn2 = Button(label = "Button 2", stylesheets = [style_btn2], name = "btn2")
btn3 = Button(label = "Button 3", name = "btn3", classes = ["btn3"]) 

template = """
{% block preamble %}
<link href="styles.css" rel="stylesheet">
{% endblock %}
{% block contents %}
<div class="container">
<div class="row">
  <div class="btn-div">
    Default <code>bk-btn</code>
    <div class="bk-wdg-center">
    {{ embed(roots.btn1) }}
    </div>
  </div>
  <div class="btn-div">
    Using <code>stylesheets</code>
    <div class="bk-wdg-center">
    {{ embed(roots.btn2) }}
    </div>
  </div>
  <div class="btn-div">
    JS function to select <code>shadowRoot</code><br>
    and add external stylesheet.
    <div class="bk-wdg-center">
    {{ embed(roots.btn3) }}
    </div>
    </div>
  </div>
</div>
</div>
<script>
function runBkScript() {
    if ((window.Bokeh.documents[0] !== undefined)) {
      let sroot = document.getElementsByClassName("btn3")[0].shadowRoot;
      const linkElem = document.createElement("link");
      linkElem.setAttribute("rel", "stylesheet");
      linkElem.setAttribute("href", "styles.css");

      // Attach the created element to the shadow DOM
      sroot.appendChild(linkElem);
      } else {
        setTimeout(runBkScript, 1000);
      }
}
window.onload = function() {
    runBkScript();
}
</script>
{% endblock %}
"""
contents = [btn1, btn2, btn3]
save(contents, template=template, title="CSS button")

styles.css

.bk-btn {
  font-family: Arial;
  font-size: 15px;
  color: white;
  border-color: yellow;
  background-color: black;
  }

.container {
    /*max-width: 1500px;*/
    margin: auto;
}

.row {
  display: flex;
  justify-content: center;
}

.btn-div {
  margin: 10px;
}
.bk-wdg-center {
  display: flex;
  justify-content: center;
}
2 Likes

Sweet got it to work. Thanks a lot!

1 Like