Misaligned header when using scrollX and margin:auto
Misaligned header when using scrollX and margin:auto
mwouts
Posts: 20Questions: 3Answers: 0
Hi there,
I have recently added a "Streamlit" component to ITables, that let Python users render their DataFrames as interactive datatables in that context - see the demo here: https://itables.streamlit.app/
For the Streamlit component I've had to set scrollX=True by default as the tables are rendered with an iframe that, unlike Jupyter Notebook outputs cells, don't have an horizontal scroll bar.
This mostly works, but when I try to center the table using margin:auto;table-layout:auto;width:auto;caption-side:bottom for the style, I get a centered table but the header remains on the left, like in the screenshot below.
Do you see how to fix that? Thanks!

This question has an accepted answers - jump to answer
Answers
NB: to really get
)
margin:autoin the app above, it's necessary to set it as the beginning or final condition (or to use a space), because the app currently replaces;margin:auto;with;margin:0;(that was an effort to no expose the users to this issueA common problem is that Datatables needs
style="width:100%"set on thetabletag, as shown in this example to help calculate column sizes. Looks thewidth:auto;sets the table width at 844px no matter the page width. Inspecting the table shows this:Not sure how to set this specifically on the
tabletag in your environment. Possibly setting ``width:100%;` will work.Kevin
Thank you Kevin!
I experimented with the table style set to
margin:auto;table-layout:auto;width:100%;caption-side:bottom(through the "style" text input in the app) but I am afraid I still get the issue (I will try harder this week-end!)What you have highlighted is the
div. Look at thetabletag instead:Not sure if the test case you linked to is updated but it still shows a width of 844px.
Kevin
I looked at this more and realized this is a sample app from the developers of iTables. Looking at it further it seems that no matter what the width setting in the Style input is set to the
tabletag haswidth: 844pxset. For example:I would check with the iTables developers about the column width issue when using
scrollX. Its unclear what exactly they are doing to setup the HTML and Datatables environment. Looks like you can ask about this here:https://github.com/mwouts/itables/issues
Kevin
Thanks Kevin! BTW I do maintain ITables and that's why I am trying to get this right
The style in the text box is passed verbatim to the table (well except for the replacement of
;margin:auto;with;margin:0;which I will remove when we solve this). It is set using table.setAttribute('style', style) and I can confirm that at the timestyleis set, it haswidth:100%if I pass that in the text box. So it must be changed to a fixed pixel width later on?Is it possible that calling
new DataTablechanges the style? When I log the style attribute I find, for instance:- (before)
margin:auto;table-layout:auto;width:100%;caption-side:bottom- (after)
margin: auto; table-layout: auto; caption-side: bottom; width: 0px;I also tried setting the style after calling
new DataTablebut then the caption was located between the table header and the rows. And if I set the style twice (before and afternew DataTable) then I get a stretched table which is consistent withwidth:100%but is not what I am looking for...I also tried
dt.columns.adjust()as mentioned in https://datatables.net/forums/discussion/49564/scrolling-header-alignment but that had no effect, probably because my table is not 'visible' at that time.Maybe what I am after is more a behavior like
overflow-x:scroll;as mentioned in that other thread, e.g. keep the table centered if there are not too many columns, and scroll only if it does not fit the container. Is that possible using only the standard DataTables arguments? (I have transitioned to thelayoutargument so I don't see myself adding a dedicated div in thedomargument as in the other thread).Looking at this example the
tabletag hasstyle="width:100%"the width of thetablehas a specific value. Note that Datatables clones the header, displays the cloned header and hides the original header withheight: 0;. It looks like the clonedtablehas the defined width in px. I didn't realize that happened. Sorry for the misleading suggestion.Use
columns.adjust()after the table becomes visible. See this example. I'm not sure how you are making the table visible. Maybe there is an event you can use or possibly a short setTimeout() to executecolumns.adjust().As a test maybe you can initialize Datatables with the table visible.
Kevin
Thanks Kevin! Sorry for taking that much of your time. I have tried
columns.adjust()in a simpler context where I think that the table is initially visible, but that did not help.What I did precisely what to modify the html template in this way:
then I displayed a table with a style set to

margin:auto;width:auto, andscrollX=true:What I find strange (but I am afraid I know too little of html) is that the table gets a (fixed) width in pixels while

dt-scroll-bodyanddt-scroll-footget a width of100%It isn't clear to me that your
columns.adjust()call there would happen after the table is made visible. It looks like it is just running immediately after the table is initialised, which wouldn't make any difference since the table initialisation already does column adjustment.As a hacky test, try resizing the window - if the table springs into the right size then you will need to discover whatever event it is, or code action that is making the table visible and trigger that. Perhaps it is in a tab, or there is a fade effect on the whole page or something?
Allan
Thank you Allan. Well even if I use
setTimeoutand check (visually) that the table is visible beforedt.columns.adjust()is called, I still get the misaligned header. I have extracted below a short HTML file that shows the issue. Thank you for your help with this!Thanks for the extra code!
Here is that example running: https://live.datatables.net/zixucoyu/1/edit .
And with
width:autochanged to bewidth:100%it is fixed: https://live.datatables.net/zixucoyu/2/editYou can remove the
setTimeoutwith that. The key is to setwidth:100%.Allan
Thanks Allan! I agree than setting
width:100%aligns the header and table body (and I don't think I needdt.columns.adjust()in that case).Let me try to describe what I am trying to achieve:
1. I am looking for a default that would trigger an horizontal scroll bar for wide tables, but would work also for non-wide tables (and I don't know whether the table is wide or not, so I can't set scrollX dynamically)
2. I'd like to not stretch the table
3. I'd like to keep the table centered
If I use
-
scrollX=False,margin:auto;width:auto(the current default in Jupyter for ITables) then I get 2 and 3 (and Jupyter does provide an horizontal scroll so I almost get 1 - but I don't get that in the newer rendering context called "Streamlit")-
scrollX=True,margin:auto;width:100%then I get 1 and 3, but a stretched table like here: https://live.datatables.net/zixucoyu/4/edit-
scrollX=True,margin:auto;width:auto;float:leftthen I get 1 and 2, but a left sided table like here: https://live.datatables.net/zixucoyu/6/edit-
scrollX=True,margin:auto;width:autothen I get 1, 2 and 3 - except for the misaligned headerDo you see any other way to get 1+2+3 other than aligning the header with the table in the last configuration?
Thanks! I've got a bitter idea of what you want now, and given that you only want horizontal scrolling, not vertical, what I would do is set the table width to be
autoas you originally did (and addmargin: 0), but don't enablescrollX. Instead, simply place the table in adivwhich hasoverflow: auto.https://live.datatables.net/zixucoyu/8/edit
That way the table will be as narrow as it can be, but it has space that it can grow into and will overflow horizontally if needed.
The only downside is that the paging controls / filter would scroll out of sight at well, but that might not be an issue if you aren't using them (like in this example), or you could reposition them.
If this is what you are looking for, a perhaps better way of doing it, is to make the
divthat DataTables puts immediately around the table the scrolling element. That can be done with a little CSS.Allan
Thank you Allan (and Kevin) for your patience! Yes you're completely correct, the little CSS in your last link is what I was looking for!
I will now use, in the next PR,
rather than the
scrollXoption (except possibly in certain cases like the fixed columns...). This seems to work well in Jupyter, in Jupyter Book (= the documentation site) and in Streamlit too. Thank you again!Yeah, that workaround won't work with FixedColumns (or probably FixedHeader) unfortunately.
I had actually looked at using this method in DataTables 2 when vertical scrolling wasn't enabled. It solves a lot of issues, but introduces others...! You win some, you loose some. This one is a score draw
Allan
hope this help
https://stackoverflow.com/questions/34897030/header-columns-misaligned-with-datatable-when-scrollx-is-enabled