Changing the text color of only one metric

Hi, I have 3 different metrics but I need to change the text color of only one of them,
I tried this code snipped which changed all metrics text to red:

st.markdown("""
<style>
div[data-testid="metric-container"] {
   color: rgb(232, 0, 0);
}
</style>
""", unsafe_allow_html=True)

I thought maybe I could write it before that specific metric and then change it back with the same markdown just with color: black but it changed the previous metric too to red.

Is there any way to do it for specific metrics?

Hi @ImSo3K

Because your metric widgets are internally identified as ‘metric-container’, colour applied to 1 metric widget, will apply to all metric widgets on that page.

If you inspect the page and identify the class of a particular widget, and then apply colour changes only to that class, your app instructions may not work in the next version of Streamlit (as the widget class for a given widget may not be static across Streamlit versions).

The only easy way you can selectively change the CSS parameters of widgets on a page, is to go through the HTML using streamlit.components.v1 (There is a drawback in this, as it introduces a blank line / row onscreen with each invocation. In the code below, you have 4 invocations of the ColourWidgetText function, so there will probably be 4 blank lines after all the 3 metric widgets have been rendered onscreen).

Nevertheless, here’s an example of how you can do this with streamlit.components.v1

import streamlit as st
import streamlit.components.v1 as components

def ColourWidgetText(wgt_txt, wch_colour = '#000000'):
    htmlstr = """<script>var elements = window.parent.document.querySelectorAll('*'), i;
                    for (i = 0; i < elements.length; ++i) { if (elements[i].innerText == |wgt_txt|) 
                        elements[i].style.color = ' """ + wch_colour + """ '; } </script>  """

    htmlstr = htmlstr.replace('|wgt_txt|', "'" + wgt_txt + "'")
    components.html(f"{htmlstr}", height=0, width=0)

c1, c2, c3 = st.columns(3)
c1.metric('Metric1', value=10)
c2.metric('Metric2', value=50)
c3.metric('Metric3', value=70)

ColourWidgetText('Metric1', '#00B0F0')  # colour only metric text
ColourWidgetText('10', '#FF0000')       # colour metric value

ColourWidgetText('Metric2', '#FF0000')
ColourWidgetText('Metric3', '#00B050')

The result will be:
metric pix

I have used hex colour codes, but you can modify the code to use rgb instead.

You can use or extend this code to selectively colour your other widgets on the basis of their label text. Additionally, you can also add other parameters such as background colour, etc., to the function if/as required.

Hopefully, Streamlit will soon give us an option to natively do this, as everyone is eventually going to cosmetically customise their own app regardless.

Cheers

1 Like