Custom Fonts on Streamlit

Hello everybody!

I would like to know if it is possible to change the font for the entire application.

I saw in the customization of themes that streamlit uses the sans-serif font as default, I would like to use the font-family: “Cabin”, sans-serif;

I’d like to use it for all the app, text, widgets, etc.

I tried using some CSS like @andfanilo shows in his youtube video (By the way thanks for the amazing content! I’m your fan!). But I believe my CSS skills are not good enough.

1 Like

Hi @Guilherme_Hungaro ,

If you want to set the font globally, you can do that in the config file. Go right down to the bottom of the page in this following link.

However, if you want to change the font for some parts of your application, you could refer this link and experiment for yourself.

Cheers

1 Like

Thanks for your reply friend!

I configured the config file, however it only accepts some fonts (“sans serif”, “serif”, or “monospace”.) the font I want to use seems to be not supported.

Here the message that I receive when try to set font = “cabin” (or Cabin)
2022-06-02 19:08:23.003 “cabin” is an invalid value for theme.font. Allowed values include [‘sans serif’, ‘serif’, ‘monospace’]. Setting theme.font to “sans serif”.

Is there any way I can put a global font other than the ones that are available?

1 Like

Hi @Guilherme_Hungaro
You need to create a style.css file and put in something like this :slight_smile:

@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap'); 

html, body, [class*="css"] {
    font-family: 'Roboto', sans-serif; 
    font-size: 18px;
    font-weight: 500;
    color: #091747;
}

In your main.py you need to put this:


with open( "app\style.css" ) as css:
    st.markdown( f'<style>{css.read()}</style>' , unsafe_allow_html= True)
4 Likes

Thank you very much Ricardo! I’ll try it later and let you know if it worked!

1 Like

This solved!! Tks a lot Ricardo!

1 Like

Any time !

Thank you for this Ricardo! It works for almost everything, but doesn’t seem to style AgGrid. I’ve tried using the custom_css parameter to set the AgGrid theme font-family attribute, but haven’t had luck. for example, using your code above, I can render all text outside of the AgGrid component with the Poppins font, but the AgGrid renders with Times New Roman.

custom_css = {
    ".ag-theme-material": {
        "--ag-font-family": "Poppins,Times New Roman,sans-serif;"
        , "--ag-row-height": "26px;"
        }
    }

gd = GridOptionsBuilder.from_dataframe(df)
gd.configure_selection(selection_mode='single',use_checkbox=False)
gd.configure_pagination()
gd.configure_auto_height=True
gd.configure_column("Model Description",autoHeight=True)
gd.configure_column("Model Description",wrapText=True)
gridOptions = gd.build()

table = AgGrid(df,
      gridOptions=gridOptions,
      theme='material',
      reload_data=True,
      allow_unsafe_jscode=True,
      custom_css=custom_css)
1 Like

As AgGrid (streamlit-aggrid) is a component, it runs inside an iframe. So you have to define de font inside the component page.

One way is thought CSS customization:

@font-face {
    font-family: "FONT_NAME";
    src: url("http://address/font.ttf") format("truetype");
}

[class^="ag-"]:not([class^="ag-icon"]) {
    font-family: "FONT_NAME";
}

Using the custom_css parameter you mention:

custom_css = {
    '@font-face': {
        'font-family': '"FONT_NAME"',
        'src': 'url("http://address/font.ttf") format("truetype")'
    },

    '[class^="ag-"]:not([class^="ag-icon"])': {
        'font-family': '"FONT_NAME"'
    }
}

I think you can just add the following to your original custom_css and it will work:

    '@font-face': {
        'font-family': '"Poppins"',
        'src': 'url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJfecg.woff2) format("woff2")'

I got the font link from:
https://fonts.googleapis.com/css?family=Poppins

1 Like

This solution will not work for Streamlit versions after 1.26.0

1 Like

The solution proposed by @ricardo.pascoal will work on the current (1.31.1) streamlit distribution with one modification to the css selector being used along with adding the !important modifier to the font-family.

@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap'); 

body * {
    font-family: 'Roboto', sans-serif !important;
}

with the code in your main.py the same as he suggests:

with open( "app\style.css" ) as css:
    st.markdown( f'<style>{css.read()}</style>' , unsafe_allow_html= True)

Note: using body * will essentially override the font for every element. When that is not the desired effect you may want to inspect your page in a web editor and tweak your CSS selector to more refined targets. This becomes obvious when you look at st.code() code blocks as their monospace font will be replaced by your custom font.
In my case I noticed that all of the streamlit elements that I wanted my font to affect contained a class that starts with st-emotion. Therefor my CSS selector looks like the following:

[class^=st-emotion] {
    font-family: myFont !important
}

The above change from using body * allows any inline styles to remain applied as they relate to the font. Such as allowing the formatting of st.code() blocks to remain intact.

3 Likes

This is very helpful, thank you!

1 Like