Pure CSS scrolling UL LI table with fixed header
Solution 1
You can try this: DEMO
I got these correct in pure css:
- using table CSS (table, table-row, table-cell, table-header-group...)
- all cells have to be list items (LI)
- header has to be fixed when table content is scrolling
The last requirement I had to use some jquery.
Anyway what I did was create two <li class="testRow">
for <div class="testHeader">
. One of them has an id with css position:fixed
That trick accomplishes your first 3 requirements. The last one is really tricky for css alone so what I did was add jquery:
$(document).ready(function(e) {
adjustHeader();
});
function adjustHeader(){
//get width of the NOT fixed header spans
var a = $("span#tid").width();
b = $("span#tname").width();
c = $("span#tdesc").width();
d = $("span#tod1").width();
e = $("span#tod2").width();
//Change the width of the fixed header spans
//with the other headers spans
$("span#fid").width(a);
$("span#fname").width(b);
$("span#fdesc").width(c);
$("span#fod1").width(d);
$("span#fod2").width(e);
}
Hope it helped!
EDIT
Run function adjustHeader()
everytime you add new data so that the headers will realign.
Here is a DEMO
Solution 2
As soon as you specify either position: absolute
or position: fixed
on .testHeader
, it sets display: block
which overrides display: table-header-group
.
Solution 3
I believe I have solved this issue by creating a second header section. To start I duplicated the "testHeader" html:
<div class="testHeader">
<li class="testRow">
<span>ID</span>
<span>Name</span>
<span>Description</span>
<span>Other details 1</span>
<span>Other details 2</span>
</li>
</div>
<div class="secondHeader">
<li class="testRow">
<span>ID</span>
<span>Name</span>
<span>Description</span>
<span>Other details 1</span>
<span>Other details 2</span>
</li>
</div>
Note that the new "secondHeader" has a new class. This class is set to position absolute.
.secondHeader {
display: table-header-group;
position: fixed;
top: 0px;
}
Then set the original header (that gives the table its structure) to visibility hidden.
.testHeader {
display: table-header-group;
visibility: hidden;
}
You should now have a list displayed as a table, with a fixed header element that stay in position when you re size. I updated your fiddle as a demo.
Related videos on Youtube
OzrenTkalcecKrznaric
I'm in the software development since 2002, and in the web development (using Microsoft technologies) since 2008. Since I use Microsoft .NET Framework and C# daily, I gues I'm good at it. I've developed quite a few applications and components in .NET, and I have enough practical programming knowledge to solve advanced problems. So, I'm here to help. And I'll be more than happy if I get some help from you as well ;)
Updated on October 09, 2022Comments
-
OzrenTkalcecKrznaric over 1 year
I'm trying to implement a pure CSS scrolling UL-LI table with fixed header.
My requirements:
- using table CSS (table, table-row, table-cell, table-header-group...)
- all cells have to be list items (LI)
- header has to be fixed when table content is scrolling
- when table column changes width, appropriate header width should be changed
Currently I have HTML:
<ul class="testTable"> <div class="testHeader"> <li class="testRow"> <span>ID</span> <span>Name</span> <span>Description</span> <span>Other details 1</span> <span>Other details 2</span> </li> </div> <div class="testBody"> <li class="testRow"> <span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span> </li> <li class="testRow"> <span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span> </li> </div> </ul>
...and CSS...
.testTable { display: table; margin: 0px; padding: 0px; } .testRow { display: table-row; } .testRow > span { list-style:none; display: table-cell; border: 1px solid #000; padding: 2px 6px; } .testHeader { display: table-header-group; /*position: absolute;*/ } .testHeader span { background-color: #ccc; } .testBody { display: table-row-group; }
Fiddle is here: http://jsfiddle.net/ozrentk/QUqyu/1/
BUT! The moment I try to fix position of the header using
position: absolute
orfixed
, the table falls apart. I tried several techniques, but to no avail. Also, there is zero to none examples how to do this using pure table CSS.This was close, but not exactly what I require.
Is there a CSS guru that can help me?
EDIT
Now, why the hell did I want to display this list as a table?
In my dynamic ASP.NET MVC driven site I have a number of places where I return unordered lists to the browser. Browser will then take this markup and display it to the reader. But the display format itself can actually depend on context, like users display-related preferences or the device format itself. CSS is used for the display formatting, as it should be. At last, if there is some display-light-n-magic-effect to be used, jQuery and/or a plugin should be used for that, and hopefully only for that.
You see, I want my server to remain display-format agnostic. That is, I don't want my server to care about how the particular client want his display to look like. I don't want if-blocks that return unordered-list-items in one case and table-cells in the other. Of course I could have two return points, one which returns ul/li/span format and the other which returns table/tr/td, but that would be violating DRY principle.
Another thing is that I'm using a really nice jQuery plugin that displays tabular data and can be fed with list-items, but not table markup. And I decided to stick with the plugin. because I like it, it's great and supports the way my site should work.
I hope this sorts things out. You see, using one paradigm can be in contrast with the other. It turns out I have to give away general-tabular-data-semantics to have a DRY code.
P.S. The more I think about this situation, the more it looks like a pragmatic, not a semantic problem.
-
Danield over 10 yearsWhy do you need to use tables if there are other ways of doing this?
-
andi over 10 yearsYour data looks like tabular data, so I think it's more semantic in this case to use <table> for it.
-
cimmanon over 10 yearsAnything other than a table for this content would be a misuse of markup.
-
OzrenTkalcecKrznaric over 10 yearsI see lot of people are concerned of why am I using HTML list-items to display tabular data. I don't have time to explain everything now, but I promise I will do it tomorrow.
-
OzrenTkalcecKrznaric almost 11 yearsOk, but how can I get this functionality then with CSS 'table-' attributes?
-
OzrenTkalcecKrznaric almost 11 yearsThis is a problem because I'm using MVC and jQery plugin that relies on Ajaxed li's from server, which i then stuff as table cells. It doesn't work with td's. And as I understand, CSS gurus say table is so last year... hm...
-
André Dion almost 11 yearsTables are intended for tabular data. You're trying to reinvent the wheel here in a very inappropriate way. If you have control over what your server is responding with, abstract your data into a layout-agnostic format such as JSON and then render it however you want.
-
OzrenTkalcecKrznaric almost 11 yearsI already told you that there is jQuery plugin that lays out items and expects LIs, not TDs. It fails on TDs. I can't change the plugin. What would you do in my place?
-
André Dion almost 11 yearsI would ditch the plugin as it doesn't seem to fit the needs of your application.
-
OzrenTkalcecKrznaric over 10 yearsAlthough it doesn't satisfy all the requirements, this is the best solution so far. One problem I found is when I add additional items after it's displayed, header gets misaligned.
-
Jo E. over 10 years@OzrenTkalcecKrznaric I added the code to a function
adjustHeader()
and ran it ondocument.ready
. If you add new code just addadjustHeader
so that the headers will realign again. Check my edit -
Martyn0627 over 10 years@OzrenTkalcecKrznaric was this of any use?
-
OzrenTkalcecKrznaric over 10 yearsI believe this is it. I'm sorry I haven't had time to take a look at this until now, but tomorrow if tests pass, I will incorporate it into the solution we're implementing.
-
Jo E. over 10 years@OzrenTkalcecKrznaric you do know that the correct answer is NOT the correct answer right? :|
-
OzrenTkalcecKrznaric over 10 yearsWhy do you think so? I gave the sample for testing and received no objections. And it worked for me.
-
Jo E. over 10 years@OzrenTkalcecKrznaric haha ok. I thought the
header should adjust to the content
his code in this fiddle jsfiddle.net/QUqyu/25 with different values :) well its your question. you know what you need. Cheers! -
OzrenTkalcecKrznaric over 10 yearsGreat. Obviously we tested this code like this: http://jsfiddle.net/ozrentk/umNGj/1/. It behaves well when header labels are wide enough and there are whitespace candidates for page breaks. Otherwise, it gets ugly and I dont like it. I believe we failed while testing.
-
OzrenTkalcecKrznaric over 10 yearsYour solution passed the test, but we didn't count in the case when content is wider than the label and there are no whitespaces for page breaks. Then header gets misaligned, like this. Another problem is when content with ordinary whitespace gets wider than the label, and table is not in constant-width container, like this. Is there a possibility to solve these two problems?
-
Jo E. over 10 yearsSo the correct answer is incorrect? (Sorry if I misunderstood your comment my brain is tired at the moment) . . anyway I'm pretty sure its still incorrect because you said
One problem I found is when I add additional items after it's displayed, header gets misaligned
and the code of the checked answer alone can't do the dynamic requirement. -
OzrenTkalcecKrznaric over 10 yearsYes, the correct answer is as a matter of fact incorrect :( It happened because I was testing YOUR solution properly, and somebody else was tesiting Martyn0627 solution while I was 4 days on vacation. I have to try get things right with Martyn0627 solution now first.
-
Jo E. over 10 years@OzrenTkalcecKrznaric check this fiddle.jshell.net/QUqyu/28/show (its the source of the fiddle iframe). I tried using your headers and data sample. In a big window its fine. But in a smaller window it could create problems. How small is the page window?
-
Muneem Habib almost 9 yearsI am unable to set height of ul. How to set height of ul?
-
Johann over 5 yearsIf you resize the width of the table by resizing your browser, the header columns don't align with the data in the scrollable area. Not good.