How do I use a background image on streamlit

Hey @timL!

I hacked it, but maybe someone has a better idea. For now, try this:

def sidebar_bg(side_bg):

   side_bg_ext = 'png'

   st.markdown(
      f"""
      <style>
      [data-testid="stSidebar"] > div:first-child {{
          background: url(data:image/{side_bg_ext};base64,{base64.b64encode(open(side_bg, "rb").read()).decode()});
      }}
      </style>
      """,
      unsafe_allow_html=True,
      )

Call this

side_bg = 'path_to_local_image'
sidebar_bg(side_bg)

I tried it locally and it works! :slight_smile:

5 Likes

Hello , i tried your code and it worked perfectly , i wonder would it work for gifs ?

Hey @tarek-kerbedj!

Welcome to the Streamlit community. :sparkles:

The code I shared works with gifs as well, just use

def sidebar_bg(side_bg):

   side_bg_ext = 'gif'

   st.markdown(
      f"""
      <style>
      [data-testid="stSidebar"] > div:first-child {{
          background: url(data:image/{side_bg_ext};base64,{base64.b64encode(open(side_bg, "rb").read()).decode()});
      }}
      </style>
      """,
      unsafe_allow_html=True,
      )

Call this

side_bg = 'path_to_local_image.gif'
sidebar_bg(side_bg)

Let me know if you can replicate. :slight_smile:

1 Like

Hey, @soft-nougat thanks a lot! It worked. You saved my day. :smiley:

1 Like

Hey, @soft-nougat your code is working great!
Is there any way to set the background image for a container only instead of the whole app?
Thank you!

Hey @Eevee!

Sorry for the late response, I am not sure how to approach this. I did use this approach to change the sidebar image only, you can see that I call the [data-testid=“stSidebar”] div and set an image - code below:

def sidebar_bg(side_bg):

   side_bg_ext = 'png'

   st.markdown(
      f"""
      <style>
      [data-testid="stSidebar"] > div:first-child {{
          background: url(data:image/{side_bg_ext};base64,{base64.b64encode(open(side_bg, "rb").read()).decode()});
      }}
      </style>
      """,
      unsafe_allow_html=True,
      )

Maybe this already helps - if not let me know. :slight_smile:

Hey @soft-nougat, thank you for the code!

Is there a way to change also the background of the top white strip (see the screenshot)?

I would use the same code as for the sidebar, but I don’t know how to identify that element.

Thanks!

1 Like

Hey @Andrea_Pesare! :slight_smile:

Glad you found the code useful. I cannot replicate the white bar on my end, but you can use this logic to find the div name:

Go to the white bar, inspect element and find the information on the name on the right. Try to change the name of the data-testid in the code below ([data-testid=“stSidebar”]) to the name you found on the right:

def sidebar_bg(side_bg):

   side_bg_ext = 'png'

   st.markdown(
      f"""
      <style>
      [data-testid="stSidebar"] > div:first-child {{
          background: url(data:image/{side_bg_ext};base64,{base64.b64encode(open(side_bg, "rb").read()).decode()});
      }}
      </style>
      """,
      unsafe_allow_html=True,
      )

It will probably take a few tries to get it right, but this is the logic I used to hack the sidebar :smiley:
Let me know how it goes!

Hi @soft-nougat, thank you so much!

That element should be the stHeader. I tried with

f"""
      <style>
      [data-testid="stHeader"] > div:first-child {{
          background: url(data:image/{img_ext};base64,{bin_str});
      }}
      </style>
"""

but it didn’t work, it only colored a tiny strip “behind” the real header. Then I tried

f"""
      <style>
      header.css-k0sv6k.e8zbici2 {{
          background: url(data:image/{img_ext};base64,{bin_str});
      }}
      </style>
"""

and it works! :slightly_smiling_face:

For reference, this is the result:

1 Like

How do I add a logo from my local to the title in streamlit.

Hi @Andrea_Pesare and others,

so the stHeader method doesn’t work but also finding the artificial “real” header name is not working. How to fix and set this straight?

f"""
     <style>
     header.css-k0sv6k.e8zbici2 {{
         background: url(data:image/{img_ext};base64,{bin_str});
     }}
     </style>
"""

Hello,

In the meantime, I documented my own process for coloring/imaging a background and finding the CSS classes necessary to change here: Custom Streamlit Background Image/Color Gradient through CSS - YouTube

It takes a bit of practice to find the correct css classes/attributes to use, and between Streamlit versions those CSS classes will change which is why you need to be able to find them by yourself through the devtools

Happy Streamlitin’
Fanilo

3 Likes

Hey, @soft-nougat your code is working great!
I wonder would it work for json files please? (that comes from the st_lottie function)
Thanks

Hey @julien-mcx!

I am not familiar with this, hope @andfanilo might be able to help?

Good luck :slight_smile:

Hello @julien-mcx

As far as I know the Lottie JSON encodes a full animation. You would probably need to extract an image from the animation to use as background image using Lottie Editor: Edit and customize Lottie animations - LottieFiles . The browser won’t know how to interpret the Lottie animation to use as background.

Hope this helps,
Fanilo

Thank you!

hi, i have been trying to add background image for my web page from my local disk ,but its not working the code you provided,here is my code: from PIL import Image

Title of the web app

st.title(“NOVO STAR eCRF Generator”)

Load the background image

st.cache(allow_output_mutation=True)
def get_base64_of_bin_file(bin_file):
with open(bin_file, ‘rb’) as f:
data = f.read()
return base64.b64encode(data).decode()

def set_png_as_page_bg(png_file):
bin_str = get_base64_of_bin_file(png_file)
page_bg_img = ‘’’

body {
background-image: url(“data:image/jpeg;base64,%s”);
background-size: cover;
}

‘’’ % bin_str

st.markdown(page_bg_img, unsafe_allow_html=True)
return

Update the path to your background image

background_image_path = “d:/novonordisk/star_2.jpg”

Call the set_png_as_page_bg function to set the background image

set_png_as_page_bg(background_image_path)

this helped alot and saved me alot of time!!! thank you!

Thank you so much, this worked for me too.
As mine is a chat window, i have added a background with the code below(same as yours) but the scroll is not working. any suggestions?

titleimg = “static/Picture7.png”
def set_bg_hack(main_bg):
# set bg name
main_bg_ext = “png”

st.markdown(
    f"""
     <style>
     .stApp {{
         background: url(data:image/{main_bg_ext};base64,{base64.b64encode(open(main_bg, "rb").read()).decode()});
         background-repeat: no-repeat;
         background-position: right 50% bottom 95%;
         background-size: contain;
         background-attachment: scroll;
     }}
     </style>
     """,
    unsafe_allow_html=True,
)

set_bg_hack(titleimg)

Hi, what worked for me to make the bg_image scrollable is to:

  1. change the selector from .stApp to .main
  2. background-attachment: scroll; → background-attachment: local;