Are you using HTML in Markdown? Tell us why!

I use it to embed Folium maps (as html objects) in apps

1 Like

The MainMenu component doesn’t make sense for viewers coming to a deployed app, so we did
hide_menu_style = “”"

#MainMenu {visibility: hidden;}

st.markdown(hide_menu_style, unsafe_allow_html=True)

For what it’s worth, I tried using unsafe_allow_html to embed javascript for an analytics app. That didn’t work, which wasn’t a huge deal.


Hi @Chris_Brake.

Welcome to the community :+1:

Could you provide a smal example/ code snippet of the Folium maps. I think this would be of general interest.

I could include it in the Gallery at

Hi @Marc,
It’s probably more of a hack than an elegant solution tbh (!):

  1. create map using folium as save as html (which folium makes really simple)
  2. run a basic python web server in the directory where I store the map file(s)
    python3 -m http.server [port]
  3. Folium map now available as url
  4. Use markup to insert local link as iframe:
        f'<iframe width="{width}" height="{height}" src="{src}" frameborder="0" ></iframe>',

with src = the network url for the map
height = 900, width = 750 gives a nice portrait aspect ratio.

But I think the solution higher up this thread for creating & embedding Folium maps is probably better:

m = folium.Map(location=[45.5236, -122.6750])
    st.write(m._repr_html_(), unsafe_allow_html=True)

I’m currently using it to adjust layout and add some simple CSS styling:

st.markdown(f'<span class="badge badge-pill badge-success">{n_pass} Passing</span>', unsafe_allow_html=True)

I’d love the concept of themes or a cleaner way to style my streamlit apps.

Keep up the amazing work guys :heart:

1 Like

Linking to a post in the forum about specifying CSS in a div inside markdown for alignment.

I was rambling about injecting custom CSS and specifying a list of new CSS classes in an arg of st methods (if I can edit the markdown/write, what if I want to change the styling of the sidebar with st.sidebar.slider(...csslist=[".red", ".hide"]), or maybe expose a specific custom class per component (like .st-sidebar) to change in an external file.

I stumbled on @isaac’s hack, which I like a lot and will reuse :stuck_out_tongue: really a huge thanks for all those shared snippets !

Now I’m going to look for a way to change that sidebar color :upside_down_face:.


For markup of raw text in NLP. Highlighting certain features, original spacing, etc…
Streamlit formats the text which is nice but sometimes it is needed to see raw text and still use some custom formatting.


It’d be great to be able to adjust the background.
E.g. Creating a moving background using HTML and CSS.

1 Like

We’re using unsafe_allow_html in a few places now to inject css. The most recent is to make our Altair-based graphs responsive (they previously looked pretty bad on mobile).

canvas {
max-width: 100%!important;
height: auto!important;

I have a lot of trust in the Streamlit team, because you’re doing awesome stuff. But I’m still nervous about whether we’ll be able to replicate these css hacks after the deprecation…

1 Like

Hi Dan — thanks for the kind words!

Regarding your max-width hack, we’re probably going to have an official solution soon.

As for the Altair issue, can you create a bug report for it? This is the first time I’m hearing about it, but it sounds like something we should address too.

Regarding all the other things in this thread (and in assorted Github issues!), we have recently compiled a doc where we cluster everyone’s use-cases into categories and then brainstorm official solutions for each. So there is some progress, even though you can see it yet! Our goal really is to have clean solutions for the vast majority of things people are proposing here, and at his point I’m confident it’s doable.

More on this very soon!


Thanks. I may have mischaracterized things with the graphs looking bad. It was just that we previously set widths that made sense for desktop, and they were (as one would expect) too wide to look good on mobile.

So, the only issue was wanting the responsiveness we get from that css hack. Glad to hear there’s good solutions in the works =)

Thanks again for all the thought you’re putting into this


I just used html and css to generate a legend for pydeck charts. My map shows concentrations with a color gradient going from blue to green. I have not found a way in pydeck to generate this, so I included the code below, that renders a blue and a green dot with the corresponding value interval. Ideally of course, I could generate the legend with pydeck directly (maybe this is possible and I just did not find out how :smile:). Second best solution would be if I could generate Unicode symbols directly from streamlit:
st.write(st.symbol(#9679, blue) + ‘10-15’)
st.write(st.symbol(#9679, green) + ‘15-20’)
so something like this is shown:
:large_blue_circle: 10-15
:green_circle: >15-20

However, I find HTML/CSS very handy and fear it will be difficult to replace it by something similarly flexible.

legend = """
                .bdot {{
                height: 15px;
                width: 15px;
                background-color: Blue;
                border-radius: 50%;
                display: inline-block;
                .gdot {{
                height: 15px;
                width: 15px;
                background-color: #4DFF00;
                border-radius: 50%;
                display: inline-block;
                <div style="text-align:left">
                <span class="bdot"></span>  {} - {}<br>
                <span class="gdot"></span>  &#62;{} - {}
                """.format(round(min_val), round((max_val - min_val) / 2), round((max_val - min_val) / 2), round(max_val))
            st.markdown(legend, unsafe_allow_html=True)

I’m starting to experiment with converting an app to something that feels like dark mode.

body {
    color: #fff;
    background-color: #111;
    """, unsafe_allow_html=True)

There’s still some work needed to update all the colors like I’d want them, as well as adjusting the color pallete in plots so they don’t fry my corneas against the black background.

I may put it on hold until I there’s more info about how much CSS control we’ll have after the relevant changes. But it’d be nice to be able to do this.


I want to use html not due to formatting reasons, but because more and more python libraries render the output of analysis in HTML format.

As such, these are not html injected by me, but are directly generated by those packages after me inputting some legit input. They could be interactive charts or rich-formatted tables.

Without html function one would go extreme length to reverse-engineer the original package, by stopping the function one step short of the html output, then plot one’s own chart, basically re-do a lot of things already in those packages. Many times that’s not feasible.


I wanted to insert script tag with JS code. The code adds keyboards shortcuts to buttons in my Streamlit app.

Update: We heard you, and have no plans to deprecate allow_unsafe_html ! :champagne:

Thank you for sharing your thoughts. It’s really useful!! :pray:t2:


i just try ur code, but the maps didnt show, how ?thanks

1 Like

That’s great to hear, I had some nightmares about html being disabled :wink:

1 Like

I converted an ipynb notebook to a local html file and displayed it in streamlit.

    HtmlFile = open("sales_impact_report.html", 'r', encoding='utf-8')
    source_code = 
    st.markdown(source_code, unsafe_allow_html=True)

However, my output gives me this, how can i hide/remove the blocks before my header?

1 Like

Hi @Chris_Brake,
Thanks for your contribution.

I’m having trouble trying to make this work here. If I just use st.write(m.repr_html()), then copy the code and inject it manually in the page source code, my map shows ok.

But if I try to use st.markdown(m.repr_html(), unsafe_allow_html=True) the object uses the space in the page but shows nothing.

Did you face a similar problem? I can’t figure out what is going wrong.

If I inspect the page source code, all js code is missing after using st.markdown. For instance, if I add onload=“;this.contentDocument.write(atob(this.getAttribute(‘data-html’)));this.contentDocument.close();” before allowfullscreen the map is correctly shown.

This is the file I’m trying to replicate - (version 0.53.0):

import streamlit as st
import pandas as pd
import folium

all_cities = pd.DataFrame(
    [(40.7127837, -74.0059413),(34.0522342, -118.2436849),(41.8781136, -87.6297982)],
    ['New York', 'Los Angeles', 'Chicago'],

selected_city = st.selectbox('Select city', all_cities.index)

route_map = folium.Map(location=(all_cities.loc[selected_city]), zoom_start=9, control_scale=True)

aux = route_map._repr_html_()
st.markdown(aux, unsafe_allow_html=True)
1 Like