如何在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
相关产品推荐
相关产品推荐

