Pure CSS scrolling UL LI table with fixed header

I am trying to implement a clean UL-LI CSS scrolling table with a fixed header.

My requirements:

  • using a CSS table (table, table-row, table-cell, table-header-group ...)
  • all cells must be list items (LI)
  • should be fixed when scrolling the contents of the table.
  • when the column of the table changes width, you should change the corresponding width of the header.

I currently 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 here: http://jsfiddle.net/ozrentk/QUqyu/1/

BUT! The moment I try to fix the position of the header using position: absolute or fixed , the table is falling apart. I tried several methods, but to no avail. In addition, there is not a single example of how to do this using pure CSS tables.

It was close , but not quite what I needed.

Is there a CSS guru that can help me?

EDIT

Now, why the hell do I want to display this list in a table?

On my dynamic ASP.NET MVC site, I have several places where I return unordered lists to the browser. Then the browser will do this markup and display it for reading. But the display format itself may actually depend on the context, for example, on the display preferences associated with the display, or on the device format. CSS is used to format the display, as it should be. Finally, if there is some kind of display-light-n-magic effect, you need to use jQuery and / or a plugin for this, and hopefully only for that.

You see, I want my server to remain agnostic in display format. That is, I do not want my server to care about how a particular client wants its display to look. I don't need if-blocks that return unordered list items in one case and table-cells in another. Of course, I could have two return points, one of which returns the format ul / li / span, and the other that returns the table / tr / td, but this would violate the DRY principle.

Another thing is that I use a really good jQuery plugin that displays tabular data and can be loaded with list items, but not table layout. And I decided to stick with the plugin. because I like it, it's great and supports the way my site works.

Hope this all works out. You see, using one paradigm can be the opposite of another. Turns out I have to give general-table-data-semantics in order to have DRY code.

PS The more I think about this situation, the more it looks like a pragmatic, not semantic, problem.

+7
css css3 css-transitions
source share
3 answers

You can try the following: DEMO

I got this correctly in pure css:

  • using a CSS table (table, table-row, table-cell, table-header-group ...)
  • all cells must be list items (LI)
  • should be fixed when scrolling the contents of the table.

The last requirement that I had to use in jQuery.

Anyway, I made two <li class="testRow"> for <div class="testHeader"> . One of them has id with css position:fixed

This trick fulfills your first 3 requirements. The latter is very difficult for css, so I added: 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 this helps!

EDIT

Execute the adjustHeader() function every time you add new data so that the headers are rebuilt.

Here is a demo

+6
source share

Once you specify either position: absolute or position: fixed on .testHeader , it sets display: block , which overrides display: table-header-group .

See this topic for more details .

+5
source share

I believe that I solved this problem by creating a second header section. To get started, I duplicated the html "testHeader":

  <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 absolute.

 .secondHeader { display: table-header-group; position: fixed; top: 0px; } 

Then set the original title (which gives its structure) hidden visibility.

 .testHeader { display: table-header-group; visibility: hidden; } 

You should now have a list displayed as a table, with a fixed title element that remains in position when you resize. I updated your violin as a demo.

+1
source share

All Articles