Wing
Wing

Reputation: 992

Streamlit how to display buttons in a single line

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?

Upvotes: 20

Views: 36602

Answers (5)

Branden Keck
Branden Keck

Reputation: 572

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. 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="stColumn"] {
                    width: fit-content !important;
                    flex: unset;
                }
                div[data-testid="stColumn"] * {
                    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(...)

Upvotes: 9

Jack Damiani
Jack Damiani

Reputation: 151

I wanted to point out that sometimes you might want 2 buttons right next to each other. I've adapted some of these solutions to line up two buttons (in this case a thumbs up and thumbs down) to be right next to each other. The trick is to use a 3rd column for buffering so that the buttons can be next to each other. This can be resized to apply for different conditions.

Here is the code:

col1_, col2_, col3_ = st.columns([1,1,12])
with col1_:
    st.button("👍")
with col2_:
    st.button("👎")
with col3_:
      pass

Upvotes: 4

ggorlen
ggorlen

Reputation: 57195

Generalizing 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")

Upvotes: 4

Constantine Kurbatov
Constantine Kurbatov

Reputation: 905

I 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): enter image description here

Upvotes: 3

Wing
Wing

Reputation: 992

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')

Upvotes: 33

Related Questions