Create floating containers in streamlit
applications.
No third-party libraries required other than streamlit
itself.
streamlit run streamlit_float.py
Copy the following code into your
streamlit
application and use thest_float_container
function similar to how you would usest.container
.
- The
st_float_container
supports customization through css and js parameters to modify styling and behavior.
import time
import streamlit as st
from streamlit.components.v1 import html
def st_float_container(
*,
border: bool = None,
align: str = None,
key: str = None,
css: str = None,
js: str = None,
style: str = None,
**kwargs,
):
"""
Custom Streamlit container with floating capabilities and style customization.
:param border: Enable/disable container border
:param align: Horizontal alignment: `left`, `right` or `center`
:param key: Unique identifier for the container
:param css: Custom CSS styles (use `>>` as container selector)
:param js: Custom JavaScript code
:param style: Inline CSS styles for the container
:param kwargs: Additional CSS properties in camelCase format
"""
def camel_to_kebab(s):
return "".join(
[
"-" + c.lower() if i and c.isupper() else c.lower()
for i, c in enumerate(s)
]
)
if key is None:
key = str(int(time.time() * 1000))
if css:
css = css.replace(">>", f".st-key-st_float_container_{key} ")
if js is None:
js = ""
else:
js = js.replace("`", r"\`").replace("$", r"\$")
if style is None:
style = ""
align = {"left": "flex-start", "right": "flex-end"}.get(align, "center")
if kwargs:
if "position" not in kwargs:
style += "position:fixed;"
if "zIndex" not in kwargs:
style += "z-index:999999;"
if not style.strip().endswith(";"):
style += ";"
style += ";".join([f"{camel_to_kebab(k)}:{v}" for k, v in kwargs.items()]) + ";"
class _st_container(st._DeltaGenerator):
def __enter__(self):
super().__enter__()
st.html(f"""
<style>
.st-key-st_float_container_{key}>div:last-child {{
display: none !important;
}}
.st-key-st_float_container_{key}>div>div {{
display: flex;
justify-content: {align};
}}
{css}
</style>""")
def __exit__(self, type, value, traceback):
html(
f"""
<script>
let doc = window.parent.document;
let elems = doc.getElementsByClassName("st-key-st_float_container_{key}");
if (elems.length > 0) {{
let container = elems[0].parentNode.parentNode;
container.style = "{style}";
if (container.getElementsByTagName('script').length == 0) {{
const html = `{js}`;
if (html != "") {{
let script = doc.createElement("script");
script.innerHTML = html;
container.appendChild(script);
}}
}}
}}
</script>""",
width=0,
height=0,
)
super().__exit__(type, value, traceback)
_container = st.container(border=border, key=f"st_float_container_{key}")
return _st_container(
_container._root_container,
cursor=_container._cursor,
parent=_container._parent,
block_type=_container._block_type,
)