Here’s a quick answer based on the same mechanism of using the label to color the buttons, It needs a little extra tweak if you want the button font color to remain the hover color after it’s clicked instead of just having the box shadow linger. It’s set for dark mode, but there are lines at the top for you to switch out if you are in light mode or have a custom theme.
If you use the other mechanism I mentioned with nth-of-type
selectors, you can get away with simpler CSS instead of JavaScript, but that’s just trading one kind of mess for another.
import streamlit as st
import streamlit.components.v1 as components
#if you have specified a theme, you can get the border color with:
#border = st.get_option('theme.secondaryBackgroundColor')
#border = 'rgb(49,51,63,.2)' #light mode
border = 'rgb(250,250,250,.2)' #dark mode
def ChangeButtonColour(widget_label, font_color, hover_color, background_color='transparent'):
htmlstr = f"""
<script>
var elements = window.parent.document.querySelectorAll('button');
for (var i = 0; i < elements.length; ++i) {{
if (elements[i].innerText == '{widget_label}') {{
elements[i].style.color ='{font_color}';
elements[i].style.background = '{background_color}';
elements[i].onmouseover = function() {{
this.style.color = '{hover_color}';
this.style.borderColor = '{hover_color}';
}};
elements[i].onmouseout = function() {{
this.style.color = '{font_color}';
this.style.borderColor = '{border}';
}};
elements[i].onfocus = function() {{
this.style.boxShadow = '{hover_color} 0px 0px 0px 0.2rem';
this.style.borderColor = '{hover_color}';
this.style.color = '{hover_color}';
}};
elements[i].onblur = function() {{
this.style.boxShadow = 'none';
this.style.borderColor = '{border}';
this.style.color = '{font_color}';
}};
}}
}}
</script>
"""
components.html(f"{htmlstr}", height=0, width=0)
cols = st.columns(4)
cols[0].button('first button', key='b1')
cols[1].button('second button', key='b2')
cols[2].button('third button', key='b3')
cols[3].button('fourth button', key='b4')
ChangeButtonColour('second button', 'red', 'blue') # button txt to find, colour to assign
ChangeButtonColour('fourth button', '#c19af5', '#401000', '#354b75') # button txt to find, colour to assign