container滚动条.md 13 KB

是的,st.container默认情况下不支持横向滚动。它只支持垂直滚动。让我为您演示几种解决方案:

import streamlit as st

def container_default():
    st.title("📦 默认Container - 只有垂直滚动")
    
    long_text = "Lorem ipsum. 12345678901234567890123456789012345678901234567890123456789012345678901234567890" * 1000

    with st.container(height=300, width=600, border=True):
        st.markdown(long_text)
    
    st.write("☝️ 上面的容器只能垂直滚动,长文本会自动换行")

def container_with_horizontal_scroll():
    st.title("↔️ 使用CSS实现横向滚动")
    
    # 方案1:真正的双向滚动(修复版)
    st.subheader("🔄 双向滚动 - 修复版")
    
    # 创建既宽又高的内容
    wide_content = """
    <div style="height: 300px; width: 600px; overflow: auto; border: 2px solid #4CAF50; border-radius: 10px; padding: 15px; background-color: #f9f9f9;">
        <div style="min-width: 1200px; min-height: 800px;">
            <h3>这个容器支持横向和纵向滚动</h3>
            <p>横向内容:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</p>
            <p>正常换行内容:Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
            <table style="border-collapse: collapse; margin: 20px 0; min-width: 1000px;">
                <tr style="background-color: #e6f3ff;">
                    <th style="border: 1px solid #ddd; padding: 8px;">超长列名1超长列名1超长列名1</th>
                    <th style="border: 1px solid #ddd; padding: 8px;">超长列名2超长列名2超长列名2</th>
                    <th style="border: 1px solid #ddd; padding: 8px;">超长列名3超长列名3超长列名3</th>
                    <th style="border: 1px solid #ddd; padding: 8px;">超长列名4超长列名4超长列名4</th>
                    <th style="border: 1px solid #ddd; padding: 8px;">超长列名5超长列名5超长列名5</th>
                </tr>
    """
    
    # 添加多行表格数据
    for i in range(50):
        wide_content += f"""
                <tr>
                    <td style="border: 1px solid #ddd; padding: 8px;">数据{i}-1数据{i}-1数据{i}-1</td>
                    <td style="border: 1px solid #ddd; padding: 8px;">数据{i}-2数据{i}-2数据{i}-2</td>
                    <td style="border: 1px solid #ddd; padding: 8px;">数据{i}-3数据{i}-3数据{i}-3</td>
                    <td style="border: 1px solid #ddd; padding: 8px;">数据{i}-4数据{i}-4数据{i}-4</td>
                    <td style="border: 1px solid #ddd; padding: 8px;">数据{i}-5数据{i}-5数据{i}-5</td>
                </tr>
        """
    
    wide_content += """
            </table>
            <p>更多垂直内容...</p>
            <div style="height: 200px; background: linear-gradient(45deg, #ff9a9e 0%, #fecfef 50%, #fecfef 100%); border-radius: 10px; margin: 20px 0; display: flex; align-items: center; justify-content: center;">
                <h2>这是一个高度为200px的彩色区域</h2>
            </div>
        </div>
    </div>
    """
    
    # 添加滚动条样式
    st.markdown("""
    <style>
    .dual-scroll {
        height: 300px;
        width: 600px;
        overflow: auto;
        border: 2px solid #4CAF50;
        border-radius: 10px;
        padding: 15px;
        background-color: #f9f9f9;
    }
    
    .dual-scroll::-webkit-scrollbar {
        width: 12px;
        height: 12px;
    }
    
    .dual-scroll::-webkit-scrollbar-track {
        background: #f1f1f1;
        border-radius: 10px;
    }
    
    .dual-scroll::-webkit-scrollbar-thumb {
        background: #888;
        border-radius: 10px;
    }
    
    .dual-scroll::-webkit-scrollbar-thumb:hover {
        background: #555;
    }
    
    .dual-scroll::-webkit-scrollbar-corner {
        background: #f1f1f1;
    }
    </style>
    """, unsafe_allow_html=True)
    
    st.markdown(wide_content, unsafe_allow_html=True)
    
    st.write("☝️ 上面的容器支持真正的横向和纵向双向滚动")
    
    # 方案2:只有横向滚动的版本(原来的)
    st.subheader("↔️ 只有横向滚动版本")
    
    long_text_no_wrap = "Lorem ipsum dolor sit amet consectetur adipiscing elit " * 50
    
    st.markdown("""
    <style>
    .horizontal-only {
        height: 100px;
        width: 600px;
        overflow-x: auto;
        overflow-y: hidden;
        border: 2px solid #FF6B6B;
        border-radius: 10px;
        padding: 15px;
        background-color: #fff5f5;
        white-space: nowrap;
    }
    
    .horizontal-only::-webkit-scrollbar {
        height: 12px;
    }
    
    .horizontal-only::-webkit-scrollbar-track {
        background: #f1f1f1;
        border-radius: 10px;
    }
    
    .horizontal-only::-webkit-scrollbar-thumb {
        background: #ff6b6b;
        border-radius: 10px;
    }
    </style>
    """, unsafe_allow_html=True)
    
    st.markdown(f'<div class="horizontal-only">{long_text_no_wrap}</div>', unsafe_allow_html=True)
    
    st.write("☝️ 上面的容器只支持横向滚动")
    
    # 方案3:垂直滚动版本
    st.subheader("↕️ 只有垂直滚动版本")
    
    vertical_content = """
    <div style="height: 200px; width: 400px; overflow-y: auto; overflow-x: hidden; border: 2px solid #9B59B6; border-radius: 10px; padding: 15px; background-color: #f8f4ff;">
    """
    
    for i in range(20):
        vertical_content += f"<p>这是第{i+1}行文本内容,用于测试垂直滚动功能。</p>"
    
    vertical_content += "</div>"
    
    st.markdown(vertical_content, unsafe_allow_html=True)
    
    st.write("☝️ 上面的容器只支持垂直滚动")

def container_code_block():
    st.title("🔤 代码块容器 - 自带横向滚动")
    
    # 长代码行
    long_code = """
def very_long_function_name_that_exceeds_normal_width():
    very_long_variable_name = "this is a very long string that will definitely exceed the container width and require horizontal scrolling to view completely"
    another_very_long_variable = {"key1": "very_long_value_1", "key2": "very_long_value_2", "key3": "very_long_value_3"}
    return very_long_variable_name + str(another_very_long_variable)

# 更多长代码行
print("This is a very long print statement that contains lots of text and will definitely require horizontal scrolling to see the complete content")
"""
    
    with st.container(height=300, border=True):
        st.code(long_code, language="python")
    
    st.write("☝️ 代码块自动支持横向滚动")

def container_dataframe():
    st.title("📊 DataFrame容器 - 自带横向滚动")
    
    import pandas as pd
    
    # 创建宽DataFrame
    wide_df = pd.DataFrame({
        f"很长的列名_{i}": [f"很长的数据内容_{j}_{i}" for j in range(20)] 
        for i in range(15)
    })
    
    with st.container(height=300, border=True):
        st.dataframe(wide_df, width='stretch')
    
    st.write("☝️ DataFrame自动支持横向滚动")

def container_custom_html():
    st.title("🎨 自定义HTML容器")
    
    # 创建表格数据
    table_html = """
    <div style="height: 300px; width: 600px; overflow: auto; border: 2px solid #FF6B6B; border-radius: 10px; padding: 10px;">
        <table style="min-width: 1200px; border-collapse: collapse;">
            <tr style="background-color: #f2f2f2;">
                <th style="border: 1px solid #ddd; padding: 8px; white-space: nowrap;">Very Long Column Header 1</th>
                <th style="border: 1px solid #ddd; padding: 8px; white-space: nowrap;">Very Long Column Header 2</th>
                <th style="border: 1px solid #ddd; padding: 8px; white-space: nowrap;">Very Long Column Header 3</th>
                <th style="border: 1px solid #ddd; padding: 8px; white-space: nowrap;">Very Long Column Header 4</th>
                <th style="border: 1px solid #ddd; padding: 8px; white-space: nowrap;">Very Long Column Header 5</th>
                <th style="border: 1px solid #ddd; padding: 8px; white-space: nowrap;">Very Long Column Header 6</th>
            </tr>
    """
    
    # 添加表格行
    for i in range(20):
        table_html += f"""
            <tr>
                <td style="border: 1px solid #ddd; padding: 8px; white-space: nowrap;">Very long data content {i}-1</td>
                <td style="border: 1px solid #ddd; padding: 8px; white-space: nowrap;">Very long data content {i}-2</td>
                <td style="border: 1px solid #ddd; padding: 8px; white-space: nowrap;">Very long data content {i}-3</td>
                <td style="border: 1px solid #ddd; padding: 8px; white-space: nowrap;">Very long data content {i}-4</td>
                <td style="border: 1px solid #ddd; padding: 8px; white-space: nowrap;">Very long data content {i}-5</td>
                <td style="border: 1px solid #ddd; padding: 8px; white-space: nowrap;">Very long data content {i}-6</td>
            </tr>
        """
    
    table_html += """
        </table>
    </div>
    """
    
    st.markdown(table_html, unsafe_allow_html=True)
    st.write("☝️ 自定义HTML表格支持横向和纵向滚动")

def container_plotly_chart():
    st.title("📈 Plotly图表 - 自带横向滚动")
    
    import plotly.graph_objects as go
    import pandas as pd
    
    # 创建宽图表数据
    categories = [f"Category_{i}" for i in range(30)]
    values = [i * 10 + 50 for i in range(30)]
    
    fig = go.Figure(data=[
        go.Bar(x=categories, y=values, name="Long Bar Chart")
    ])
    
    fig.update_layout(
        title="Very Wide Bar Chart with Many Categories",
        width=1500,  # 设置很宽的图表
        height=400,
        xaxis_title="Categories (Very Long Names)",
        yaxis_title="Values"
    )
    
    with st.container(height=450, border=True):
        st.plotly_chart(fig, width='content')
    
    st.write("☝️ Plotly图表在容器中自动支持横向滚动")

def container_iframe():
    st.title("🌐 iframe容器")
    
    iframe_html = """
    <iframe 
        src="https://www.openstreetmap.org/export/embed.html?bbox=-0.004017949104309082%2C51.47612752641776%2C0.00030577182769775%2C51.478569861898606&layer=mapnik" 
        style="width: 800px; height: 300px; border: 2px solid #4CAF50; border-radius: 10px;"
        scrolling="yes">
    </iframe>
    """
    
    with st.container(height=350, border=True):
        st.markdown(iframe_html, unsafe_allow_html=True)
    
    st.write("☝️ iframe内容可以有自己的滚动条")

# 页面选择
page = st.radio("Select Container Type", [
    "📦 Default Container (Vertical Only)",
    "↔️ CSS Horizontal Scroll",
    "🔤 Code Block Container",
    "📊 DataFrame Container", 
    "🎨 Custom HTML Container",
    "📈 Plotly Chart Container",
    "🌐 Iframe Container"
])

if page == "📦 Default Container (Vertical Only)":
    container_default()
elif page == "↔️ CSS Horizontal Scroll":
    container_with_horizontal_scroll()
elif page == "🔤 Code Block Container":
    container_code_block()
elif page == "📊 DataFrame Container":
    container_dataframe()
elif page == "🎨 Custom HTML Container":
    container_custom_html()
elif page == "📈 Plotly Chart Container":
    container_plotly_chart()
elif page == "🌐 Iframe Container":
    container_iframe()

总结:

🚫 Streamlit Container的限制:

  • st.container默认只支持垂直滚动
  • 不提供内置的横向滚动功能
  • 文本内容会自动换行

实现横向滚动的方案:

  1. CSS方案:使用overflow-x: autowhite-space: nowrap
  2. 代码块st.code()自带横向滚动
  3. DataFramest.dataframe()自带横向滚动
  4. 自定义HTML:完全控制滚动行为
  5. Plotly图表:支持宽图表的横向滚动

📝 推荐方案:

  • 文本内容:使用CSS方案
  • 数据展示:使用DataFrame或自定义HTML表格
  • 代码展示:使用st.code()
  • 图表展示:使用Plotly等支持滚动的图表库

如果您需要在容器中显示特定类型的内容并需要横向滚动,请告诉我具体的使用场景,我可以为您提供更针对性的解决方案!