Rendering of colored text for messages in st.chat_message for chatbot

I am facing an issue when rendering colored texts inside a chat message. The color of the text is generated as per the sentiment [I am doing sentiment analysis in chatbot]

The problem is when the page sits there for some time and it’s static and I rerun the script sometimes the color is shown. BUT as soon as I send a new prompt all the colors return to default(while).

This code works perfectly when it’s not rendered as a chat message ie. a normal markdown container.

I did try to add an explicit rerun() but it did not work.

def sentiment_color(sentiment: str) -> str:

    # Define a dictionary mapping sentiments to colors

    sentiment_colors = {"positive": "green", "negative": "red", "neutral": "blue"}

    return sentiment_colors.get(sentiment.lower())
# Display previous messages
for message in st.session_state.messages:
    # Displays a chat messages based on its roles stored in streamlit session state.

    with st.chat_message(message["role"]):
        if message["parts"]:
            if message["role"] == "user":

                st.markdown(
                    f"""
                    {message["parts"]}
                    :{sentiment_color(str(message["sentiment"]))}[{str(message["sentiment"]).upper()}]
                    """
                )

            else:
                st.markdown(message["parts"])
        if message["image"]:
            image_source = (
                "Uploaded Image" if message["role"] == "user" else "Generated Image"
            )
            st.image(message["image"], caption=image_source, use_container_width=True)

I also tried using CSS styling, but the results were same.

                sentiment_color_code = sentiment_color(str(message["sentiment"]))
                st.markdown(
                    f"""
                    {message["parts"]}  
                    <span style="color: {sentiment_color_code}; font-weight: bold;">
                        [{str(message["sentiment"]).upper()}]
                    </span>
                    """,
                    unsafe_allow_html=True,
                )

Expected Solution:
The sentiments are colored as per their properties and properly rendered in the chat.

Static Page when rerun:


(ignore the random text)

When I send a new message:


(it goes back to default)

Python 3.12.4
Streamlit 1.41.1
The app is locally deployed.

Solution:

Check any overriding CSS in your browser due to extensions or customizations.
Thanks, @edsaac for pointing it out.

I tried to reproduce the issue with a simplified version of the code but I was not able to. Perhaps you have other CSS injections conflicting with those text colors?

Code:
import streamlit as st
from collections import namedtuple

Message = namedtuple("Message", ["role", "parts", "sentiment"])

SENTIMENT_COLORS = {
    "positive": "green",
    "negative": "red",
    "neutral": "blue",
}

if "messages" not in st.session_state:
    st.session_state.messages = [
        Message("user", "Hello", "neutral"),
        Message("ai", "Hi <3", "positive"),
        Message("ai", "Bye >.<", "negative"),
    ]

# Display previous messages
for message in st.session_state.messages:
    role, parts, sentiment = message
    text_color = SENTIMENT_COLORS.get(sentiment.lower())

    with st.chat_message(role):
        st.markdown(f"{parts}\n\n:{text_color}[**{sentiment.upper()}**]")

new_chat = st.chat_input()

if new_chat:
    st.session_state.messages.append(Message("user", new_chat, "negative"))
    st.session_state.messages.append(Message("ai", "Some answer", "neutral"))
    st.rerun()
2 Likes

The closest I got to the white text overriding the sentiment color was using the HTML snippet that you provided and passing some invalid key, for which the get method returns None.

...

    with st.chat_message(role):
        st.html(
            f"""{parts}
            <span style="color: {text_color}; font-weight: bold;">
                [{sentiment.upper()}]
            </span>
            """
        )
...

if new_chat:
    # A Message with an unrecognized sentiment
    st.session_state.messages.append(Message("user", new_chat, "idk"))

My new guess is that your sentiment analysis tool returns something different than those three options you set colors for.

Perhaps you have other CSS injections conflicting with those text colors?

Oh my, I cannot believe I made such a silly mistake. It was a “browser extension”. I had a dark mode extension turned ON. It did not affect the rest of the page and colors so I never even thought about it

The dark mode is turned ON:


the colors are present (I think this has to do with how Streamlit renders its built-in elements vs the editable markdown)

Explicitly turning dark mode OFF and ON:


the colors are now weird (which is exactly why I never even considered that was causing the problem)

Thanks, @edsaac for pointing it out.

I am extremely embarrassed by my dumb mistake. Thank you so much for replying so promptly.
Have a beautiful day!

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