Tables with fixed header, the current state of the art - javascript

It's a recurring question since, like, forever: how to keep the headers fixed on top when scrolling down a table?
Yes, I know that the web isn't designed to show long spreadsheet-like tables, but when a client asks for something like that (because s/he used to those old Excel documents...), you have no choice but comply.
This is to sum up the major problems and attempted solutions with fixing the headers of a table:
a <thead> element can be relatively postioned, but it won't move from its position;
with position: absolute or fixed, the head is "detached" from the rest of the table, and the column widths doesn't match anymore; moreover, you have to reserve some space above the table body;
this can be solved using a different table for just the headers, leaving the body in the other, but won't fix the problem of the different widths of the columns;
you can set the columns with fixed widths, but it's not always applicable depending on your needs - i.e. in case of dynamic or unknown content;
Javascript can adjust the widths of the columns, but accessing to properties like offsetWidth causes a reflow, which is a quite heavy task even for a browser like Chrome or Firefox, and adds an annoying rendering lag with even not-so-large tables but with dynamic content;
you can create a copy of the table, using the first to show the headers and the other to show the body, but this makes the DOM twice as heavy and should rely on Javascript to copy the changes of the content;
using <div>s with display: table-whatever won't actually solve a thing, and deprives you of the chance to add rowspans and colspans.
With the latest technologies of the web, maybe we can try something new. I've experimented a solution using transform: translate which behaves acceptably good (see the fiddle here), and keeps the space above the table body, and the columns width still match.
This of course won't work in IE8 and lower. But it works fine in Chrome, Safari and Firefox. It doesn't work in Opera 12.x and below, but it does work in Opera 15 thanks of its brand new Blink render engine. I've noticed this works better or at least as well with translate than with translate3d: it shows a bit less flickering.
Unfortunately, this doesn't work in IE9 and IE10, and the headers are kept in their positions. It's really a shame since there's no way to detect this behaviour (that I know of).
So, what are your most recent solutions for this problem? I'm looking for CSS and pure Javascript solutions.

I recently had to do this exact thing for a client and found it be next to impossible. I did find a really good library called SlickGrid, however when it came to translating that to mobile, it just wouldn't work (performance was too big of an issue). If mobile is not a concern of yours then I definitely suggest checking it out. https://github.com/mleibman/SlickGrid

Related

Generated HTML tables that I've successfully changed several indirectly... except this particular one

My site has these interactive tables that are inert until activated by an instructor when they are testing students. The backend is controlled by a vendor and I am the lowly web developer who cleans up their mess on the frontend so things look presentable. I've managed to change several tables indirectly through CSS and JS, but I can't apply anything to the HTML directly to the table since it's generated when the page loads. This particular table is perplexing,it will not shrink down to 720px. I tried everything from adddClass, nth-child, fixed sizes, etc. My last attempt was to write a function that set attributes to td's. It worked and it'll show on the developer tools but the actual table didn't shrink at all. I've been up 24+ hours so I might just be tired and not aware of simple mistakes. Anyways here's my demo. Thank you very much any help is very appreciated.
I just found this: Why is my table cell width wrong in Chrome?
Tables have a property called table-layout which is by default set to auto. It allows the table to be flexible and gives it the ability to distribute column widths on the fly. Setting my rogue table this way:
table-layout: fixed; width: 100%
made it behave and honor the widths I had assigned to it. Here's more details on table-layout
Demo
EDIT: I forgot to mention that this only happens in Chrome, but in Firefox and to a certain extent IE (it's a little off, but that's what you'd expect from a half-baked piece of work), are ok.

Jquery columnizer plugin: 40 times faster in Windows Firefox. Why?

I have a number of large texts which I'm using a lightly-stripped-down version of the columnizer jquery plugin (https://github.com/adamwulf/Columnizer-jQuery-Plugin) to turn into "columns" for use in another plugin. Columnizer is an OK performer for my purposes--as long as there is no floated content within the chunk being columnized.
Chrome, FF and IE10 all have similar performance on pure text or text with images and other simple html mixed in, for the most part. However, if you include floated content (images, in this case), things change dramatically:
Big Book w/ Images, roughly 700 columns created
Test condition Firefox (sec) Chrome (sec)
-----------------------------------------------------------------
Normal book build (images, floats) 31.5 1254.2
As above, but no images 23.2 18.9
w/ images, but no floated images 25.1 24.7
Only a few floated images 27.6 1010.9
Remove all images, tags except 'p' 21.3 18.9
As you can see, that is a huge, huge difference. (I do cache the builds, but because each browser/OS combo renders things slightly differently, I still have to build each one first in the "major" browsers. You haven't lived until you wait for Safari on an iPad to build this thing -- multiply the windows chrome numbers by 4.)
So my question: What is firefox doing "right" without being asked, and what can I do to re-work the columnizer code to mimic it in the other browsers? Columnizer is fairly "dirty" in that it does thousands (I think over 100,000 in this book's case) of appends, which I know is definitely Not Cool. Is it using document fragments? Some other trick?
Columnizer requires that the destination container (where it does its content flow) to be in the dom so that styles can be applied correctly (ie, no "display:none" and then toggling when done). In my CSS, I set this to position:absolute, visibility:hidden, as recommended. I'm thinking FF must view this set of attributes in a way the other browsers don't. Or...?
I should note at the end of the process, except for the slight font rendering differences, the output is identical among the browsers.
I'm not absolutely certain this answers my own question, but I did make things a lot better, which in some ways is answer enough for me. I'd love to actually learn why my solution made any difference.
Background: I do as much "pre-formatting" of the book's text in PHP as I can, as it is much much faster to do clean-up and other mundane text chores server-side. This cleaned-up chunk of html is then thrown into a div, which is what I columnize. This container (let's call it "raw"), and the empty destination container for the columns ("dest"), need to be in the dom, so I have this CSS on a wrapper div which has "raw" and "dest" as children:
position: absolute;
top: -2000px;
left: -2000px;
width: 700px;
height: 500px;
visibility: hidden;
overflow: hidden;
This 'removed' the two divs from the page (as far as our eyeballs are concerned), but they're still in the dom, allowing Columnizer to work with them.
Hmmm: In Firefox, this was enough to make things work well, floats or no. But in Chrome, Safari and IE...well, look at the table in my original question. Yuck.
But by adding "position: absolute" to "raw", the other browsers' performance was increased dramatically. They're not as fast as FF, but not far behind. Instead of 1200+ seconds, Chrome now takes 40 seconds when presented with the full book. The ipad, instead of taking a glacial epoch, takes a couple of minutes.
Why? It's a mystery to me. Here's what seem to be the pertinent bits within columnizer, during its prep:
...
var $sourceHtml = $('div.raw'),
$cache = $('<div></div>'),
$inBox = $('#dest'),
$destroyable, $col;
...
$cache.append($sourceHtml.contents().clone(true));
$inBox.empty();
$inBox.append($("<div style='width:" + options.width + "px;'></div>"));
$col = $inBox.children(":last");
$inBox.empty();
try {
$destroyable = $cache.clone(true);
} catch(e) {
$destroyable = $cache.clone();
}
...
That empty div created as the cache should be in the DOM but outside of the HTML page at this point, since it has not been appended to anything yet. Eh? So as it is manipulated, the page shouldn't need to be repainted.
My half-arsed theory is that while FF recognizes that, the other browsers don't, and consider $destroyable to be within the painted area of the page--perhaps appending it to the body tag or even to "wrap" (though watching through Chrome's inspector showed no such thing)?
As nodes are stripped from $destroyable and appended to the columns being created, the other browsers repaint the page every time $destroyable is altered. Speedy with block and inline stuff, expensive when floats are added.
But to poke a hole in that half-baked idea: Trying to add "position: absolute" to $destroyable makes no difference. It's only when the original "raw" div has that attribute that things speed up.
Anyway, back to heavy drinking and ignorance. Please sigh patiently and make this a teachable moment, if you can!

Specific height for div in Mobile Windows 6.1

I always come to stackoverflow to check for answers; however, for the current question I have not found any relevant information yet.
I have a Mobile Windows 6.1 PDA and I want to create a simple HTML page for it. I want specific divs of the page to have a specific height, based on the text that are inside these divs.
Maximum I want 2 rows of text.
The text can contain HTML code. I want to slice the text but do not hurt the HTML code.
Before you think "there are 100 different solutions with CSS or Javascript for this" I would like to mention that 6.1 uses a mixture of IE4 with some features of IE5. The browser supports only CCS1 (so no max-height, no overflow:hidden, no position: absolute, no top, bottom etc).
Also the browser supports a very limited range of Javascript functions. I thought to parse the DOM of Javascript and constantly check if the text inside the div is bigger than 28pt (this is two rows) and cut it. However, most of the DOM functions do not work. createElement() does not work, appendChild either. Only getElementById and innerHTML work.
I found this solution https://code.google.com/p/cut-html-string/ for Javascript, which works perfectly with modern browsers, however, since it contains functions such createElement(), appendChild(), cloneNode() etc. it does not work with IE4. Work-around to the createElement() is the innerHTMl which works perfectly but then the browser reports errors for the DOM functions that the code uses.
P.S: Please do not answer "change PDA etc.". I know that the OS is very old but I have to use it.
Ok so if your only dealing with 1 style of device could you use a javascript viewport sniff maybe and use the inner html adjustments to adjust to a new style sheet so that you can have it work for said device, if you have to program for multiple devices you can create multiple style sheets. I would advise for testing purposes to see if anyone has an android or iOs device with similar screen sizes so you can use something like edge inspect from adobe creative cloud that you can adjust and see the changes.
Someone has a thing on viewport find here
Find the exact height and width of the viewport in a cross-browser way (no Prototype/jQuery)
that may be of use.
Since your dealing with basic javascript you should just be able to change the address of a css link and that may be a solution. If i mistook any of the functionality of the device im sorry however it has been a while since I had a windows mobile 6.x phone.

Text content overflow to new dynamic column on lower window heights

How do I go about getting text content to carryover to a dynamically created column to it's right when the window height is reduced?
Basically this:
Is there any jquery/other plugins out there that can do this?
I hit the wall while working on a horizontally scrolling website, and this has been haunting me and driving me crazy for the past month. I guess, the madness had clogged my mind to allow proper research.
There's treesaver.js http://demo.nomadeditions.com/wide-screen/#-/wide-screen/oscar-bloggers.html; it works fine in IE9, but wouldn't even load in IE8 (I checked on IEtester so chances are it could be incorrect). The only problem I have with treesaver is it's constant re-loading whenever the window's resized but that's just a pet peeve.
It would be nice if this can be done in css itself; this trivial issue really shouldn't need a javascript plugin, but the wide array of browsers(along with their own quirkiness') used in the market forces me to dip my hand in the js basket first.
What you are asking for is currently a W3C candidate reccomendation
http://www.w3.org/TR/css3-multicol/
You can see it in action here:
http://www.quirksmode.org/css/multicolumn.html
The bad news is it's not supported by IE 8 even in standards mode. I don't have IE 9 available here, but if this is a public site, you probably can't require IE 9 yet anyway.
Take a look at the text effects in http://www.jwf.us/projects/jQSlickWrap/

What Cross-Browser issues have you faced? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
While developing for multiple sets of browsers, what issues have you faced while development due to differences in browser implementation?
To start with I am listing some of those which i faced:
A text node in Firefox allows only 4K data. So an XML Ajax response gets split up into multiple text child nodes instead of only one node. Its fine in Internet Explorer. For Firefox, to get the full data you either need to use node.normalize before you call node.firstChild or use node.textContent, both of which are Mozilla specific methods
Internet Explorer does not replace or HTML char code 160, you need to replace its Unicode equivalent \u00a0
In Firefox a dynamically created input field inside a form (created using document.createElement) does not pass its value on form submit.
document.getElementById in Internet Explorer will return an element even if the element name matches. Mozilla only returns element if id matches.
In Internet Explorer if a select box has a value not represented by any of the options, it will display blank, Firefox displays the first option.
The only one that really gets to me:
IE6 is still used by ~18% of the web -- that's nearly 1 in 5 -- and addressing its issues is time consuming, hackish, and frustrating. ;) The issues are really too numerous to list here.
If you're interested in the issues themselves, QuirksMode.org is an amazing resource I used every day before making the leap to client-side libraries. Also check out John Resig's The DOM is a Mess presentation at yahoo, which gives a lot of theory about how to deal with cross-browser topics efficiently.
However, if you're interested in simply having them solved, your question is an excellent example of why many consider using client-side libraries like jQuery, YahooUI, MooTools, Dojo, etc. With a thriving community, talented people and corporate backing projects like those allow you to focus on your app rather than these issues.
Here are some jQuery examples that avoid much of the cross-browser frustration and can really make all of this.. fun.
Cross-browser mouse click binding
$('#select anything + you[want=using] ~ css:selectors').click(
function(){
alert('hi');
}
);
Cross-browser HTML Injection
$('#anElementWithThisId').html('<span>anything you want</span>');
Cross-browser Ajax (all request objects are still made available to you)
$('p.message').load('/folder/file.html');
And what really blows me away, load a data subset with selectors (see manual for details)
$('p.message').load('/folder/file.html body p:first-child');
Now, how all this really starts to get fun: chaining methods together
$('ul.menu a').click( // bind click event to all matched objects
function(evt){ // stnd event object is the first parameter
evt.preventDefault(); // method is cross-browser thx to jquery
$(this) // this = the clicked 'a' tag, like raw js
.addClass('selected') // add a 'selected' css class to it
.closest('ul.menu') // climb the dom tree back up to the ul
.find('a.selected') // find any existing selected dom children
.not(this) // filter out this element from matches
.removeClass('selected'); // remove 'selected' css class
}
)
Reminds me of Joel's Can Your Programming Language Do This? article.
Taking all this to a theoretical level, true advancement doesn't come from what you can do with conscious thought and effort, but rather what you can do automatically (without thought or effort). Joel has a segment on this in Smart And Gets Things Done regarding interviewing questions and smart developers, completely changed my approach to programming.
Similar to a pianist who can just 'play' the music because she knows all the keys, your advancement comes not from doing more things that require thought but rather more things that require no thought. The goal then becomes making all the basics easy.. natural.. subconscious.. so we can all geek out on our higher level goals.
Client side libraries, in a way, help us do just that. ;)
Most of the problems I have are with IE, specifically IE6. Problems I personally deal with that have left a memorable impression (in no particular order):
Having to use frameworks to do basic things because each browser implements the DOM a little differently. This is especially heinous with IE and AJAX, which necessitates multiple if-blocks just to get the call started. In an ideal world I'd be able to work in JavaScript without the framework to do basic things.
onChange on selects in IE are implemented wrong, and fire before the select loses focus (which is incorrect). This means you can never use onChange with selects due to IE, since keyboard-only users will be crippled by this implementation issue.
You mentioned it in your post, but it's a huge pain when IE grabs an element by name when using getElementById().
When in an RTL locale (Arabic, Hebrew, etc.), Firefox implements "text-align: right;" incorrectly. If the container overflows for some reason, the text aligns to the right side of the viewable container, rather than the right side of the container itself (even if it makes part of it invisible).
Different browsers have differing levels of pickiness with regards to how you end arrays and objects. For example, Firefox is more than okay with an array looking like this: [ item0, item1, ]". However, this same code will make Opera barf because it hates the trailing comma. IE will make the array a three-item array, with the third item undefined! This is bad code for sure, but there's been dynamically generated javascript I've worked on that was a huge pain to rewrite - would've been nice if this just worked.
Everything having to do with IE's hasLayout. So much awful pain has revolved around this attribute, especially when I didn't know it existed. So many problems fixed by using hacks to add hasLayout. So many more problems created as a result of the hacks.
Floats in IE rarely work the way you hope they do. They also tend to be annoying in other browsers, but they at least conform to a particular behavior. ;)
IE adding extra white space between list items has caused me no end of pain, since YUI uses lists to make their menus. (To fully grasp the issue, you have to view that link in IE and another browser side by side.)
I have lots of issues getting text not to wrap in containers in IE. Other browsers listen to "white-space: nowrap" a lot better. This has been a problem with a UI I worked on that has a resizable sidebar; in IE, the sidebar items will start to wrap if you resize it too much.
The lack of many CSS selector types in IE6 means you have to class-up your DOM more than necessary. For example, the lack of +, :hover, :first-child.
Different browsers treat empty text nodes differently. Specifically, when traversing the DOM with Opera, I have to worry about empty text nodes when browsing a node's children. This isn't a problem if you're looking for a particular item, but it is if you're writing code that expects a particular input and the way the browser views that input differs.
In IE6, when you dynamically generate an iframe via javascript, the iframe sometimes doesn't fill its container automatically (even with width and height set to max). I still don't know how to solve this issue, and have been thinking of posting a question about it.
In IE, you can't set overflow CSS on the <tbody> element. This means that scrollable tables (with a concrete <thead> and <tfoot>) are impossible to make in a simple manner.
I will probably add more to this list later, since (to me) the worst part of web development are cross-browser issues. Also, I doubt I'll ever edit out the "I will probably add more to this list later", since these problems are endless. :)
IE6? Meh. You guys have got it easy! You've never had to make CSS layout work in Netscape 4 (without crashing the entire browser)? You've never had to write for appliance browsers that don't support tables? You've never had to write for IE Mobile?
there is no support for JavaScript-assigned event handlers; you can only write an event handler through setting “onclick="somestring"” in innerHTML;
most basic DOM Level 1 properties (eg. nodeName, nodeType, nodeValue, firstChild, lastChild, nextSibling, previousSibling, data, value, HTMLElement.getElementsByTagName, all HTMLTableElement members, most CSSStyleDeclaration members) simply do not exist;
most CSS layout properties do not work; many simply CSS properties like ‘width’ don't work on some elements such as form fields;
setting many other CSS properties on elements like tables and form fields causes an instant browser hang, which, since Windows Mobile has no built-in task manager, means you have to soft-reset the device;
oh, and putting anything but text inside a <button> is insta-crash too;
huge chunks of basic JavaScript methods and “DOM Level 0” methods going back as far as Netscape 2 (!) are missing.
And this is the most up-to-date release of Microsoft's flagship Windows Mobile browser in 2009.
Sure, it supports XMLHttpRequest, but writing AJAX code on a browser whose CSS and script support is less than IE3 (!) is bizarrely schizophrenic, like you're working with a weird amalgam of 21st-century and 19th-century technologies.
I wouldn't recommend it.
Been doing this too long to have many problems, but it still drives me nuts that I have to hack around IE's non-support for CSS things like display:table, :last-child, and :hover outside of anchors.
All the IE stuff is still insane, but it's just background insanity now :)
Biggest Cross-Browser Issue? - Internet Explorer!
<start_grumpy>
IE is solely responsible for "holding back the web" - us developers can't create amazing sites using HTML5, or SVG, or XFORMS, or CANVAS... not because of Firefox,Safari or Chrome, but because 2/3s of the Internet is still stuck on IE. Not to mention that ~20% of the web is still stuck on IE6! IE8 is the first version of IE to at least try to be standards compatible (2001's standards that is), which means it will be at least 2018 before we can finally start dropping all support for IE7.
</start_grumpy>
Otherwise name a DOM method that IE fully supports... the fact that this is a hard question to answer is my biggest CrossBrowser issue.
getElementById() - badly broken
getElementsByName() - buggy
getElementsByTagName() - buggy
getAttribute() - buggy
setAttribute() - majorly broken
createElement() - buggy
appendChild() - buggy
even things IE invented are messed up...
innerHTML (getting) - returns the worst markup possible
innerHTML (setting) - doesn't work on the elements you'd want to dump a bunch of data into (e.g. Tables and Selects)
While developing a system tests framework for a web app we had to simulate various events such as clicks. I remember that we couldn't find any normal way to do it in IE and FF and had to implement it in two different ways with a lot of voodoo around.
I don't remember the specifics, but I remember that it was really annoying.
This, basically.
Modern javascript frameworks (jQuery, prototype, etc) have done wonders for getting code working in lots of browsers at once.
The biggest problem I have now is the fact that any sort of rich UI behaviour runs amazingly slowly. IE7 is bad. IE6 is worse. IE8 is buggy, half finished, and really no better than IE7.
The worst thing is that I don't think we'll ever be free of IE6. It was so ubiquitous, and so damn quirky. Loads of 'enterprise' (and by that I mean big web apps made by one big company for another big company) applications used highly specific IE6 javascript that doesn't even work in IE7, never mind anything else.
Companies can't afford to completely replace these apps - we're trying to sell them new ones and that means IE6 support is mandatory. The way it is right now, with credit-crunched companies cutting costs, I reckon we'll still be supporting IE6 in 2015 :-(
In internet explorer (note: older versions of IE, not necessarily versions 9/10+), if you create form elements using document.createElement, the field won't be submitted with the form. The only workaround is to use
element.innerHTML = "<input type='text' value="+val+" name="+name+">";
In IE, you can not hide select option elements, only the select element itself. This makes it difficult to dynamically change the contents of select options using Javascript.
This problem also exists in Safari and Chrome.
There are many other issues with IE, but this one has caused me the most frustration recently.
IE's restrictions on using DOM manipulations on tables forced me to take a completely different approach to something. Very frustrating at the start, but the positive out of it was that the second approach was ultimately better, so I suppose I should be grateful to IE. ;)
For Firefox, to get the full data you either need to use node.normalize before you call node.firstChild or use node.textContent, both of which are Mozilla specific methods
Actually all of those are W3C DOM methods supported by the vast majority of browsers. I think you'll find they also work in IE.
My biggest cross-browser issue is that there are people out there still using IE.
Second biggest is that even in standards-following browsers, doing some things in CSS is still impossible; for instance tbody {overflow:auto} does nothing useful in anything but Gecko, and even there it has bugs.
Firefox and IE ahve different table setups in the DOM, in one, all siblings of a cell are the other cells, whilst the other has elements between the cells. I can't remember which way around it is, but it gave me a real headache in one application.
My biggest problem are browser makers. Arrogant little *^&%s. I mean, you can't sell a browser to anybody, yet everyone is in their little corner trying to out do each other, only creating division. Oh and Chrome. Chrome still doesn't know what it wants to be, Safari or Firefox. Aside from its one parlor trick, its practically useless. I blame all you guys who kept googling just because you hate monopolies. Guess what, they're the monopoly now. Now we can all enjoy second rate, prematurely launched software.
This mostly stems from a bug* I had in Chrome today, it never dawned on me to query the browser. Both Safari and Chrome were failing so I figured hey, once I fixed the Safari problem Chrome would be fixed automatically, but oh no no. Mr."I run tabs in seperate processes" AKA "Sr. No full screen" just had to hold me in the lizard lock with its mind boggling implementation.
I also detest Firefox. I can't tell whether I have a virus infestation or Firebug running. Now until Adobe decides to release a browser that makes Flash practical for things other than movie clips I'm pretty much going to have something to bitch about for a long time. And we all know that's what life is all about.
Also, I only enjoy programming when I encounter ridiculous bugs that make my brain juices run.
Inconsistencies in the CSS box model when dealing with forms. In particular it's irritating how each browser handles the <select> Box
my only nightmare is IE6 you should always look for hacks but everytime you face a problem with it there is someone who ran into it before you and blogged about it (and we will never get away from it )
I was working on CSS layout written by someone who thought that the size given to an element is size+padding+border like in IE5 and not only the content box as explained in official specification. It was written only a few month ago so he did dirty hacks to make it look well in IE7. It took me several hours with FireBug to track down the source of the problem and by the time I realized it I was really annoyed.
If you open site with "floating" CSS written for IE5 in Firefox the boxes just do not have enough space to fit and fall down the page. If you open it in IE7 it looks nice as IE7 lets the borders overlap so it looks almost correct. For someone as inexperienced as me it was hard to note.
To remove iframe borders in Internet Explorer you have to specify the frameborder attribute as camelCase format, which is non xhtml compliant.
<iframe frameBorder="0"/>
An easy way to help with the pesky IE display issues is to use firebug, Yep enen in IE 6/7/8 Just use Firebug Lite
If you add the following as a bookmark and stick it on your tool bar it will enable firebug lite off any webpage with a single click. (only check this in IE and it works fine.)
javascript:var%20firebug=document.createElement('script');firebug.setAttribute('src','http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js');document.body.appendChild(firebug);(function(){if(window.firebug.version){firebug.init();}else{setTimeout(arguments.callee);}})();void(firebug);

Categories

Resources