Center Streamlit Button
Asked Answered
S

8

18

How do I center a button with Streamlit so that the button is still clickable? Here is a small example for a button that returns random numbers:

 import streamlit as st 
 import numpy as np

 if st.button('Click'): 
     rand = np.random.standard_normal()
     st.write(str(rand))

I've seen solutions with markdown for a title, but not for an interactive element like a button.

Shanaeshanahan answered 26/2, 2020 at 10:10 Comment(3)
Can you explain what do you mean by "center" the button?Leung
@Leung I am referring to the horizontal alignment of the button. To make it appear in the middle of the app and not left-aligned as is the default.Shanaeshanahan
Any update on this?Pippy
B
14

Right now that’s not supported in Streamlit, but we are working on it (see our Roadmap for more info). Feel free to add your ideas to Customizable Layout for Streamlit discussion.

And thanks for using Streamlit!

Ballast answered 9/3, 2020 at 7:20 Comment(2)
Is the solution via the columns (see comments above) the solution from the roadmap? Or is there a more tailored solution on the roadmap?Shanaeshanahan
At this moment there is no "official" solution to this problem. That issue is on our roadmap, but it's not at the top of it. I'll add the solution here as soon as it's available. Sorry for the inconvenience!Ballast
B
9
col1, col2, col3 = st.beta_columns(3)
if col2.button('Click'):
    st.write('hello')
Breslau answered 20/3, 2021 at 18:2 Comment(1)
The button is in the middle column but not centeredKayseri
P
5

As far as I know there is no standard way to align the button in the center. I have however found a quick fix. It's not the right way but does the job.

You can try out :

col1, col2, col3 , col4, col5 = st.beta_columns(5)

with col1:
    pass
with col2:
    pass
with col4:
    pass
with col5:
    pass
with col3 :
    center_button = st.button('Button')

The following will create 5 columns and you can center your button in the third one while the other 4 remain empty. This is just a quick fix and not the correct way however it did the job for me. Hope you liked it.

Parttime answered 15/3, 2021 at 11:40 Comment(1)
st.beta_columns(5)[2].button("Button") seems easier, without all of the withs and passes. Note that you've called the return value of st.button() center_button, but really this is a boolean whether the button was clicked, so I'd call it is_center_button_clicked or something like that.Wuhsien
W
5

TL;DR;

import streamlit as st

st.markdown("----", unsafe_allow_html=True)
columns = st.columns((2, 1, 2))
button_pressed = columns[1].button('Click Me!')
st.markdown("----", unsafe_allow_html=True)

You will get the following result (if default: narrow streamlit page settings): enter image description here

Streamlit columns

Streamlit docs define columns() in the following way:

columns = st.columns(spec)

where spec is either int or a list (or a tuple). For example, st.columns([3, 1, 2]) creates 3 columns where the first column is 3 times the width of the second, and the last column is 2 times that width. Hence, you may play around with their relative width.

What is more useful, you will get a list of columns, so you may address them as consequent numbers. You may use that in case of flexible numbers of columns:

import streamlit as st
import random

column_qty = random.randint(1, 10)  # random number of columns on each run
buttons_pressed = []  # here we will collect widgets
st.markdown("----", unsafe_allow_html=True)

#  Create all columns with random relative widths
columns = st.columns([random.randint(1, 3) for _ in range(column_qty)]) 

# Show widgets in them
for x, col in enumerate(columns):
    # if you need a static widget, just use: `col.text("some text")`
    buttons_pressed.append(col.checkbox(f'{x}')) # add widgets to the list to be able checking their state later
st.markdown("----", unsafe_allow_html=True)
st.text(f'Total columns: {column_qty}')

# Check each widget for its state and display the index of the checked squares.
for x, btn in enumerate(buttons_pressed):
    if btn:
        st.write(f"{x}")  # NOTE: some columns may be dropped next run! 

enter image description here

A very useful thing for flex input forms.

Wrac answered 12/6, 2022 at 2:31 Comment(0)
I
1

Use:

_, _, _, col, _, _, _ = st.columns([1]*6+[1.18])
clicked = col.button('Button')
Impoverish answered 17/11, 2021 at 13:0 Comment(1)
post some explenation why this works and your answer is better compared against your fellow posters. End of Review.Vociferous
W
1

To create 3 columns, pick the center one and add a button to it, you can use:

import streamlit as st  # 1.18.1

if st.columns(3)[1].button("click me"):
    st.write("clicked")

This doesn't center the button within the column, though, so hacking the CSS seems to be a current option, but I suspect the classes aren't reliable:

style = "<style>.row-widget.stButton {text-align: center;}</style>"
st.markdown(style, unsafe_allow_html=True)

with st.empty():
    if st.button("click me"):
        st.button("clicked!")

Another centering approach, following existing answers, is to force the button's container to be smaller so it takes up most or all of the space in it, functionally centering it:

col = st.columns(7)[3]  # use an odd number and pick the middle element
clicked = col.button("click me")

Better than that might be to keep 3 columns, but make the first and last large and fit the middle one roughly to the button size. Adjust to taste:

col = st.columns((3, 1, 3))[1]  # adjust to taste, possibly using floats
clicked = col.button("click me")

Removing the flex property with custom CSS might help make this robust to different screen sizes so the button text doesn't squish when shrunk.

None of these approaches are entirely satisfactory, so I'm curious to hear any new developments.

See also How to center the title and an image in streamlit?.

Wuhsien answered 16/2, 2023 at 19:39 Comment(0)
C
0

to solve this problem, you can use:

col1, col2, col3 = st.columns([0.26, 0.3, 0.1])
with col1:
   pass
with col2:
   btn = st.button("your_button")
   if btn:
      st.write('clicked')
with col3:
   pass

In this code, it is known that our button will be placed at the beginning of the second column (col2). To adjust the position of the button to the left or right, you can simply modify the width of the first column col1(0.26). By adjusting the width percentage of col1, you can move the button accordingly. Please ensure that the sum of the width percentages for all columns remains less than or equal to 1. The width percentage of the third column (col3) is not relevant to the button's placement.

Cedar answered 18/6, 2023 at 18:22 Comment(0)
S
0

I needed to center in a sidebar, so the other solutions did not work for me.

To center all buttons one can use:

# center button in sidebar
st.markdown(
    """
    <style>
        [data-testid=stSidebar] [data-testid=stButton]{
            text-align: center;
            display: block;
            margin-left: auto;
            margin-right: auto;
            width: 100%;
        }
    </style>
    """, unsafe_allow_html=True
)
Spermatozoon answered 1/8, 2024 at 17:6 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.