I am trying to add custom outline to containers used in my app. I am familiar with the technique of applying custom CSS styles through markdown and have no issue with that. However, I am struggling to only apply styles to containers created with st.container() without affecting all the other containers that Streamlit generates on its own (e.g. when using tabs). Sadly, manually created containers have no “data-testid” attribute, unlike metrics and some other widgets. That would’ve helped resolve the issue.
Basically, my question narrows down to this: How can I add a CSS outline to the container I am creating manually without affecting other widgets?
Let this be an example application:
st.write('text outside the container')
with st.container():
st.write('text inside the container')
Your idea is magnificent! Although, I would make some minor changes to the structure of the css selector so that it does not affect st.columns() grid
Turns out that the st.columns() method generates a similar hierarchy of divs. Luckily, there is a difference! Unlike those that compose a container, these divs are not direct children. So, a specific descendant-child order would make our thingy more precise This allows us to play with containers without affecting other widgets (as far as I can tell).
to who it may concern:
if you want to style a specific element you can create a css element with an id and then style it using the css “has” property. It works directly in edge and chrome, in firefox (v 109) you have to enable the css has selector in the config first.
st.write('''<style>
[data-testid="stHorizontalBlock"]:has(div.PortMarker) [data-testid="stMarkdownContainer"] p {
margin: 0px 0px 0.2rem;
color: #ff0000;
}
</style>''', unsafe_allow_html=True)
with st.container():
INcol1, INcol2 = st.columns(2)
with INcol1:
st.write('Test 1')
st.write("""<div class='PortMarker'/>""", unsafe_allow_html=True)
with INcol2:
st.write('Test 2')
You can actually make that quite convenient using the new :has CSS pseudo-class using a simple <span> as a CSS tag:
st.write('text outside the container')
with st.container(border=True):
st.write('text inside container with red border')
st.write('<span class="red-frame"/>', unsafe_allow_html=True)
with st.container(border=True):
st.write('text inside container')
st.write("""
<style>
div[data-testid="stVerticalBlockBorderWrapper"]:has(
>div>div>div[data-testid="element-container"]
.red-frame
) {
outline: 2px solid red;
border-radius: 2px;
}
</style>
""", unsafe_allow_html=True)
Of course, using a separate st.write() for the tag takes up an empty line of space, so in practice, it’s probably better to place the tag inside the payload.
Keep in mind that every time you use a st.markdown(<span id="my_tag"></span>) as a css-tag you will trigger the gab attribute of the parent container. This will give you a 1rem empty space. To counteract this I did:
st.markdown("""
<style>
div[data-testid="column"]:has(span) div div div
{
gap: 0rem;
}
</style>
""", unsafe_allow_html=True)
A lot of the examples shown here work great but none work for font family, font size or font weight. Can someone help with example for these and how the font attributes can be changed ?
<div data-testid="column" class="st-emotion-cache-16nc0hx e1f1d6gn3"><div data-testid="stVerticalBlockBorderWrapper" data-test-scroll-behavior="normal" class="st-emotion-cache-0 e1f1d6gn0"> so can we change the scroll-behavior of the container using custom css
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.