Files
MemRelay/projects/8e229c96-a83b-4a02-ac40-10a0a9da444e/Streamlit st.html 注入全局 CSS 的坑:内容含 '-' 会被 DOMPurify 整段丢弃.md
T

31 lines
2.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Streamlit st.html 注入全局 CSS 的坑:内容含 '<' 会被 DOMPurify 整段丢弃
type: experience
permalink: main/projects/8e229c96-a83b-4a02-ac40-10a0a9da444e/streamlit-st.html-注入全局-css-的坑内容含-会被-dompurify-整段丢弃
stable_id: 30702060-b113-4e9e-b1f0-2553e8b35046
scope: project
project_id: 8e229c96-a83b-4a02-ac40-10a0a9da444e
memory_type: experience
status: active
revision: 1
restored_from_commit: 6a6a895eafcca6052e81a14fca103a42635dd1c2
created_at: '2026-09-23T15:01:37.094752+00:00'
updated_at: '2026-09-23T15:01:37.094807+00:00'
tags:
- streamlit
- css
- st.html
- dompurify
- ui
---
问题:在 ui/layout.py 的 COMPACT_CSS 中加入内联 SVG data URL(含 `<svg ...>`)后,界面所有紧凑布局、隐藏 Enter 提示等全局样式同时失效;DOM 中 stEvent 容器的元素为空。
原因:Streamlit 1.64 的 `st.html` 对内容做 DOMPurify 清洗,纯 `<style>` 内容会送到 event 容器;样式文本里出现 `<` 会让整个 `<style>` 被清洗掉,而且不报错。
解决:CSS 里不写任何 `<`(图标改用 Streamlit 自带控件或 mask 以外的方式);`apply_compact_layout` 加了 `assert "<" not in COMPACT_CSS`,tests/test_toolbox.py 增加 `test_global_css_survives_streamlit_sanitizer` 守护。
附带结论:
- 隐藏所有输入框右下角 “Press Enter to submit form/apply” 提示:`[data-testid="InputInstructions"]{display:none !important}`,全局生效(app.py 在 st.navigation 前调用 apply_compact_layout)。
- 输入框内右侧 ✕ 清除按钮:`st.text_input(type="search")` 自带(stTextInputClearButton),不需要自定义 CSS;只需隐藏左侧放大镜 `[data-testid=stTextInputRootElement]:has(input[type=search]) [data-testid=stTextInputIcon]` 并把根元素 padding-left 置 0;placeholder 为空时会显示默认 “Search”,需显式传 placeholder。
- 排查手段:浏览器 CDP 查 `[data-testid=stEvent]` innerHTML 是否含样式文本、`.block-container` paddingTop(紧凑时≈13.6px,未生效为 96px)。