On the first rendering of items in tabs that are long, they glitch out for a brief moment. This is what they look like in that moment:
Video demonstration:
As you can see, this only happens the first time they are rendered, they’re fine after that.
Example code:
import streamlit as st
st.write("## Example site")
tab1, tab2, tab3, tab4, tab5 = st.tabs(
[
"Tab 1",
"Tab 2",
"Tab 3",
"Tab 4",
"Tab 5",
]
)
with tab1:
form = st.form("tab 1 form", clear_on_submit=True)
uploaded_files = form.file_uploader("Upload files")
form.form_submit_button("submit")
with tab2:
form = st.form("tab 2 form", clear_on_submit=True)
uploaded_files2 = form.file_uploader("Upload files")
form.form_submit_button("submit")
with tab3:
st.write("# Hi")
st.write("## make this longer")
with tab4:
st.write("# fine")
with tab5:
st.write("# This is not fine because it is long")
2 Likes
Any ideas? Could someone point me to this part of the source code maybe?
This even happens on the st.tabs documentation page (st.tabs - Streamlit Docs ):
I think this might be what you’re looking for.
/**
* Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { ReactElement, useRef, useState, useEffect } from "react"
import { useTheme } from "@emotion/react"
import { Tabs as UITabs, Tab as UITab } from "baseui/tabs-motion"
This file has been truncated. show original
Thanks, did some traversal and I think it’s this autosizer that is causing this problem:
<AutoSizer disableHeight={true} style={styledVerticalBlockWrapperStyles}>
{({ width }) => {
const propsWithNewWidth = { ...props, ...{ width } }
return (
<StyledVerticalBlock width={width} data-testid="stVerticalBlock">
<ChildRenderer {...propsWithNewWidth} />
</StyledVerticalBlock>
)
}}
</AutoSizer>
I think it is just taking too long to calculate the proper width.
marduk
December 6, 2022, 6:57pm
6
Hi both @kevinlinxc , @willhuang ,
FYI, I opened an issue for this on Github:
opened 06:55PM - 06 Dec 22 UTC
type:bug
status:needs-triage
### Checklist
- [X] I have searched the [existing issues](https://github.com/st… reamlit/streamlit/issues) for similar issues.
- [X] I added a very descriptive title to this issue.
- [X] I have provided sufficient information below to help reproduce this issue.
### Summary
Currently, the content inside tabs jitters when a user switches tabs for the first time.
Another user reported [this](https://discuss.streamlit.io/t/bug-with-st-tabs-glitches-for-1-frame-while-rendering/33497/5) bug on the forum, but wanted to create an official issue here too.
### Reproducible Code Example
```Python
import streamlit as st
st.title('Content inside tabs jitters on first load')
t1, t2, t3 = st.tabs(['First tab','Second tab','Third tab'])
t1.header('This content is inside the first tab')
t2.header('This content is inside the second tab')
t3.header('This content is inside the third tab')
```
### Steps To Reproduce
1. Run the Reproducible Code Example as a Streamlit app.
2. Click on the different tabs and see how the content jitters.
### Expected Behavior
Content inside each tab does not jitter when switching tabs.
### Current Behavior
_No response_
### Is this a regression?
- [ ] Yes, this used to work in a previous version.
### Debug info
- Streamlit version: 1.14.1
- Python version: 3.10
- Operating System: macOS
- Browser: Brave
- Virtual environment: conda
### Additional Information
_No response_
### Are you willing to submit a PR?
- [ ] Yes, I am willing to submit a PR!
Did you by any chance find a workaround or solution? Thanks in advance.
5 Likes
@kevinlinxc @marduk
Having the same problem right now, I am happy to hear that it’s a width problem and not a “data not initializing problem”.
With my case the first tab shows all elements correctly, but additional tabs only show the text. (Note the tabs are inside of an expander)
I have noticed that if I create a function to display a tabs elements it works fine — but it’s not sufficient in my case.
I’ll be looking into this a good amount tomorrow and will update you guys if I get anything working.
1 Like
I never found anything, sorry. My JS knowledge is pretty limited and it seems like this a pretty niche issue even if I knew more about React
2 Likes
marduk
February 10, 2023, 7:32pm
9
Bumping this in case someone found a temporary workaround.
And for those interested, please remember to like the GitHub issue to signal interest
2 Likes
Here is a possible solution:
import streamlit as st
from streamlit.components import v1
st.title('Content inside tabs jitters on first load')
t1, t2, t3 = st.tabs(['First tab', 'Second tab', 'Third tab'])
t1.header('This content is inside the first tab')
t2.header('This content is inside the second tab')
t3.header('This content is inside the third tab')
v1.html("""
<script>
const tabs = window.parent.document.querySelectorAll('button[data-baseweb="tab"] p');
const tab_panels = window.parent.document.querySelectorAll('div[data-baseweb="tab-panel"]');
tabs.forEach(function (tab, index) {
const tab_panel_child = tab_panels[index].querySelectorAll("*");
function set_visibility(state) {
tab_panels[index].style.visibility = state;
tab_panel_child.forEach(function (child) {
child.style.visibility = state;
});
}
tab.addEventListener("click", function (event) {
set_visibility('hidden')
let element = tab_panels[index].querySelector('div[data-testid="stVerticalBlock"]');
let main_block = window.parent.document.querySelector('section.main div[data-testid="stVerticalBlock"]');
const waitMs = 1;
function waitForLayout() {
if (element.offsetWidth === main_block.offsetWidth) {
set_visibility("visible");
} else {
setTimeout(waitForLayout, waitMs);
}
}
waitForLayout();
});
});
</script>
""", height=0)
import streamlit as st
from streamlit.components import v1
st.title('Content inside tabs jitters on first load')
t1, t2, t3 = st.tabs(['First tab', 'Second tab', 'Third tab'])
t1.header('This content is inside the first tab')
t2.header('This content is inside the second tab')
t3.header('This content is inside the third tab')
v1.html("""
<script>
function checkElements() {
const tabs = window.parent.document.querySelectorAll('button[data-baseweb="tab"] p');
const tab_panels = window.parent.document.querySelectorAll('div[data-baseweb="tab-panel"]');
if (tabs && tab_panels) {
tabs.forEach(function (tab, index) {
const tab_panel_child = tab_panels[index].querySelectorAll("*");
function set_visibility(state) {
tab_panels[index].style.visibility = state;
tab_panel_child.forEach(function (child) {
child.style.visibility = state;
});
}
tab.addEventListener("click", function (event) {
set_visibility('hidden')
let element = tab_panels[index].querySelector('div[data-testid="stVerticalBlock"]');
let main_block = window.parent.document.querySelector('section.main div[data-testid="stVerticalBlock"]');
const waitMs = 1;
function waitForLayout() {
if (element.offsetWidth === main_block.offsetWidth) {
set_visibility("visible");
} else {
setTimeout(waitForLayout, waitMs);
}
}
waitForLayout();
});
});
} else {
setTimeout(checkElements, 100);
}
}
checkElements()
</script>
""", height=0)
Would Streamlit consider just including your function in their source code, or would it be considered too hacky?
system
Closed
June 4, 2024, 8:19pm
14
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.