Are you using HTML in Markdown? Tell us why!

Thanks for the info @tbatchelli and @cajones! Super useful.

Based on what you’re saying, I think when we add support for horizontal layouts we should probably also support grid layouts. So I created a feature request here: https://github.com/streamlit/streamlit/issues/309 .

Please follow the feature there to be notified when we implement it. And help us come up with a nice API for it too!

5 Likes

My use case is embedding youtube videos

There already is a video widget. It would be cool to be able to give it a youtube link.

3 Likes

Great idea. Feature request created: Ability to pass URLs (and YouTube link!) to st.video · Issue #348 · streamlit/streamlit · GitHub

For now i just do

def video_youtube(src: str, width="100%", height=315):
    """An extension of the video widget
    Arguments:
        src {str} -- A youtube url like https://www.youtube.com/embed/B2iAodr0fOo
    Keyword Arguments:
        width {str} -- The width of the video (default: {"100%"})
        height {int} -- The height of the video (default: {315})
    """
    st.write(
        f'<iframe width="{width}" height="{height}" src="{src}" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>',
        unsafe_allow_html=True,
    )

I guess I will be developing more extensions using html as I continue. You can find them in for inspiration

1 Like

I would like to create a tooltip to provide more info related to an item on my app. So, once a user hovers over it, the tooltip should be displayed. Is there a way to achieve this at the moment?

One more question that is related to HTML:
Is there a way to customize the HTML of the default index page and add custom CSS styling as well, etc.?
Thanks for the amazing app. It’s really amazing, and speeds up everything. Thanks a million!

3 Likes

@jeremie’s usecase is embedding SVGs in Streamlit.

Hi. The use case that came to my mind (and actually how I found this page) is embedding an interactive code/text editor like this one: https://ace.c9.io/

I’m using it to add <hr> in the sidebar, to separate groups of related widgets:

st.sidebar.markdown("<hr>", unsafe_allow_html=True)
1 Like

<hr> is supported in Streamlit markdown with ---. So you could do something like this:


import streamlit as st

st.sidebar.subheader("Component 1")

t1 = st.sidebar.text_input("Component 1 name")
s1 = st.sidebar.slider("Component 1 value")

st.sidebar.markdown("---")

st.sidebar.subheader("Component 2")
t2 = st.sidebar.text_input("Component 2 name")
s2 = st.sidebar.slider("Component 2")

st.title("Hello!")

st.write(t1, s1)
st.write(t2, s2)

5 Likes

I would like to embed graph visualisations based on d3js (e.g. based on this library https://github.com/vasturiano/force-graph) in my streamlit app. Is this even possible?

Hi @arminp

Thanks for the info! I’m actually not even sure you’ll be able to make that work with the limited HTML that is supported in Markdown.

Our long term solution for situations like yours will be an easy-to-use plug-in architecture. You can follow the feature request here: https://github.com/streamlit/streamlit/issues/327

Thanks @thiago for the fast response! I’ll track the feature request :slight_smile:

I am still wondering about a temporary workaround. So far, I need to run a separate local python server to access the visualisation htmls (because of the browser’s same-origin policy). Would it be possible for me to copy the vis-htmls to the local streamlit folder, in order to access them from the same port as streamlit (8501 for instance)?

EDIT: Found the static html folder, I’ll just symlink my generated htmls inside it for the time being. It’s a bit of a sketchy workaround, but it’s okay for now! Being able to embed js in streamlit at some point would be awesome!

Hello,
I’m using the allow html option to display Spacy NER model’s output, here’s my code :

doc = nlp(text)
html_page = displacy.render([doc], style=“ent”, page=True)
st.write(html_page,unsafe_allow_html=True)

2 Likes

I use st.markdown with unsafe_allow_html to inject custom CSS and Google Material Design icons.

4 Likes

Hi Isaac,

Thanks for your note.

Could you please help me with a sample ?

Thanks
Iyyappan

Yeah, sure. Here is an example of loading custom CSS.

st.markdown('<style>h1{color: red;}</style>', unsafe_allow_html=True)

And here is an example of loading a custom icon after I’ve included the icon CSS library using the hack above.

st.markdown('<i class="material-icons">face</i>', unsafe_allow_html=True)

More direct support for custom css using like st.css(css: str | dict) and custom icons using like st.icon('face') would be amazing.

7 Likes

Thanks a lot Isaac. You saved my day.

Hi Isaac,

Sorry to disturb you again. Could you please help me with how to import material-icons as you mentioned in the following line?
st.markdown(‘face’, unsafe_allow_html=True)

  1. Download the Google Material Design CSS stylesheet from https://fonts.googleapis.com/icon?family=Material+Icons locally to e.g. icons.css.
  2. Load css using hack I specified above.
st.markdown('<style>' + open('icons.css').read() + '</style>', unsafe_allow_html=True)
  1. Display icon by injecting icon html.
st.markdown('<i class="material-icons">face</i>', unsafe_allow_html=True)

But it would be awesome if the maintainers could add st.css() and st.icon() features.

8 Likes

That’s a cool idea, but we’ll have to think a bit about how it fits with the rest of the API. For example, should icons be clickable? How would st.css interop with our planned horizontal/grid layout APIs? etc.

In the meantime, you could always create your own library and share with the community through Github :smiley:

Something like:

(NOTE: This code is untested!)

import streamlit as st

def local_css(file_name):
    with open(file_name) as f:
        st.markdown('<style>{}</style>'.format(f.read()), unsafe_allow_html=True)

def remote_css(url):
    st.markdown('<style src="{}"></style>'.format(url), unsafe_allow_html=True)

def icon_css(icone_name):
    remote_css('https://fonts.googleapis.com/icon?family=Material+Icons')

def icon(icon_name):
    st.markdown('<i class="material-icons">{}</i>'.format(icon_name), unsafe_allow_html=True)
3 Likes