プログラミング

Streamlitで画面分割とCSS適用



どうも、ねぎねずです。

Streamlitで画面を分割したり、CSSの適用を試す機会がありました。

試しているとStreamlitで出来ることが多いことに気づいたので、備忘録として残しておこうと思います。

記事の要約

  • 画面分割では「st.columns」と「st.container」を使う
  • CSSを適用する場合は「st.markdown」と組み合わせる
  • ただし、CSSのみを挿入する場合は「st.markdown」より「st.html」が推奨されている
  • 「streamlit-extras」というライブラリを使ってCSSを適用することもできる

Streamlitで画面を分割

Streamlit では1枚のページを分割したレイアウトを作ることができます。

 参考: レイアウトに関する公式ドキュメント

縦に分割する場合

画面を縦に分割する場合は、「st.columns」を使います。

等間隔で分割する場合は、分割数を指定するだけです。

col1, col2, col3 = st.columns(3)
with col1:
    st.header("col1")
    st.file_uploader("アップロード", key="col1", type=[".txt"])
with col2:
    st.header("col2")
    st.file_uploader("アップロード", key="col2", type=[".txt"])

with col3:
    st.header("col3")
    st.file_uploader("アップロード", key="col3", type=[".txt"])


異なる大きさで分割したい場合は、st.columnsにリストで大きさの比率を入れてあげます。

[1,2] と指定することで、左側の2倍の幅で右側が表示されます。

left_page, right_page = st.columns([1, 2])

with left_page:
    st.header("左ページ")
    st.write("何か入力して下さい。")
    st.text_input(label="")
    st.button("送信")

with right_page:
    st.header("右ページ")
    st.write("何かファイルをアップロードしてください。")
    st.file_uploader("アップロード", type=[".txt"])


横に分割する場合

「st.container」を使って領域を確保して、そこに複数の要素を入れることができます。

分割というより、領域を確保してくれるイメージです。

パラメータの「height」で高さを指定することで、領域を確保できます。

# border=Trueでコンテナーの境界線を表示
container = st.container(border=True, height=120)
container.write("コンテナーのなか")
st.write("コンテナーの外")



Containerの中にタブを入れることもできます。

ソースコードを見る
import streamlit as st

st.set_page_config(page_title="画面分割", layout="wide")
st.title("画面分割お試し")
with st.sidebar:
    st.header("サイドバー")
    st.write("ここはサイドバーです。")

left_page, right_page = st.columns([1, 2])

with left_page:
    st.header("左ページ")
    st.write("何か入力して下さい。")
    st.text_input(label="")
    st.button("送信")

with right_page:
    st.header("右ページ")
    st.write("何かファイルをアップロードしてください。")
    st.file_uploader("アップロード", type=[".txt"])

with st.container():
    tab1, tab2 = st.tabs(["タブ1", "タブ2"])
    with tab1:
        tab1_container = st.container(height=300)
        tab1_container.write("タブ1のコンテナー")
    with tab2:
        tab2_container = st.container(height=300)
        tab2_container.write("タブ2のコンテナー")


タブを「st.expander」に変えると、このようになります。
st.container と様々な要素を組み合わせることで画面レイアウトの自由度が上がりますね!

with st.container():
    with st.expander("表示する"):
        st.write("中身を表示しました。")



StreamlitでCSSを適用する方法

Streamlit では、そのまま使用しても良い感じのデザインが多いですが、色や大きさを自分で変更したい場合があると思います。

デザインを変更したい場合はCSSを適用する必要があります。今回はCSSの適用方法を3つ紹介します。

st.markdownを使う

st.markdownを使ってCSSを挿入します。

st.markdown(
    """
    <style>
        .custom-text {
            color: white;
            background-color: black;
        }
    </style>
    <p class='custom-text'>Hello World!</p>
""",
    unsafe_allow_html=True,
)


st.markdownを使ってを適用することはできますが、公式ドキュメントではHTMLやCSSのみを挿入したい場合は「st.html」を使うことが推奨されています。

Note
If you only want to insert HTML or CSS without Markdown text, we recommend using st.html instead.

Streamlit公式ドキュメント「st.markdown」


st.htmlを使う

CSSのみを挿入する場合は、st.markdownではなく、「st.html」が公式で推奨されています。

st.htmlではHTMLをそのまま挿入することができ、好きなデザインに変更することができます。

st.html(
    """
    <style>
        .custom-text {
            color: white;
            background-color: black;
        }
    </style>
    <p class='custom-text'>Hello World!</p>
"""
)


streamlit-extrasでCSSを適用する

最後に紹介するのは「streamlit-extras」というStreamlitのカスタムコンポーネントを集めたライブラリです。

その中でも「Styleable Container」を使うとStreamlitの中でCSSが扱えるようになります。

以下のコマンドで、streamlit-extrasをインストールができます。

pip install streamlit-extras


stylable_containerの引数「css_styles」にCSSを入れることでデザインを適用することができます。

st.write("何か入力して下さい。")
st.text_input(label="")
with stylable_container(
    key="green_button",
    css_styles="""
            button {
                background-color: green;
                color: white;
                border-radius: 20px;
            }
            """,
):
    st.button("送信")

まとめ

Streamlitの画面分割やCSS適用方法について、まとめてみました。

基本的にデフォルトのデザインでもいい感じの画面は作れますが、CSSが適用できるとさらに理想の画面を作れると思います。

Streamlitは手軽に画面が作れて便利なので、チャット画面など、他にも試してみたいと思います。

ここまで読んでいただき、ありがとうございました。
何か皆様のお役に立てれば幸いです。

  • この記事を書いた人

ねぎねず

IT企業で働くエンジニア6年目。プログラミングや生成AIを勉強中。勉強や生活するなかで役に立った情報を発信していきます。

-プログラミング