2025, Sep 22 10:01

Рабочий способ поменять шрифт кнопки st.button в Streamlit

Как заставить st.button в Streamlit принять нужный шрифт: разбор DOM, правильные CSS-селекторы для текста кнопки, пример кода и советы по проверке в DevTools.

Стилизовать st.button в Streamlit кажется задачей на пять минут — пока шрифт упрямо не отказывается меняться. Вы подключаете CSS, обновляете страницу, пробуете даже шрифт, вшитый через base64, — а надпись на кнопке не меняется. Причина не в кэше и не в iframe. Дело в реальной структуре DOM у кнопки и в том, где находится текстовый узел.

Пример кода

import streamlit as ui

ui.markdown(
    """
    <style>
    div.stButton > button > div {
        font-family: "Courier New", sans-serif !important;
        font-size: 20px !important;
    }
    </style>
    """,
    unsafe_allow_html=True
)

if ui.button("Click me", use_container_width=True):
    ui.success("Clicked!")

Что на самом деле происходит

Откройте DevTools в Chrome или Firefox и посмотрите сгенерированный HTML — вы заметите один тонкий момент: видимая надпись st.button — это не собственный текст элемента button. На самом деле текст лежит внутри p, вложенного в div, который, в свою очередь, находится внутри кнопки. У этого внутреннего div есть свои стили, связанные со шрифтами, поэтому селектор, направленный только на сам button, проигрывает каскаду. В итоге CSS вроде div.stButton > button { font-family: ... } не добирается до реального текстового узла.

И потому приём с встраиванием шрифта через base64 или очистка кэша не помогут, если селектор не нацелен на элемент, который действительно отрисовывает текст.

Решение

Нужно попасть на правильный уровень DOM, где выводится подпись. Селектор, который «проваливается» во вложенную структуру, уверенно переопределяет font-family и font-size. На практике работает div.stButton > button > div, а при необходимости можно пойти глубже — например, div.stButton > button > div > p или div.stButton > button p.

Как только селектор указывает на контейнер, оборачивающий текст, шрифт меняется мгновенно. Никаких дополнительных хаков, iframe или сторонних компонентов.

Почему это важно

Правки интерфейса в Streamlit часто упираются в понимание того, как компоненты собраны в DOM. Если целиться не в тот элемент, каскад и внутренние стили перекроют ваши правила, и может показаться, что «Streamlit игнорирует мой CSS». Умение проверять сгенерированный HTML помогает понять, что именно применяется, и где корректно его переопределить.

Выводы

Если вам нужен собственный шрифт для st.button, это реально. Проверьте структуру в DevTools и направьте CSS на элемент, который содержит текст. С правильным селектором font-family и font-size применяются без проблем, и вам не понадобятся костыли или альтернативные компоненты, имитирующие кнопку.

Статья основана на вопросе с StackOverflow от Fathi Farzad и ответе furas.