LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-28-2019, 10:42 AM   #1
mfoley
Senior Member
 
Registered: Oct 2008
Location: Columbus, Ohio USA
Distribution: Slackware
Posts: 2,555

Rep: Reputation: 177Reputation: 177
HTML How to get thead and tbody to align


I'd like to have a scrollable <tbody> in my table with the header staying fixed. None of the "tips" I've found work for me (Firefox or IE). The following:
Code:
<table>
<thead>
  <tr><th> ... </th></tr>
  <tr><th> ... </th></tr>
</thead>

<tbody style="height: 500px; overflow-y: auto">
  <tr><td> ... </td></tr>
  <tr><td> ... </td></tr>
</tbody>
</table>
Does nothing special. The body is not scrollable.

The following:
Code:
<table>
<thead style="display: block">
  <tr><th> ... </th></tr>
  <tr><th> ... </th></tr>
</thead>

<tbody style="display: block; height: 500px; overflow-y: auto">
  <tr><td> ... </td></tr>
  <tr><td> ... </td></tr>
</tbody>
</table>
Does give me a scrollable tbody, but the thead is all compressed to the left, not aligned with tbody. setting thead to width: 100% does nothing. Keeping the "width: 100%", but removing the "display: block" from thead stretches the row all the way across the page, not just to the width of the table. Removing "width: 100%" and adding "display: table-header-group" also stretches the row to full page width.

I can't think of any combinations that will work other than using the 2nd example and hard-coding the width of header elements and body elements -- not what I want to do.

Suggestions?
 
Old 02-28-2019, 11:21 AM   #2
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,307
Blog Entries: 3

Rep: Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721
One ham-fisted way would be to force the columns to be certain widths.

Code:
    tr th { width: 10%; }
    tr td { width: 10%; }
Or

Code:
    tr th:nth-child(1) { width: 15%; }
    tr th:nth-child(2) { width: 10%; }
    tr th:nth-child(3) { width: 20%; }
    tr th:nth-child(4) { width: 25%; }
    tr th:nth-child(5) { width: 10%; }

    tr td:nth-child(1) { width: 15%; }
    tr td:nth-child(2) { width: 10%; }
    tr td:nth-child(3) { width: 20%; }
    tr td:nth-child(4) { width: 25%; }
    tr td:nth-child(5) { width: 10%; }
I would hope there is a better way though. Certainly I would have expected the table layout to default to what you are asking, but I guess it's not the case.
 
Old 02-28-2019, 11:37 AM   #3
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,307
Blog Entries: 3

Rep: Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721
I got curious and searched a bit. It looks like if you set the scope attribute, it fixes column widths:

Code:
    <thead>
      <tr>
        <th scope="col">One</th>
        <th scope="col">Two</th>
        <th scope="col">Three</th>
        <th scope="col">Four</th>
        <th scope="col">Five</th>
        <th scope="col">Six</th>
      </tr>
    </thead>

Source: https://www.w3.org/TR/WCAG20-TECHS/H63.html
 
1 members found this post helpful.
Old 02-28-2019, 11:39 AM   #4
scasey
LQ Veteran
 
Registered: Feb 2013
Location: Tucson, AZ, USA
Distribution: CentOS 7.9.2009
Posts: 5,727

Rep: Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211
You're putting each cell on a seperate row
Try
Code:
<table>
<thead style="display: block">
  <tr><th> ... </th><th> ... </th></tr>
</thead>

<tbody style="display: block; height: 500px; overflow-y: auto">
  <tr><td> ... </td><td> ... </td></tr>
</tbody>
</table>
Note that the code need not be on a single line
Code:
<tr>
     <th> ... </th>
     <th> ... </th>
</tr>
is equivalent, and is the way I'd usually write it.
Not sure what the CSS is doing for you.

PS: set width on the <table> tag, not on the <tr> tag.
Either
Code:
<table width=500px>
or, better,
Code:
<table style="width: 500px">

Last edited by scasey; 02-28-2019 at 11:45 AM.
 
1 members found this post helpful.
Old 02-28-2019, 03:44 PM   #5
mfoley
Senior Member
 
Registered: Oct 2008
Location: Columbus, Ohio USA
Distribution: Slackware
Posts: 2,555

Original Poster
Rep: Reputation: 177Reputation: 177
Quote:
Originally Posted by Turbocapitalist View Post
One ham-fisted way would be to force the columns to be certain widths.
Yes, I mentioned that, but that's exactly what I'm trying to avoid. Column widths may vary depending on contents.
Quote:
Originally Posted by Turbocapitalist View Post
I got curious and searched a bit. It looks like if you set the scope attribute, it fixes column widths:
That didn't work. Using the scope="cols" exactly as you've shown still puts the header row to full-width of the page. Adding "display: block" compacts the header row to the left. This is true on both Firefox and IE. The scope attribute seems to have no effect at all. Your link does no really say that the scope attribute will align header cells with body cells, nor do the examples I looked at use thead and tbody.
Quote:
Originally Posted by scasey View Post
You're putting each cell on a separate row
:
PS: set width on the <table> tag, not on the <tr> tag.
Actually, no I'm not. Look again. I am specifying more than one row in <thead>, but the cells are not on separate <tr>'s. I do have a width set on the table. I don't have any widths set on the <tr>.

Hopefully you all, or someone, has some additional ideas. Otherwise, it seems like setting explicit widths on the columns is the only solution -- which I'm not going to do. In which case I think the thead and tbody tags need a bit more work to be really useful.

Last edited by mfoley; 02-28-2019 at 04:19 PM.
 
Old 02-28-2019, 06:42 PM   #6
scasey
LQ Veteran
 
Registered: Feb 2013
Location: Tucson, AZ, USA
Distribution: CentOS 7.9.2009
Posts: 5,727

Rep: Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211
Quote:
Originally Posted by mfoley View Post
I'd like to have a scrollable <tbody> in my table with the header staying fixed. None of the "tips" I've found work for me (Firefox or IE). The following:
Code:
<table>
<thead>
  <tr><th> ... </th></tr>
  <tr><th> ... </th></tr>
</thead>

<tbody style="height: 500px; overflow-y: auto">
  <tr><td> ... </td></tr>
  <tr><td> ... </td></tr>
</tbody>
</table>
Does nothing special. The body is not scrollable.

The following:
Code:
<table>
<thead style="display: block">
  <tr><th> ... </th></tr>
  <tr><th> ... </th></tr>
</thead>

<tbody style="display: block; height: 500px; overflow-y: auto">
  <tr><td> ... </td></tr>
  <tr><td> ... </td></tr>
</tbody>
</table>
Actually, no I'm not. Look again. I am specifying more than one row in <thead>, but the cells are not on separate <tr>'s. I do have a width set on the table. I don't have any widths set on the <tr>.
I'm sorry, but
Code:
<tr><th>content</th></tr>
<tr><th>content</th></tr>
IS specifying two rows (<tr></tr>), each containing one cell (<th></th>)
and the only place you've set width is on the tbody tag, which is NOT the <table> tag

Please try my suggestions to see if they give you what you want...then state specifically why they don't, if they don't.

Does this help?

Last edited by scasey; 02-28-2019 at 06:46 PM.
 
1 members found this post helpful.
Old 02-28-2019, 11:44 PM   #7
mfoley
Senior Member
 
Registered: Oct 2008
Location: Columbus, Ohio USA
Distribution: Slackware
Posts: 2,555

Original Poster
Rep: Reputation: 177Reputation: 177
Quote:
Originally Posted by scasey View Post
I'm sorry, but
Code:
<tr><th>content</th></tr>
<tr><th>content</th></tr>
IS specifying two rows (<tr></tr>), each containing one cell (<th></th>)
and the only place you've set width is on the tbody tag, which is NOT the <table> tag

Please try my suggestions to see if they give you what you want...then state specifically why they don't, if they don't.

Does this help?
Perhaps my meta-syntax is throwing you off. I have elipses in the row description: <tr><th> ... </th></tr>, which was intended to mean multiple columns. The elipses were not intended to indicate <th> content. It would have been more clear had I done, <tr><th>text</th><th>text</th> ... <th>text</th><th>text</th></tr>.

In any case, my actual table <thead> section does have two rows of multiple columns. I've also done one row of multiple columns, makes no difference.

That link you referenced is exactly where I went in the first place, having never done anything with thead or tbody tags before.

As an experiment, if you think you have a handle on how this should work, snag the html below and see if any of your ideas let the thead section line up with the tbody. Never mind explicitly setting column widths. I know I can make that work. They also line up OK if there is no block/height/overflow styling on the tbody, but that, I think, is rather the point of having the thead/tbody tags. Otherwise, it's just a normal table and thead/tbody adds nothing.
Code:
<!DOCTYPE html>
<html>
<body>
<table>
<thead>
<tr><th>The</th><th>rain</th><th>in</th><th>Spain</th></tr>
</thead>
<tbody style="display: block; height: 80px; overflow-y: auto">
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
</tbody>
</table>
</body>
</html>
Thanks --Mark

Last edited by mfoley; 02-28-2019 at 11:47 PM.
 
Old 03-01-2019, 12:47 AM   #8
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
started fiddling, then i remembered:
some folks never search before posting.
try this:
HTML How to get thead and tbody to align
 
Old 03-01-2019, 06:33 PM   #9
mfoley
Senior Member
 
Registered: Oct 2008
Location: Columbus, Ohio USA
Distribution: Slackware
Posts: 2,555

Original Poster
Rep: Reputation: 177Reputation: 177
Quote:
Originally Posted by ondoho View Post
started fiddling, then i remembered:
some folks never search before posting.
try this:
HTML How to get thead and tbody to align
I'll assume that "never search" comment wasn't directed to me specifically. I visited all those pages previously. None of the ideas worked. The thead and tbody align just fine until you put the height and overflow-y attributes in the tbody. Try it. Copy/paste my simple example and try it in your browser. I've done some additional test settings based on those very suggested sites that don't work for aligning thead and tbody:
Code:
<style>
thead th{ display: table-cell;}    
</style>
</head>
<body>
<table style="table-layout:fixed">
<thead style="display: table-header-group;">
<tr><th>The</th><th>rain</th><th>in</th><th>Spain</th></tr>
</thead>
<tbody align=right style="display: block; height: 80px; overflow-y: auto;">

Last edited by mfoley; 03-01-2019 at 06:43 PM.
 
Old 03-01-2019, 07:22 PM   #10
AnanthaP
Member
 
Registered: Jul 2004
Location: Chennai, India
Posts: 952

Rep: Reputation: 217Reputation: 217Reputation: 217
I had read about javascript code about this topic now googled this.

https://codereview.stackexchange.com...igning-columns
It's got "run script options" to check it out.

Does it help?
 
Old 03-01-2019, 08:07 PM   #11
mfoley
Senior Member
 
Registered: Oct 2008
Location: Columbus, Ohio USA
Distribution: Slackware
Posts: 2,555

Original Poster
Rep: Reputation: 177Reputation: 177
Quote:
Originally Posted by AnanthaP View Post
I had read about javascript code about this topic now googled this.

https://codereview.stackexchange.com...igning-columns
It's got "run script options" to check it out.

Does it help?
Yeah, I saw that one too, but wow! He's got javascript, I assume running onload, that compares the width of the th cell in the <thead> (assuming all th's are in <thead>) with the width of the corresponding td cell in the <tbody> and sets both cells' widths to the max of either. This example assume only one table in the page as he gets all th and td elements, but that could be handled by adding names or ids or some other identifier to the elements of the target table.

I was hoping for something a bit less complex, but maybe that's as good as it gets. I'll experiment with that and post back.

Last edited by mfoley; 03-01-2019 at 08:10 PM.
 
Old 03-01-2019, 11:26 PM   #12
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,307
Blog Entries: 3

Rep: Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721
You might try asking on css-d -at- lists.css-discuss.org before sinking to javascript. That list, if any, would have people who should be able to figure out the answer to getting both the scrolling and the matching columns at the same time. If you do find an answer that is only CSS, please do remember to post it here.
 
Old 03-04-2019, 11:14 AM   #13
mfoley
Senior Member
 
Registered: Oct 2008
Location: Columbus, Ohio USA
Distribution: Slackware
Posts: 2,555

Original Poster
Rep: Reputation: 177Reputation: 177
I'm throwing in the towel on this one. I tried a simplified javascript based on AnanthaP's link:
Code:
function adjusttbody()
{
    thElements = document.getElementsByTagName("th");
    tdElements = document.getElementsByTagName("td");

   for (var i = 0; i < thElements.length; i++)
        tdElements[i].style.width = thElements[i].offsetWidth + "px";
}
But that didn't work. If I need that elaborate set of css definitions the author of that link example has, it's not worth the trouble.

Turbocapitalist, excellent suggestion with the maillist, but I'm done investing time in this. Besides, if there were a css only solution someone would have probably posted it. I'm on a number of lists and normally those list postings are findable.

I suppose <tbody> could be useful for hiding sections of a table given multiple <tbody> statements, but for scrolling it seems near useless.

I'll revert to an easier solution I've used in the past which is to have 2 tables:
Code:
<table style="margin: 0; width: <nnn>px">
<tr><th>head1</th><th>head2</th> ... <th>headN</th></tr>
</table>
<div style="width: <nnn>px; margin: 0; height: <yyy>px; overflow: auto">
  <table style="margin: 0; width: 100%">
<tr><td>col1</td><td>col2></td> ... </td>colN</td></tr>
:
:
</table>
</div>
Then, all I have to do is adjust the column widths as needed. I could probably even use that script to do the width automatically. (I might try that)

Last edited by mfoley; 03-04-2019 at 11:21 AM.
 
Old 03-04-2019, 11:41 AM   #14
mfoley
Senior Member
 
Registered: Oct 2008
Location: Columbus, Ohio USA
Distribution: Slackware
Posts: 2,555

Original Poster
Rep: Reputation: 177Reputation: 177
Actually, the <table><div> technique works like a champ with the auto-adjust javascript function. I don't even need to hard-code column widths unless I want to tweak. You do have to set the header table with and the <div> width to line up. To the devil with <thead><tbody>!
Code:
<!DOCTYPE html>
<html>
<head>
<style>
td, th { border: 1px solid red }
table { border-collapse: collapse }
</style>
<script>
function adjusttbody()
{
    thElements = document.getElementsByTagName("th");
    tdElements = document.getElementsByTagName("td");

    for (var i = 0; i < thElements.length; i++)
        thElements[i].style.width = tdElements[i].offsetWidth + "px";
}
</script>
</head>
<body onload="adjusttbody()">

<table style="margin: 0; width: 484px">
<tr><th>The</th><th>rain</th><th>in</th><th>Spain</th></tr>
</table>
<div style="width: 500px; margin: 0; height: 80px; overflow: auto">
<table style="margin: 0; width: 100%">
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
<tr><td>Falls mainly</td><td>In the Plain</td><td>Falls mainly</td><td>In the Plain</td></tr>
</table>
</body>
</html>

Last edited by mfoley; 03-04-2019 at 11:43 AM.
 
1 members found this post helpful.
Old 03-04-2019, 11:46 AM   #15
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,307
Blog Entries: 3

Rep: Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721
What were the CSS specialists on the mailing list able to figure out? Or did they not respond?
 
  


Reply

Tags
html, table



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Can't get conky to align correctly BobSwi Slackware 4 07-08-2016 01:34 PM
The teddy bear thead! ButterflyMelissa General 9 07-20-2011 04:35 AM
align columns of strings and explain '\t' (java) dave bean Programming 3 01-10-2004 10:55 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:53 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration