Hello, I am trying to figure out a way to select a color from a predetermined color schema.
Solution 1 - Color picker : As far as I know, st.color_picker doesn’t allow restricting the colors to a specified selection.
Solution 2 - Selectbox: This is the solution that I currently use, and I think matches my requirements the most, but it’s not user-friendly at all, since the user needs to do their selection based on the color number, not the color. (see screenshot)
I tried to play a bit with the labels of the selectbox, to at least display the color in the label once selected, but it wasn’t relliable on color change or color removing. It could help the user for sure, but it’s still far from ideal since the user would need to select the color to see it.
If anyone has had a similar issue / requirement I’ll gladly take on advices. Maybe there is a widget that can do that but I didn’t find it.
Hello ! I don’t know if it is a satisfying option for you but you can use CSS and the n-th child property ! Here is a working example, do not hesitate to ask for more precise use cases:
import streamlit as st
def generate_css_for_options(colors: list) -> str:
css = "<style>"
for i, color in enumerate(colors):
css += (
f"""ul[data-testid="stSelectboxVirtualDropdown"] li[role="option"]:nth-child({i + 1})"""
+ "{"
+ f"background-color: {color['code']}; color: {color['text_color']};"
+ "}"
)
return f"{css}</style>"
def generate_css_for_box(color_name: str) -> str:
css = "<style>"
for color in colors:
if color["name"] == color_name:
css += (
"""div[data-baseweb="select"] div {"""
+ f"background-color: {color['code']}; color: {color['text_color']};"
+ "}"
)
return f"{css}</style>"
colors = [
{"code": "#101B58", "name": "Penn Blue", "text_color": "#FFFFFF"},
{"code": "#45296C", "name": "Tekhelet", "text_color": "#FFFFFF"},
{"code": "#793780", "name": "Eminence", "text_color": "#FFFFFF"},
{"code": "#AD4594", "name": "Fandango", "text_color": "#FFFFFF"},
{"code": "#E153A8", "name": "Brilliant Rose", "text_color": "#FFFFFF"},
{"code": "#F0A998", "name": "Melon", "text_color": "#FFFFFF"},
{"code": "#F8D490", "name": "Sunset", "text_color": "#000000"},
{"code": "#FFFF88", "name": "Icterine", "text_color": "#000000"},
]
st.markdown(generate_css_for_options(colors), unsafe_allow_html=True)
options = [color["name"] for color in colors]
st.markdown(
generate_css_for_box(st.session_state.get("color_selected", colors[0])),
unsafe_allow_html=True,
)
st.selectbox(label="Choose a color", options=options, key="color_selected")
Thanks a lot, that works quite well, but it ends up coloring all the other selectboxes no ? Or am I missing something ?
I think I read somewhere that streamlit is planning to put the key in the css, so that should allow this code to work only for specified selectboxes haha.
You could create PNG images and display them inline. It’s not supported yet for Selectbox options (though there is an open PR for it). However, you could use st.pills.
Yes after some tests the solution has two major issues :
All the other selectboxes are colored. To fix this, you could create a unique combination of containers and columns that encapsulates the selectbox you want to color and make a more precise CSS selector. This works well but is not very flexible especially in large applications.
If you have many colors and scroll down, some options will not be rendered anymore and thus the nth-child property will not work as wanted.
If you want, I can help you on the first option ! Or if it is really needed you could also create a custom component !
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.