Change metric color, font, background and style

How can I change the metric box color and the inside font color?

I figured it out:
create a style. css file and get the metric’s css class name by inspecting the metric element.

/* metric styling */
div.css-rikpzh.e1tzin5v3{
			background-color: rgba(28, 131, 225, 0.1);
			border: 1px solid rgba(28, 131, 225, 0.1);
			padding: 5% 5% 5% 10%;
			border-radius: 5px;
			color: rgb(30, 103, 119);
			overflow-wrap: break-word;
		}
/* breakline for metric text		 */
div.css-1ht1j8u{
			overflow-wrap: break-word;
			white-space: break-spaces;
		}

and in app.py

with open ('style.css') as f:
			st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
st.metric(label="This is a very very very very very long sentence", value="70 °F")
1 Like

I don’t believe this solution is stable as the classes, e.g., css-rikpzh e1tzin5v3, are not stable. They appear to be dynamically generated class names. Having said that, it’s all we have.

@asehmi Does that mean the class names may suddenly change? What triggers the change?

Not sure… but this issue has always been cited as a caveat of these CSS hacks.

1 Like

A new version will change the dynamically generated CSS classes.
Generally CSS classes that start with st or div attributes are considered a bit more stable because they are manually implemented. They may change on a version where the devs decide to change style guide, though this shouldn’t happen often.

import streamlit as st

st.markdown("""
<style>
div[data-testid="metric-container"] {
   background-color: rgba(28, 131, 225, 0.1);
   border: 1px solid rgba(28, 131, 225, 0.1);
   padding: 5% 5% 5% 10%;
   border-radius: 5px;
   color: rgb(30, 103, 119);
   overflow-wrap: break-word;
}

/* breakline for metric text         */
div[data-testid="metric-container"] > label[data-testid="stMetricLabel"] > div {
   overflow-wrap: break-word;
   white-space: break-spaces;
   color: red;
}
</style>
"""
, unsafe_allow_html=True)

st.metric(label="This is a very very very very very long sentence", value="70 °F")

Have a nice day!
Fanilo

3 Likes

Good to know @andfanilo! So this is why some divs have a data-testid attribute. :thinking: Agree with you, and I’ve been using the st* div containers where I can.

One more question: @andfanilo
why isn’t the stMetricValue working for me?

/* breakline for metric text		 */
div[data-testid="metric-container"] > label[data-testid="stMetricLabel"] > div {
			overflow-wrap: break-word;
			white-space: break-spaces;
			
		}

div[data-testid="metric-container"] > label[data-testid="stMetricValue"] > div {
			font-size: large;
}

Hello,

would you please tell me how to put a thousand separators in metric value?

metric

@R_D The reason this isn’t working is that the item with testid = stMetricValue isn’t a label, it’s a div (at least currently)

Hello all,
I’m new here.
I found this topic really interesting for my project.
I would like to ask you, if anyone knows, if it is possible and how to change the colour of one specific container on the basis of a condition.
Example: if the value of the metric is higher than a certain threshold, the colour of the container (or its number) should become red. All the others should not change.
Thank you to everyone will reply to my question. :slight_smile:

1 Like

I have the same question :slight_smile:

Hello,
This code is very helpful! I just wonder, is it possible to change the font size of “stMetricLabel”? When I add font-size: 100%, nothing happens.

st.markdown("""
<style>
div[data-testid="metric-container"] > label[data-testid="stMetricLabel"] > div {
   overflow-wrap: break-word;
   white-space: break-spaces;
   color: red;
   font-size: 100%;
}
</style>
"""
, unsafe_allow_html=True)```

Hi @panda_mv, welcome to the forum!

The reason it’s not working is that there is a more specific selector that is overriding the changes you’re trying to make to the font size.

You can fix this by specifying the styling on the p tag inside the div, and using !important

import streamlit as st

st.markdown(
    """
<style>
div[data-testid="metric-container"] > label[data-testid="stMetricLabel"] > div {
   overflow-wrap: break-word;
   white-space: break-spaces;
   color: red;
}
div[data-testid="metric-container"] > label[data-testid="stMetricLabel"] > div p {
   font-size: 200% !important;
}
</style>
""",
    unsafe_allow_html=True,
)

st.metric("Value!", 1.2, 1.0)
1 Like

Thanks a lot for the quick reply!!! It’s working :upside_down_face: