Hi all I am building a simple web app with streamlit in python. I need to add 3 buttons but they must be on the same line.
Obviously the following code puts them on three different lines
st.button('Button 1') st.button('Button 2') st.button('Button 3') Do you have any tips?
14 Answers
Apparently this should do it
col1, col2, col3 = st.columns([1,1,1]) with col1: st.button('1') with col2: st.button('2') with col3: st.button('3') 1I had a similar problem - to add an action button to a table. I came to the following approach:
import streamlit as st # # Show users table colms = st.columns((1, 2, 2, 1, 1)) fields = ["№", 'email', 'uid', 'verified', "action"] for col, field_name in zip(colms, fields): # header col.write(field_name) for x, email in enumerate(user_table['email']): col1, col2, col3, col4, col5 = st.columns((1, 2, 2, 1, 1)) col1.write(x) # index col2.write(user_table['email'][x]) # email col3.write(user_table['uid'][x]) # unique ID col4.write(user_table['verified'][x]) # email status disable_status = user_table['disabled'][x] # flexible type of button button_type = "Unblock" if disable_status else "Block" button_phold = col5.empty() # create a placeholder do_action = button_phold.button(button_type, key=x) if do_action: pass # do some action with row's data button_phold.empty() # remove button And it works fine. The object — user_table — is a dictionary very similar to DataFrame, where each key — is a column (i.e. list in pythonic terms). And here how it looks like (Note “Blocked” — that is the result of action): 
If you're like me, it might bother you that the columns equally space, making layout not visually appealing because the buttons appear far apart.
After a lot of CSS digging, I found a pretty simple approach that doesn't require any other library installs. After creating the columns as show above, it is possible (at least for the current version of streamlit) to apply the following CSS to make columns only as wide as the button. I included this at the top of my file:
st.markdown(""" <style> div[data-testid="column"] { width: fit-content !important; flex: unset; } div[data-testid="column"] * { width: fit-content !important; } </style> """, unsafe_allow_html=True) And then (for my use case):
col1, col2, col3 = st.columns([1,1,1]) with col1: st.button(...) with col2: st.button(...) with col3: st.download_button(...) 1Generalizing this answer a bit to use a dynamic number of buttons:
import streamlit as st # 1.18.1 button_text = "foo", "bar", "baz" for text, col in zip(button_text, st.columns(len(button_text))): if col.button(text): col.write(f"{text} clicked") If the text isn't necessarily unique:
button_text = "foo", "bar", "foo" pairs = zip(button_text, st.columns(len(button_text))) for i, (text, col) in enumerate(pairs): if col.button(text, key=f"{text}-{i}"): col.write(f"{text}-{i} clicked")