great-tables icon indicating copy to clipboard operation
great-tables copied to clipboard

FR: scrollable tables with sticky headers

Open avamsi opened this issue 10 months ago • 7 comments

Prework

Proposal

I started using great-tables in Jupyter Notebooks recently and would love to have a knob to make large tables scrollable natively with sticky headers, so it's easier to parse the data. I didn't find any similar open issues but #578.

avamsi avatar Jan 24 '25 06:01 avamsi

A workaround I'm using at the moment is to inject some custom CSS like:

%%html

<style>
.gt_table {
    display: block !important;
    max-height: 80vh;
    overflow-y: auto;
}

.gt_col_headings {
    position: sticky;
    top: 0;
}
</style>

avamsi avatar Jan 25 '25 18:01 avamsi

this is interesting! - Can you show the code with the GT object too?

Yasin197 avatar Feb 07 '25 17:02 Yasin197

Just the CSS snippet is enough, you don't need any other changes (with the GT object).

avamsi avatar Feb 07 '25 18:02 avamsi

sure but can you show me how it's put together?

if i take this example, how can i add your CSS snippet to this to make the sticky and scrollable?:

Sample data for the DataFrame

data = { 'Column1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'Column2': ['A', 'B', 'C', 'D', 'E', 'A', 'B', 'C', 'D', 'E', 'A', 'B', 'C', 'D', 'E', 'A', 'B', 'C', 'D', 'E'] }

Create the DataFrame

df = pd.DataFrame(data)

GT(df)

Yasin197 avatar Feb 10 '25 16:02 Yasin197

You just copy the snippet from https://github.com/posit-dev/great-tables/issues/585#issuecomment-2614053987, put it in a different code cell and run it.

For example, you might have 3 code cells like:

import great_tables as gt
import polars as pl
%%html

<style>
table {
    display: block !important;
    max-height: 80vh;
    overflow-y: auto;
}

table > thead {
    background-color: white;
    box-shadow: 0 1px 1px -1px #bdbdbd;
    position: sticky;
    top: 0;
}
</style>

(Note that this snippet is slightly different from the snippet above -- I just figured why not generalize it to any table and its header, so this works for native Polars DataFrame renders as well.)

gt.GT(pl.DataFrame({"x": range(1000)}))

avamsi avatar Feb 10 '25 17:02 avamsi

I'm wondering if this could also be achieved using anywidget (#301).

jrycw avatar Mar 12 '25 14:03 jrycw

table = table.tab_style( style=style.css(rule='position:sticky;left: 0;'), locations=loc.stub() )

This seems to be a more native to GT solution

mhcwainwri avatar Aug 18 '25 19:08 mhcwainwri