Add spacing between tabs

Hi all! I am using st.tabs (st.tabs - Streamlit Docs) and would like to add some horizontal spacing between the tabs’ titles, as they are very close to each other and make the page feel a bit cluttered.

Is there a way of doing this, or a hack/workaround to achieve this same result?

1 Like

This is probably not the best way but adding some whitespace characters to the tab labels can help with that:

listTabs = [
    "A tab",
    "More tabs",
    "A long loooooong tab",

st.header("Tab alignment")
st.subheader("No fill:")
tabs = st.tabs(listTabs)


whitespace = 9
st.markdown("#### 💡 Center fill with whitespace (em-space):")
## Fills and centers each tab label with em-spaces
tabs = st.tabs([,"\u2001") for s in listTabs])

st.markdown("#### 🤔 Center fill with visible character")
tabs = st.tabs([,"-") for s in listTabs])

st.markdown("#### ❌ Regular spaces are stripped down by streamlit")
tabs = st.tabs([," ") for s in listTabs])

This is a nice workaround! Thanks:) Do you happen to know how one could make the font of the tabs’ titles bigger too? Its default size is very small but I can’t find a way to customize it

Nice one @edsaac! Today I learnt about :smiling_face:

For streamlit >= 1.16.0

See, you would need:

font_css = """
button[data-baseweb="tab"] > div[data-testid="stMarkdownContainer"] > p {
  font-size: 24px;

st.write(font_css, unsafe_allow_html=True)

For streamlit < 1.16.0

@tommaso-moro you can give the following a try:

tabs_font_css = """
button[data-baseweb="tab"] {
  font-size: 26px;

st.write(tabs_font_css, unsafe_allow_html=True)

Here’s how a full example would look like:


This is absolutely great! Thank you so much. I am curious about how you knew that button[data-baseweb=“tab”] was the element that needed to be styled. When I first faced the font size issue, I did not know what to apply the CSS to in order to change the font-size (I reckon Chrome’s inspect tools can be helpful though?). How did you know that? Is there any documentation on which CSS elements are relevant to which Streamlit components?

Glad it helped @tommaso-moro! To find out about button[data-baseweb=“tab”], I used Chrome inspection.

Currently there isn’t any documentation on which CSS elements to use. There are two reasons for it:

  1. If we were to document those CSS classes, we would then “commit” to keep the classes consistent through time so as not to break compatibility across releases. We’re not there yet! And it’s slightly overkill considering… :point_down:

  2. Streamlit does not provide a clean way to edit those classes besides the hacky st.write(... unsafe_allow_html=True")

One solution to those two things would be that we introduce some nice API endpoint to style elements in Streamlit, hence settling on CSS classes and documenting them would make sense. But although this has been raised already, we are still debating whether such high customization capabilities is something we truly want for Streamlit :upside_down_face:

Btw can I ask you how you would use such customization beyond the font for tabs titles? Have you encountered other use cases?


Thank you @arnaud for your exhaustive reply! That makes a lot of sense :slight_smile:

To be honest, I wouldn’t use such customization too extensively mainly because (i) streamlit’s components come with consistency built in which is something that is not trivial to achieve when designing a UI/UX from scratch and having total styling freedom in my opinion and (ii) if I were to find myself bending Streamlit’s native capabilities to serve my needs too much I would feel like I am fighting the framework instead of harnessing its power, and would therefore look to move to away from it and towards alternative ways of building my app that give me more styling freedom (e.g. using a more traditional fullstack, with something like React + UI library/tailwind in the frontend).

That being said, I do think Streamlit users would benefit a lot if widgets had default styling options at least for the “main” stuff such as font size, background color, text color, width, height to name a few. While I can see why it’s overkill to enable full customisation of Streamlit’s native components (something that not even UI component libraries do!), I also fear that being too rigid (i.e. not enabling any customisation) is also not ideal as one could build an app whose UI/UX could improve drastically with very minor changes (stuff like making the font size in the tabs a bit bigger) but is instead stuck with what they have.

For instance, in the app I am building I do change the color of the text in some places (by making it green or red depending on the kind of information it conveys for instance). Using hacky ways of achieving this kind of style (i.e. by writing CSS and setting unsafe_allow_html=True) feels like a lot of work and makes the codebase way less clean and readable in my opinion. I think many users will eventually end up using these kinds of hacky ways to implement very basic styles (things like text color or font size) anyway so why not make them native features?

Long story short, I believe a middle ground between a rigid style that can’t be customised at all (unless one uses dirty/ugly and hacky workarounds) and a full customisation would be ideal for a framework like streamlit.

Last but not least, I think streamlit is somewhat confined to the realm of data-driven apps also because of this lack of customisation. I think it would be a powerful tool to build other kinds of apps too, (such as product MVPs, internal company tools, CRUD apps and a lot more) if it enabled users to customise their apps just a little bit more.

This is just my take though! Hope this makes sense:) What do you think? And how do you see Streamlit evolve in the future?


I think you described the problem very well :smiley: it’s all a matter of finding the right balance.

I agree with you that a Streamlit nice way to solve some basic customizations would already satisfy most of requests. One notable example is indeed text coloring, for which we have drafted native solutions that may land soon! cc @jrieke (PM at Streamlit). Let’s see how it goes and whether we want to go further: in my opinion one main strength of Streamlit is its commitment to a beautiful consistency since the beginning. Moving too far away from it could be “dangerous”!

About the future of Streamlit, we are actually putting together some initial thoughts internally at the moment, but we’ll definitely share them broadly and ask feedback from the community as soon as we can!


@tommaso-moro Thanks for the beautiful write-up, was a pleasure to read! :wink: As you pointed out, customization is a sensitive topic. We discuss it internally very regularly and we are aware that many users want more customization. On the other hand, as you pointed out, we want to have a consistent design framework and want things to look good out of the box, without requiring customization or CSS.

As Arnaud mentioned, we want to add a few moderate customization options for use cases that are highly requested, make sense, and feel Streamlit-y. Text color is a good example here. Offering these improvements in a nice way (and prioritizing among the 10 thousand other things we could do!), takes a bit of time though, so please bear with us!


Hi @arnaud ,

Changing the font-size of tabs with the “CSS hack” doesn’t work anymore in the latest versions of Streamlit. Do you have any advice on how to achieve this with v1.16.0? Thanks a lot in advance :slight_smile:

Well spotted! Here’s a revised version which should work, see

CSS was updated to:

button[data-baseweb="tab"] > div[data-testid="stMarkdownContainer"] > p {
  font-size: 24px;
1 Like

Oh by the way, coming back to the discussion @tommaso-moro, colored text just landed in st.markdown :slight_smile: st.markdown - Streamlit Docs

1 Like

Thanks a lot :pray: :pray: :pray: