How to style st.expandable

Summary

Build a streamlit that display the results from dataframe inside expandables , where the expandables are styled based on the value of the column ‘position’.

Steps to reproduce

Code snippet:

import streamlit as st
import pandas as pd

# Create a dataframe
df = pd.DataFrame({
    "name": ["John Doe", "Jane Doe", "Peter Smith"],
    "position": ["CEO", "Boss", "Employee"],
    "salary": [100000, 50000, 30000]
})

# Define the style of the expandables
def style_expandable(position):
    if position == "CEO":
        return {"color": "red", "font-weight": "bold"}
    elif position == "Boss":
        return {"color": "blue", "font-weight": "bold"}
    else:
        return {"color": "black", "font-weight": "normal"}

# Create the expandables
for i, row in df.iterrows():
    with st.expander(row["name"], expanded=False, style=style_expandable(row["position"])):
        st.text_input("Name:", row["name"])
        st.text_input("Position:", row["position"])
        st.text_input("Salary:", row["salary"])


Expected behavior:

Display 3 expandables where each one has different style based on the value of position column.

  • Streamlit version: 1.25
  • Python version: 3.10
  • Using Conda? PipEnv? PyEnv? Pex?
  • OS version: windows 10

@leb_dev You can use st.markdown() to inject custom CSS based on either the class name of the element you are targeting or the full CSS selector (use browser’s inspect element to get those)

st.markdown("""
<style>
  .classnameofelement {
        your css properties
  }
</style>

""", unsafe_allow_html=True)

I already use this st.markdown based on the inspect browser but this technique will styled all the expandable or all the widgets that have the same class with the same style.

I want to make the style of the expandable differ based on a value .

I see, that’s more of a JS thing, if u can get the element by id&or class name and assign the style properties based on the change of the value using javascript, the issue would be inject JS scripts, it’s possible to a certain degree with streamlit’s html component but I don’t think it can read and send back values, I suggest to look into creating you’re own component for this case
You can check the docs for further info:

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