Adding and removing many style elements

S

Scott Sauyet

Does anyone have experience with adding and removing a large number of
style elements? I'm considering that as a solution to a thorny little
problem and was curious to hear of successes or failures along those
lines. Basically I'm thinking about adding and removing a style
element that assigns the height of a single element on resize.
(Perhaps I can just change its text?)

I'd also love to hear of other solutions to my conundrum, so here's
the problem:

For a small intranet app (no more than a few dozen users, targeting
Firefox, but would like to have it work in IE7/8 as well) that I'm
starting to modify, one requirement is that the main tables that are
the only substantial content on several pages need to keep the headers
visible when the user scrolls. I've done this several times with no
issues by wrapping the table in some fixed-height div with overflow
hidden and then making the TBODY have overflow-x hidden, overflow-y
auto, and with a height somewhat smaller than the wrapper div. Since
this is the only substantive content on the page, I also run a script
on re-size to adjust the height of the TBODY and the wrapper DIV.
There are several other tweaks to the CSS for the table, but nothing
particularly difficult.

The problem is that they also print this page frequently. With the
fixed heights assigned to the elements' styles, the printed version is
cut short at that height. It's easy enough in the print stylesheet to
override the relevant heights when they are assigned via a general
stylesheet, but not when the element itself has a height assigned.

So what I'm thinking of doing on re-size is to simply replace or
overwrite a STYLE element that determines the heights of those
elements. I know the techniques to do this, but I'm wondering if this
is asking for trouble. I will do some sort of debouncing to prevent
it from happening on every pixel of reusize, of course, but it's still
going to happen fairly frequently.

Of course I have considered other solutions, and perhaps I will end up
with one of those. I could use two separate tables with the same
column definitions and make the headers position:fixed. Or I could
add a "Print" button that displayed an alternate version of my table.
I've never liked the first one, but it may be my best bet. If I do
it, though, the headers will not appear on every page of the printed
output -- uggh! The second one is probably my last fallback as the
users are used to just printing from the browser's controls and would
not want the change.

So, does anyone have advice about changing stylesheets as frequently
as proposed?

Or do you have other good suggestions about how to get a page where
the table headers don't scroll away but the whole page prints easily?

Thanks,
 
S

Scott Sauyet

For a small intranet app (no more than a few dozen users, targeting
Firefox, but would like to have it work in IE7/8 as well) that I'm
starting to modify, one requirement is that the main tables that are
the only substantial content on several pages need to keep the headers
visible when the user scrolls.

Okay, if I bring that sentence in for a fitting, perhaps it can be
shortened by Wednesday? :)

More simply:

I'm taking over the maintenance and enhancements of a small intranet
application. It has fewer than 50 users, all of whom usually use
Firefox for it. I would prefer that it also works in IE7/8, though.
Several pages have no significant content beyond a single large
table. On those pages, the users would like to have the headers
visible as they scroll the page. But they also want the standard
repeating header behavior when the page is printed.

Okay, it's actually lengthened, but maybe those sentences aren't quite
as dense!

-- Scott
 
S

Sean Kinsey

Okay, if I bring that sentence in for a fitting, perhaps it can be
shortened by Wednesday?  :)

More simply:

I'm taking over the maintenance and enhancements of a small intranet
application.   It has fewer than 50 users, all of whom usually use
Firefox for it.  I would prefer that it also works in IE7/8, though.
Several pages have no significant content beyond a single large
table.  On those pages, the users would like to have the headers
visible as they scroll the page.  But they also want the standard
repeating header behavior when the page is printed.

Okay, it's actually lengthened, but maybe those sentences aren't quite
as dense!

  -- Scott

Short answer, use CSS instead of javascript(or ECMAScript for those of
you who don't know the word) for resizing the table.
 
S

Scott Sauyet

Short answer, use CSS instead of javascript(or ECMAScript for those of
you who don't know the word) for resizing the table.

In a sense, that's what I'm thinking of doing, in a round-about way.
Do you have a simpler method than of replacing a style sheet on re-
size?
 
S

Scott Sauyet

Scott said:
In a sense, that's what I'm thinking of doing, in a round-about way.
Do you have a simpler method than of replacing a style sheet on re-
size?

I can't, for instance, set the size of the table wrapper to a percent
of the page height, as there is some fixed-size chrome at the top of
the page. I wish I could; as that might make all the problems go
away.
 
S

Sean Kinsey

In a sense, that's what I'm thinking of doing, in a round-about way.
Do you have a simpler method than of replacing a style sheet on re-
size?

Set the height using css (hint 100%) and make sure that the parent
containers do the same.
No need to involve js at any step here.
 
R

Richard Cornford

On May 6, 3:41 pm, Scott Sauyet wrote:
The problem is that they also print this page frequently.
With the fixed heights assigned to the elements' styles,
the printed version is cut short at that height. It's
easy enough in the print stylesheet to override the
relevant heights when they are assigned via a general
stylesheet, but not when the element itself has a height
assigned.
<snip>

Although styles applied directly to an element have the highest
specificity, and so override nearly everything else, you could
try using CSS's - !important - rule modifier in the print style
sheet. That has worked for me in similar situations.

Richard.
 
T

Thomas 'PointedEars' Lahn

Scott said:
Does anyone have experience with adding and removing a large number of
style elements?
Mu.

[...]
For a small intranet app (no more than a few dozen users, targeting
Firefox, but would like to have it work in IE7/8 as well) that I'm
starting to modify, one requirement is that the main tables that are
the only substantial content on several pages need to keep the headers
visible when the user scrolls. I've done this several times with no
issues by wrapping the table in some fixed-height div with overflow
hidden and then making the TBODY have overflow-x hidden, overflow-y
auto, and with a height somewhat smaller than the wrapper div.

ISTM you can lose the wrapper-DIV, see <http://PointedEars.de/es-matrix>.
Of course, the headers will not be fixed where a scrollable TBODY is not
supported either way; unless you use two tables, one for the headers and
one for the data, which would not be semantic. As a workaround, you can
repeat the headers when the TBODY is not scrollable; that is what I do.
Since this is the only substantive content on the page, I also run a
script on re-size to adjust the height of the TBODY and the wrapper DIV.

That does not sound like an idea being thought through.
There are several other tweaks to the CSS for the table, but nothing
particularly difficult.

The problem is that they also print this page frequently. With the
fixed heights assigned to the elements' styles, the printed version is
cut short at that height. It's easy enough in the print stylesheet to
override the relevant heights when they are assigned via a general
stylesheet, but not when the element itself has a height assigned.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Do not do that, then.
So what I'm thinking of doing on re-size is to simply replace or
overwrite a STYLE element that determines the heights of those
elements.

You do not need to do this.
I know the techniques to do this, but I'm wondering if this
is asking for trouble.

An interface to do that (implemented as document.styleSheets) already
exists, so ...


PointedEars
 
S

Scott Sauyet

Sean said:
Set the height using css (hint 100%) and make sure that the parent
containers do the same.
No need to involve js at any step here.

I tried that several times with no success. Perhaps I'm simply doing
it wrong. There is some fixed-pixel height chrome above the table
(logos, etc) and that seemed to stop this technique from working.
I'll try again, though, as this seems to be the simplest possibility,
outside Richard's suggestion.

-- Scott
 
S

Scott Sauyet

Richard said:
On May 6, 3:41 pm, Scott Sauyet wrote:


Although styles applied directly to an element have the highest
specificity, and so override nearly everything else, you could
try using CSS's - !important - rule modifier in the print style
sheet. That has worked for me in similar situations.

I'm wondering if I simply didn't do this to everything that needed to
be done. I did try this, as that was the first thing to come to
mind. I'll go back and check it again.

Thanks,
 
T

Thomas 'PointedEars' Lahn

Scott said:
Sean said:
Set the height using css (hint 100%) and make sure that the parent
containers do the same. No need to involve js at any step here.

I tried that several times with no success. Perhaps I'm simply doing
it wrong. [...]

Perhaps. The elements need to be positioned. Plain CSS is on-topic in
ciwa.stylesheets.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Scott said:
I'm wondering if I simply didn't do this to everything that needed to
be done. I did try this, as that was the first thing to come to
mind. I'll go back and check it again.

That approach is wrong, it is not supposed to work (reliably).


PointedEars
 
S

Scott Sauyet

Thomas said:

No, really, even if this technique turns out to be unnecessary to
fixing my problem, I'm curious as to whether others have done this,
and if so what obstacles there are to it.

[...]
For a small intranet app (no more than a few dozen users, targeting
Firefox, but would like to have it work in IE7/8 as well) that I'm
starting to modify, one requirement is that the main tables that are
the only substantial content on several pages need to keep the headers
visible when the user scrolls.  I've done this several times with no
issues by wrapping the table in some fixed-height div with overflow
hidden and then making the TBODY have overflow-x hidden, overflow-y
auto, and with a height somewhat smaller than the wrapper div.

ISTM you can lose the wrapper-DIV, see <http://PointedEars.de/es-matrix>.

Perhaps. But it was already there and being used for other purposes,
so I wasn't worried.

That's one of the places I looked right away. I seem to remember that
you until recently had a button to toggle whether the table scrolled
or the body did. Am I imagining that? I was hoping that this button
simply altered class names to switch which styles applied. If that
worked, I assumed I could simply put one in my print-only stylesheet
and the other one on screen media. But I don't see that button any
more. I didn't chase it down further.
Of course, the headers will not be fixed where a scrollable TBODY is not
supported either way; unless you use two tables, one for the headers and
one for the data, which would not be semantic.  As a workaround, you can
repeat the headers when the TBODY is not scrollable; that is what I do.

I've also played with adding a second table of headers via script that
has "position:fixed", then hiding that one in the print stylesheet and
hiding the normal one in the screen stylesheet. The trouble is the
chrome that sits above the table. I don't have any real need to keep
that there on scroll, but I would have to do so in a straightforward
use of this technique. One possibility I really like is what Google's
Living Stories does with a sidebar, namely to scroll it with the page
until it meets the top of the viewport, then switch it to a fixed
position as the rest of the page scrolls with it. I haven't looked at
their implementation yet, but it might be the perfect UI for my
users. An example of this is at

http://livingstories.googlelabs.com/lsps/DCSchoolReform

(The "Timeline of Important Events" sidebar is what I might want to
emulate.)

That does not sound like an idea being thought through.

Can you explain why? As I said, outside the logo and similar chrome,
this table is the only content on the page. The table starts as a
fixed height table, but it re-sizes to mostly fill the page on start-
up and when the viewport is re-sized.

You do not need to do this.

Perhaps not. I'm trying other techniques, and double-checking the
ones that Sean and Richard suggested. But I really do want this table
to mostly fill the viewport.

An interface to do that (implemented as document.styleSheets) already
exists, so ...

.... I'm not asking for trouble?

I know the document.styleSheets interface (or "interfaces" given how
differently it's implemented in MSIE) and I might use it or might see
if this could be done with simple DOM manipulations. But at this
point, I think this will only happen if other techniques fail.

Still I'm curious as to how viable a technique it might be. If I have
some time when I get this project done, I'd be curious to really dig
into it.

Thanks for the response,
 
S

Scott Sauyet

Scott said:
I'm taking over the maintenance and enhancements of a small intranet
application.   It has fewer than 50 users, all of whom usually use
Firefox for it.  I would prefer that it also works in IE7/8, though.
Several pages have no significant content beyond a single large
table.  On those pages, the users would like to have the headers
visible as they scroll the page.  But they also want the standard
repeating header behavior when the page is printed.

Ok, I managed to get a working solution, only to be told that,
actually, the page they want printed should not have the scrolling
headers! I love shifting requirements. :)

I reverted to my earlier solution for the page with the scrolling
table body as they like that well and left the other one (which they
will want to print) alone.

But if anyone is curious, a technique something like the Google Living
Stories [1] approach I discussed elsewhere in this thread is
relatively simple to do and was working fine in my small test cases.
Here's some pseudo-code:


// CSS
fixed {position: fixed, top: 0}

// JS to run when page is loaded
(function() {
var
table = // getEBI("myTable"),
top = // get top offset of table
thead = // get thead of table
thead.style.left = // get left offset of table;
setInterval(function() {
if (getScrollHeight() >= top) {
addClass(thead, "fixed");
} else {
removeClass(thead, "fixed");
}
}, 50);
}());


Thanks, everyone for your contributions!


[1] http://livingstories.googlelabs.com/lsps/DCSchoolReform
 
S

Sean Kinsey

Scott Sauyet wrote: ....
Here's some pseudo-code:

    // CSS
    fixed {position: fixed, top: 0}

    // JS to run when page is loaded
    (function() {
      var
        table = // getEBI("myTable"),
        top = // get top offset of table
        thead = // get thead of table
        thead.style.left = // get left offset of table;
      setInterval(function() {
        if (getScrollHeight() >= top) {
          addClass(thead, "fixed");
        } else {
          removeClass(thead, "fixed");
        }
      }, 50);
    }());

Thanks, everyone for your contributions!

[1]http://livingstories.googlelabs.com/lsps/DCSchoolReform

Ouch! Using an interval to change the class? Maybe you should try the
resize event instead?
What if the addClass adds without checking if the class is already
added? I'm guessing that might cause some browser to redraw on each
interval..
 
S

Scott Sauyet

Sean said:
Ouch! Using an interval to change the class? Maybe you should try the
resize event instead?

No, I probably induced some confusion here by discussing multiple
different solutions to this problem. This one has nothing to do with
re-sizes. This solution essentially works by changing the CSS on the
THEAD to "position:fixed, top:0" when the top of the table is scrolled
out of view and to default behavior when it's scrolled back in.

I'm doing it in a polling interval because I don't know of an event to
capture for the scroll of the body. There might be one for Firefox,
but I hadn't checked yet since by the time I had this working, I found
out about the requirements change.

What if the addClass adds without checking if the class is already
added? I'm guessing that might cause some browser to redraw on each
interval..

The function addClass() works appropriately. It's not added if it's
already there. But since we're talking about scrolling, there is
already a redraw going on; that doesn't worry me. Do you know if
there is a scroll event I can listen to?

-- Scott
 
D

David Mark

Scott said:
Thomas said:
That approach is wrong, it is not supposed to work (reliably).

Why is that? According to the CSS2 Spec [1], importance and origin
are of higher priority than than specificity. It's not all clear to
me how this is supposed to interact with ECMAScript DOM
implementations.

The !important trick, as described by Richard, works. I've used it for
many years and though I don't know for sure if the original specs are in
agreement, I've never encountered a browser that wasn't. If the specs
say it won't work, they are long since irrelevant in the matter (i.e. an
ad hoc standard trumps them now). Knowing your history is sometimes as
(or more) important than knowing the specs.

In short, if you hide something with inline style that you want to
print, add an !important rule to your (static) print style sheet that
un-hides it. No extra script needed.
 
D

David Mark

David said:
Scott said:
Thomas said:
Scott Sauyet wrote:
Richard Cornford wrote:
Although styles applied directly to an element have the highest
specificity, and so override nearly everything else, you could
try using CSS's - !important - rule modifier in the print style
sheet. That has worked for me in similar situations.
I'm wondering if I simply didn't do this to everything that needed to
be done. I did try this, as that was the first thing to come to
mind. I'll go back and check it again.
That approach is wrong, it is not supposed to work (reliably).
Why is that? According to the CSS2 Spec [1], importance and origin
are of higher priority than than specificity. It's not all clear to
me how this is supposed to interact with ECMAScript DOM
implementations.

The !important trick, as described by Richard, works. I've used it for
many years and though I don't know for sure if the original specs are in
agreement, I've never encountered a browser that wasn't. If the specs
say it won't work, they are long since irrelevant in the matter (i.e. an
ad hoc standard trumps them now). Knowing your history is sometimes as
(or more) important than knowing the specs.

And I should add, it would be really stupid (not to mention inconvenient
as hell) if this did _not_ work (and the browser developers clearly know
this).
 
T

Thomas 'PointedEars' Lahn

Scott said:
No, really, even if this technique turns out to be unnecessary to
fixing my problem, I'm curious as to whether others have done this,
and if so what obstacles there are to it.

"Mu" is the correct answer here. It is unnecessary (and unwise) to "add and
remove a large number of style elements" (client-side, programmatically);
not only with regard to your problem.
[...]
For a small intranet app (no more than a few dozen users, targeting
Firefox, but would like to have it work in IE7/8 as well) that I'm
starting to modify, one requirement is that the main tables that are
the only substantial content on several pages need to keep the headers
visible when the user scrolls. I've done this several times with no
issues by wrapping the table in some fixed-height div with overflow
hidden and then making the TBODY have overflow-x hidden, overflow-y
auto, and with a height somewhat smaller than the wrapper div.
ISTM you can lose the wrapper-DIV, see <http://PointedEars.de/es-matrix>.

Perhaps. But it was already there and being used for other purposes,
so I wasn't worried.

That's one of the places I looked right away. I seem to remember that
you until recently had a button to toggle whether the table scrolled
or the body did.

You remember correctly.
Am I imagining that?

No, given the same user agent it should still be there. However, in
contrast to previous revisions it remains hidden (display: none) when
and while activating it would not have an effect.
I was hoping that this button simply altered class names to switch which
styles applied.

It does add/remove/modify the `class' attribute of the TBODY element with ID
`scroller'. See printScrollButton() in table.js for details.
If that worked, I assumed I could simply put one in my print-only
stylesheet and the other one on screen media. But I don't see that button
any more. I didn't chase it down further.

Either you did not use a user agent that supports sizeable TBODYs (which
includes Firefox/Iceweasel 3.6.3) or something is wrong with my feature-
testing that.
[Google's Living Stories] An example of this is at

http://livingstories.googlelabs.com/lsps/DCSchoolReform

Perhaps I am looking into this later, but I really do not expect too much of
client-side Google applications at this point with regard to code quality
and accessibility.
Can you explain why?

I'll ask two good questions by contrast to yours:

What if the window is too small? What if client-side DOM scripting is
unavailable or insufficiently supported?
As I said, outside the logo and similar chrome, this table is the only
content on the page. The table starts as a fixed height table, but it
re-sizes to mostly fill the page on start-up and when the viewport is
re-sized.

You don't need scripting for that, then.
You do not need to do this.

Perhaps not. I'm trying other techniques, [...]

Like the straightforward one, CSS?
and double-checking the ones that Sean and Richard suggested. But I
really do want this table to mostly fill the viewport.

ISTM CSS can readily provide this.
... I'm not asking for trouble?

I know the document.styleSheets interface (or "interfaces" given how
differently it's implemented in MSIE) and I might use it or might see
if this could be done with simple DOM manipulations. But at this
point, I think this will only happen if other techniques fail.

I have no idea what you are talking about here. You want to modify a
property in a stylesheet. Use document.styleSheets to do that, then,
that is what it is there for.
Still I'm curious as to how viable a technique it might be. If I have
some time when I get this project done, I'd be curious to really dig
into it.

No, you wouldn't.


PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top