Scrolling bar in a <Table> with "responsive" columns
I'm trying to design a table with a scroll bar.
The problem is that the columns don't adjust according to the information contained in the scrollbar. All the columns keep the same proportion because of the scrollbar located in <tbody>.
I therefore used Typescript code to modify the width of each column according to its content. It works fine, but the alignment of columns and values is not good. What's more, the scroll bar is inside the last column and alters the style of the buttons contained in the cells.
I don't know how to make the columns proportional and aligned according to the values, so that the style of the buttons isn't altered and the scroll bar is more outwards.
You can find the code on GitHub in the link "Click here".
And on Stackblitz "Click here"
Thanks for your help
44 Replies
have you tried using grid?
i've made tables responsive before by using grid
No I didn't, I will try. But I would like to understand in my case how can I make it works 🙂
well, instead of using the table to layout it, use grid for the layout
^ this is what makes the table's layout behave like absolute crap
Thank you for your advice, can you give a little bit more about the code ?
maybe you mean replace all of the table code by a grid code ?
not all of it
just the layouting part
just for the
<tr>
There is so much going on in that CSS it is hard to see the wood for the trees.
I suspect that one of your issues is that you have applied
display:flex
to the td cells with the class "action" - this is messing up your column alignment.
My first suggestion would be to place the buttons within a container within the cell, something like this:
it starts with the
tbody
having display: block
it completely ruins the layouting of the table
display: flex
for the td
just makes it even worse
and then adding a div
really doesn't help it at all@Chris Thanks for your suggestion, it solved part of the problem.
@ἔρως Can you to provide more code for your idea, as all the attempts I've made have been unsuccessful.
literally
display: grid
with grid-template-columns
set on each tr@ἔρως Sorry, but this doesn't make the trick, or I haven't code your idea correctly. So please provide any complete fixes to be made. Thank you very much. 🙂
As Epic has said,
display:block
is messing things up. However, in reality there is more to it than that. For example the styling directly on the <th> contents to make them look like buttons is also messing with things (in a similar way to what I mentioned about about the buttons). It would be better to style child elements than the cell itself.
I would change the HTML to this:
And replace the table related CSS to something like this:
Note - I haven't tried Epics suggestion of using grid, that may be simpler than what I am suggesting.the grid idea is just for allowing the tbody to be scrollable while keeping a sensible layout for desktop and mobile, and to make it responsive
what ive done in the past is to do something like
grid-template-columns: 1f 1f auto 50px
and when things get tight i just do 1fr 1fr
or 1fr auto
or something like that, depending on the expectations
and obviously, hide the thead, so it doesnt look scuffed
that is one of the things that got me the interview at my current job@ἔρως and no need of typescript code ?
nope, 100% css
Base on what you said I did this coding:
Has you can see on the screenshot the columns are not aligne 😦

to have the thead and tbody exactly the same, i think you need to use sub-grids
or, as the cost of usability, skip the thead
your problem is that your data isnt uniform at all, and you are trying to
auto
your way into it
but you can do it by setting the first and last column to a fixed width
and everything else will align, or use subgrid
quantity will never be bigger than, say, 80px
the column with the buttons? same thing
80px 1fr 1fr 80px
and it should look almost the same
if the word doesnt fit, 120px for quantityWell the code should be reusable so I need "auto" that's my main point and the difficulty 🙂
oh, yeah, that is a pita then
have you tried to look into existing solutions?
i remember doing this with bootstrap
I've tried a lot of things and the best way was to use typescript to do it.
I any case I want to tell you thank you to you and to @Chris Bolson for trying to help.
I still have to try Chis solution 🙂
try his solution
go for it
my solution, admitedly, isnt very generic
by the way, give bootstrap a peek
the problem on @Chris Bolson solution is the the scrolling is on the "table-wrapper" and not on <tbody>
ignore this, i misremembered and they dont have an horizontally scrolling table
ah, sorry, I didn't realize that that was a requirement 🤦♂️
I just assumed (my mistake) that what you needed was to have a sticky thead and scrolling tbody.
@Chris Bolson It's because of the scrolling in the <tbody> that I have all this mess
ok, I see. I thought that your issue was the missalignment of the header columns with the body columns, which, as Epic said right from the start, was due to the tbody having display: block.
Let me take another look.... (I still think that the it would be better to style the contents as child containers rather than styling the table cells themselves)
i told you: it all starts from the display block on the tbody, which nukes the layouting of the table
but you need it to have the scroll
hey, is the thead always the same height?
If you do go with having display:block on the tbody you should also have it on the thead
@ἔρως Yes the height can be the same.
how about this dumb idea:
- tbody with margin the height of the thead
- position sticky on the thead
- wrapper with position relative and max height with overflow hidden
or, if you dont like that because the scroll is on the wrapper, put another wrapper but with overflow visible, for the scroll to look like it is on the tbody
and the thead floats off of the way
i will try that later
Stack Overflow
HTML table with 100% width, with vertical scroll inside tbody
How can I set for <table> 100% width and put only inside <tbody> vertical scroll for some height?
table {
width: 100%;
display:block;
}
thead {
display: inline-blo...
some stuff there might work for you
I got this using your display:block method.
Ignore the red dashed lines, they are just to check that the columns are aligned.
Is that closer to what you wanted?
It looks like 🙂
without red lines
If you want the thead and tbody columns to align, they need to have the same basic properties such as inline padding. They also need to be the same width and have the same display style (eg block).
I modified a fair amount of your styling and moved the header and row "buttons" into child containers so that their styling doesn't mess with the main table layout.
I didn't touch your JS (Typescript) as I suspect that you are right in that that is the only way to ensure that the header columns and the body columns are the same width (as you are essentially separating them from each other by defining the display: block).
All the columns have the same width. 😦
It's the problem I've got and try to resolved with typescript
excuse the silly question but how do you save changes in stackblitz?
I have forked your version (I will delete it later) to make my changes but can't find the option to "save". If I copy the URL and open it in a new tab, it doesn't show any of the changes so I assume that there is no auto save.
ok, scrub that. The "save" icon has miraculously appeared in the top-left corner - I am sure it wasn't there when I asked the question here.
Here is my forked and modified version in case you are interested.
Chris Bolson
StackBlitz
Vitejs - Vite (forked) - StackBlitz
Next generation frontend tooling. It's fast!
@Chris Bolson Beautifull !! Thanks !!
I just need to resolve the problem with the quantity title when you shrink the widow to much

smaller font size
Yes
and less inline padding
I hope that can help other that need the same stuff. Thank you so much