Conditional Colouring of Checkbox Group background

This is a replication of this → Associating Color Swatches to Elements of Checkbox Group

I also found a decent related thread here → Is there a way to style buttons of a ButtonGroup individually? - #2 by Bryan

With the 3.1 ability to execute arbitrary CustomJS on DocumentReady (thanks @mateusz !), it’s suddenly more viable to attempt to implement this.

Rough MRE:

from bokeh.models import CheckboxGroup, CustomJS
from bokeh.io import curdoc
from bokeh.events import DocumentReady
from bokeh.plotting import show

cbg = CheckboxGroup(labels = ['RED','YELLOW','BLUE'],active=[0,1,2]) #or maybe make a css_classes property and pass it

init_cb = CustomJS(code='''
                   var cbgq = document.querySelector(".bk-CheckboxGroup")
                   console.log(cbgq)
                   ''')
curdoc().js_on_event(DocumentReady,init_cb)
show(cbg)

This gets me to where @Bryan suggested:

But I’m not sure how to get at the CSS properties and update them based on conditions… or even if this is the right road to go down.

And alternatively…

Maybe it would be more easily implemented by specifying a css_classes property to my checkbox group? But then how do I know what to properties/specs to put in it?

Another related thread to this approach → Including CSS Classes for DataTable - #2 by gmerritt123 . Like in this thread i’m adjusting .slick-header-columns style etc… where/how do i find the equivalent for the checkbox group?

Suggestions/guidance most welcome… Thanks

After doing a bunch of reading/perusing, it’s likely that the whole setup needs to be different as of Bokeh 3xx → Migration Guides · bokeh/bokeh Wiki · GitHub . Any example/documentation/walkthroughs on an updated way of targeting certain widgets and styling them would be much appreciated (I’m pretty stuck).

cc @mateusz for any suggestions

Another update, I made some inroads by reading this → Styling DOM elements — Bokeh 3.1.0rc3 Documentation

I managed to turn the whole checkboxgroup area background color…

from bokeh.models import CheckboxGroup, Slider
from bokeh.models import InlineStyleSheet
from bokeh.plotting import save

cbgss = InlineStyleSheet(css="div.bk-input-group{ background-color: purple; }")
cbg = CheckboxGroup(labels = ['RED','YELLOW','BLUE'],active=[0,1,2]
                    ,stylesheets=[cbgss]
                    )
save(cbg,r'C:\Projects\dev\testcb.html')

… But targetting individual checkboxes inside that still eludes me…

Inspecting them…

I’m still missing two key pieces:

  1. I don’t know how to target input[type='checkbox']

Something like…
cbgss = InlineStyleSheet(css="div.bk-input-group.input[type='checkbox']{ background-color: purple; }")
doesn’t hit the intended target.

  1. It’s the ‘appearance’ attribute that i’m gonna have to modify ultimately I think to change the checkbox colors… which has auto, revert, and a few other options, but nothing explicit to get at the ‘enabled’ color property…

It seems to be embedded in here:

But yeah… how to target and edit THAT? No idea…

If I understand what you are looking for:

cbgss = InlineStyleSheet(css="""
  div.bk-input-group input[type='checkbox'] ~ span {
    background-color: purple;
  }
""")

I’m not a CSS expert, there’s maybe some better way than the sibling selector ~.

1 Like

Or if you wanted to alternate the labels, e.g.

cbgss = InlineStyleSheet(css="""
  div.bk-input-group label:nth-child(odd) span {
    background-color: purple;
  }
""")

The input and the label are siblings, so maybe that complicates things (again, I am very far from a CSS expert, so this may be non-idea approach :person_shrugging: )

1 Like

Awesome thanks, that gets me very close (and potentially close enough depending on how involved this next part is):

With the above sort of example, I’m able to write out different selectors for various values and adjust the label properties of individual checkbox items, e.g.

div.bk-input-group input[type='checkbox'][value="1"] ~ span { color: yellow; }

will target the middle checkbox in my example.

What I actually want to target is the color of the checkbox ICON when enabled/“on”…

Looking at the existing style, I THINK it’s the “#66afe9” assigned to border-color in .bk-input:focus →

At least that’s the only hex code corresponding to that shade of blue i can find…

How to target that?

div.bk-input-group input[type='checkbox'][value="1"].bk-input:focus{ 
                                                        border-color: red;                                                         
                                                        }

Doesn’t work… but I did notice that:

div.bk-input-group input[type='checkbox'][value="1"]{ 
                                                        appearance: none; 
                                                        }

can remove the icon entirely… and looking at it in the the browser editor:

There are options like initial/revert/auto etc. By putting appearance: none in my stylesheet I am overriding the appearance attribute from the user agent stylesheet… but I’m not able (yet) to “break in” any further and edit said appearance…

Unfortunately, completely independent of Bokeh, I have no idea how to accomplish this. I did a quick google and it seems that styling checkboxes is not really trivial (10s to 20s lines of CSS for the examples I found)

1 Like

I guess that answers that :joy:

Thanks for the help, big time

What I ended up implementing, for posterity’s sake.

My use case was to display different “scenarios” being toggled by a CheckboxGroup, so i have a list of scenarios (scenario_list) and a dictionary mapping a scenario to a desired color (scenario_cdict). The following snippet constructs a single InlineStyleSheet that maps each label in the CheckboxGroup to its corresponding color (note your CheckboxGroup labels need to be in same order as scenario_list)

ss_text = ['div.bk-input-group input[type="checkbox"][value="'+str(i)+'"] ~ span {background-color: '+scenario_cdict[s]+';}' for i,s in enumerate(scenario_list)]
ss_text = '\n'.join(ss_text)
print(ss_text)
cbg_ss = InlineStyleSheet(css=ss_text)
#then assign to checkboxgroup
cbg.stylesheets=[cbg_ss]

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