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).
Little example here:
with st.container():
st.text('interesting content')
st.text('in a potentially ')
st.text('very stylish container')
col1, col2, col3 = st.columns(3)
col1.write('cool column box 1')
col2.write('cool column box 2')
col3.write('cool column box 3')
/* Style columns */
[data-testid="column"] {
box-shadow: rgb(0 0 0 / 20%) 0px 2px 1px -1px, rgb(0 0 0 / 14%) 0px 1px 1px 0px, rgb(0 0 0 / 12%) 0px 1px 3px 0px;
border-radius: 15px;
padding: 5% 5% 5% 10%;
}
/* Style containers */
[data-testid="stVerticalBlock"] > [style*="flex-direction: column;"] > [data-testid="stVerticalBlock"] {
border: 20px groove red;
}