You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Streamlit中为textarea实现动态高度调整并消除滚动条?

实现Streamlit动态高度Textarea(无滚动条)

核心思路

用原生HTML <textarea> 替代Streamlit自带的st.text_area,配合CSS隐藏滚动条,再通过JavaScript监听输入事件动态调整文本框高度,同时通过隐藏的Streamlit输入组件实现内容与会话状态的同步。

完整代码示例

import streamlit as st

# 初始化会话状态
if "user_input" not in st.session_state:
    st.session_state.user_input = ""
if "generated_text" not in st.session_state:
    st.session_state.generated_text = ""

# 创建两列布局
col1, col2 = st.columns(2)

with col1:
    st.subheader("User Input")
    # 插入自定义HTML Textarea(输入用)
    st.markdown("""
    <style>
    .auto-resize-textarea {
        width: 100%;
        min-height: 100px;
        padding: 10px;
        border: 1px solid #e6e6e6;
        border-radius: 4px;
        font-family: sans-serif;
        font-size: 14px;
        resize: none; /* 禁用手动调整大小 */
        overflow: hidden; /* 隐藏滚动条 */
    }
    .hidden-input {
        display: none;
    }
    </style>

    <textarea id="user-input-textarea" class="auto-resize-textarea" placeholder="输入内容...">{user_input}</textarea>
    <input type="text" id="hidden-user-input" class="hidden-input" value="{user_input}">

    <script>
    const textarea = document.getElementById('user-input-textarea');
    const hiddenInput = document.getElementById('hidden-user-input');

    // 初始化高度
    function resizeTextarea() {
        textarea.style.height = 'auto';
        textarea.style.height = textarea.scrollHeight + 'px';
        // 同步到隐藏输入框,让Streamlit获取值
        hiddenInput.value = textarea.value;
        // 触发隐藏输入框的变化事件,更新会话状态
        hiddenInput.dispatchEvent(new Event('input'));
    }

    // 监听输入事件
    textarea.addEventListener('input', resizeTextarea);
    // 页面加载时初始化高度
    window.addEventListener('load', resizeTextarea);
    </script>
    """.format(user_input=st.session_state.user_input), unsafe_allow_html=True)
    
    # 隐藏的输入框,用于同步会话状态
    st.session_state.user_input = st.text_input("", value=st.session_state.user_input, key="hidden_input", label_visibility="hidden")

with col2:
    st.subheader("Generated Text")
    # 模拟生成文本(实际场景替换为你的生成逻辑)
    if st.session_state.user_input:
        st.session_state.generated_text = "\n".join([f"生成内容行{i+1}" for i in range(len(st.session_state.user_input.splitlines()))])
    
    # 插入自定义HTML Textarea(展示用,只读)
    st.markdown("""
    <style>
    .auto-resize-textarea-readonly {
        width: 100%;
        min-height: 100px;
        padding: 10px;
        border: 1px solid #e6e6e6;
        border-radius: 4px;
        font-family: sans-serif;
        font-size: 14px;
        resize: none;
        overflow: hidden;
        background-color: #fafafa;
    }
    </style>

    <textarea id="generated-textarea" class="auto-resize-textarea-readonly" readonly>{generated_text}</textarea>

    <script>
    const generatedTextarea = document.getElementById('generated-textarea');
    function resizeGeneratedTextarea() {
        generatedTextarea.style.height = 'auto';
        generatedTextarea.style.height = generatedTextarea.scrollHeight + 'px';
    }
    window.addEventListener('load', resizeGeneratedTextarea);
    </script>
    """.format(generated_text=st.session_state.generated_text), unsafe_allow_html=True)

关键说明

  • CSS部分:通过overflow: hidden隐藏滚动条,resize: none禁用手动调整大小,设置基础样式匹配Streamlit原生风格。
  • JavaScript部分:resizeTextarea函数先将高度重置为auto,再设置为scrollHeight(文本实际占据的高度),确保文本框高度随内容自动扩展。
  • 会话状态同步:用隐藏的st.text_input作为中间层,通过JS将自定义textarea的内容同步到该输入框,触发input事件让Streamlit更新会话状态,保证后续业务逻辑能正常获取输入值。
  • 展示框处理:设置readonly属性禁止编辑,同样用JS初始化高度,确保展示内容时无滚动条。

内容的提问来源于stack exchange,提问作者Niko3445

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 07:35:26