15

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.

jkortner
  • 549
  • 2
  • 8
  • 23
  • Can you explain what do you mean by "center" the button? – theletz Mar 01 '20 at 05:41
  • @theletz 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. – jkortner Mar 03 '20 at 17:34

7 Answers7

12

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!

Henrikh Kantuni
  • 901
  • 11
  • 14
  • 1
    Is the solution via the columns (see comments above) the solution from the roadmap? Or is there a more tailored solution on the roadmap? – jkortner Mar 24 '21 at 11:25
  • 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! – Henrikh Kantuni Mar 25 '21 at 23:43
9
col1, col2, col3 = st.beta_columns(3)
if col2.button('Click'):
    st.write('hello')
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.

  • `st.beta_columns(5)[2].button("Button")` seems easier, without all of the `with`s and `pass`es. 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. – ggorlen Feb 16 '23 at 19:32
4

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 defines columns() in the following way:

columns = st.columns(spec)

where specs are 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 arbitrary 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
st.markdown("----", unsafe_allow_html=True)
st.text(f'Total columns: {column_qty}')

# Check each widget for its state
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.

1

Use:

_, _, _, col, _, _, _ = st.columns([1]*6+[1.18])
clicked = col.button('Button')
H. Shad
  • 97
  • 1
  • 5
  • 3
    post some explenation why this works and your answer is better compared against your fellow posters. End of Review. – ZF007 Nov 17 '21 at 13:56
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?.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
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.