Here's some background info before I get to my question...I am implementing a JavaScript library for supporting HTML tables that have scrollable bodies and stationary headers.
Requirements:
The table layout must work the same as in a normal table; the column sizes should grow or shrink to fit the contents
Multi-row headers must be supported along with reasonable use of colspan and rowspan therein.
The library should work on virtually any table, provided that the table adheres to the structure prescribed by the ScrollTable library.
Support an arbitrary number of columns.
Support arbitrary formatting of the table cells (e.g., thickened column separators between column groups)
Assumptions:
The header has no more than 2 rows
A given cell in the header can use colspan or rowspan, but not both
Each logical column in the header table contains at least one cell that does not span multiple columns.
The cells in the body do not use colspan or rowspan
How I implemented it:
Separate the table into two tables: a table of header cells and a table of body cells
Wrap each table in a <div> and then both of those in one “ScrollTable” <div>
The div containing the body table is what facilitates the scrolling
The main <div> has display: inline-block to shrink to fit its contents
Use table-layout: fixed to allow for explicit column sizing
Use box-sizing: border-box; and -moz-box-sizing: border-box; on the table cells to make column-sizing easier
Implement an updateLayout method:
Clear any explicit column widths to allow natural column sizing to occur in both tables
Loop over a representative set of cells from the header table and body table – one cell per column.
For each column, assign the bigger column width from the header or body table in both tables.
For the header table, assign the widths to the <col> elements if the table has them. If the table doesn't have <col> elements, try to assign the widths to the cells in its first row.
For the body table, assign the widths to the cells in the table's first row
Snags that I ran into but overcame:
Retrieving the widths of the columns.
The ScrollTable needs to support multi-row headers. And the cells therein might use colspan or rowspan. So I can’t just grab an entire row of cells.
You can’t get a list of columns. You can get a list of <col> elements if the table’s markup includes them, but you can’t use them to access the columns’ widths.
You can access a column’s width from cells within the column, though, so I solved the problem by writing a function that loops over the cells in the header and retrieves a representative set of cells, where the cells might not all come from the same row.
For tables with table-layout: fixed, the table and column widths are set by the widths of <table> and <col> elements or by the width of the first row of cells. That’s it; cells in subsequent rows do not affect column widths.
This ultimately means that support for multi-row headers (which might use rowspan or colspan) can only be achieved by requiring the markup of ScrollTables that have multi-row headers to include a <col> element for every column in the header.
Snags I have yet to overcome:
When I assign a width to a <col> element, it doesn’t give quite the same width as when I assign that same width to a table cell. And box-sizing: border-box; and -moz-box-sizing: border-box; appear to have no effect on <col> elements.
Question:
How can I ensure that the width I assign to the <col> elements gives the same rendered width as what I assign to the table cells?
Related
I am new to docx . I have table which have multiple columns. It works fine with auto width if I have table body cell but I doesn't work for empty body.
I am getting compressed columns row also I want to set width for every cell.
I want to apply styles to a certain column in a table. I can try nth-child but the thing is that the table columns has reorder property. It means users can reorder table columns according to his convenience. In this case, the nth-child index will be changing.
I have two tables adjacent to each other both being populated dynamically in C#, I want both of these two tables to have the corresponding row height be exactly the same depending on what the first tables row height is (no specific height has been set, just needs to fit text in).
I have tried various ways of getting the height in C#, javascript, jquery, etc however they all return null or 0, i can get it to work by actively setting the height however this is not very effecient and occasionally buggy, is there a way I can get the height of a dynamically created html table row/cell?
#JoseRuiSantos comment is a better implementation if your design allows it (i.e. combine data in both tables in to a single table and accordingly render rows and columns to display as two different tables using css).
One way I could think is to try using javascript:
For this to work, do not set any table/row/column heights in both tables.
Add an empty column at the end of each table with a div element in it. In the page load completed event, identify the max column height in corresponding row of both tables and set the corresponding div element's (in both tables) height (in corresponding row) to the column max height.
In HTML <table>
Using Javascript, i want to make square (or nearly square) the tallest cell (having max no. of lines) in every row, which results in decreasing rows height and make table compact.
Link: http://jsfiddle.net/okoer70u/ . See unnecessary white-space in ROWS, if we add white-space:nowrap to table then columns will have extra white-space.
All my tables are wider than screen and totally different cells text length and no. of cells so i can't use css like width min-width etc.
fyi, I am not using jquery.
What about wrapping the text inside the cells in a div. then count characters to find biggest?
please help
I am having trouble to fix the header of a table, here is my issue:
I used the same code from this post:
Table header to stay fixed at the top when user scrolls it out of view with jQuery
It is almost working, but the problem is the width of the header changed when I scroll down.
I wonder what I am doing wrong. I tried the following code to fix the width, but does not work.
$("#header-fixed td").each(function(index){
var index2 = index;
$(this).width(function(index2){
return $("#table-1 td").eq(index).width();
});
});
Here is the link:
http://vvb.me/test.html
The width of table cells is determined by not only the content of that particular table cell, but also the other cells in the same vertical column as it. This is because tables form blocks so the widths of the columns must line up.
What's happening here is that the calculated width of your attached thead cells is different from the widths calculated for your detached, fixed thead cells.
In the attached thead, the widths of the cells are largely determined by the data below. In the second instance, which isn't attached to the tbody, the width is solely determined by the header tds.
One solution would be to specify the width of the cells in both theads. As an example, specifying,
<td style='...; width: 50px;'>
on all of your thead cells would make them equal.
You could also use javascript to determine the width of each attached thead cell and set the bottom thead cells to be equal to their corresponding cell. Calculating the dimensions of DOM elements can be done with Javascript/Jquery. Check out answers like this one for methods on how to do that.