Blog

The joys of overflow:auto and cross-browser development

Some of you may have wondered why I initially didn't post the code for my Map/Reduce example on my blog, but only linked to the Channel9 post, and why I added it now. The answer is, because figuring out a good way to add code samples to my blog was still on the TODO list.

"But," I hear you say, "that's simple isn't it? A <pre>, maybe some fancy colouring, end of story, right?"

Right. Except, no. You may have noticed that the content on this is in a container that has a width relative to the page (70%, to be precise). So what would happen if I put a <pre> in there, and that contains a line that wouldn't fit. In Internet Explorer 7, Firefox, Opera and other browsers with a proper overflow model, the line would run out of the box. In IE6, it grows the box to fit the line, destroying the entire page layout. Neither is very desirable.

So there are two solutions. One is to have the lines wrap. The simple way to do that would be to use white-space: pre-wrap;, but alas, no browser that I know of actually supports that. The other way would be to manually format it, inserting &nbsp; and <br /> elements where needed. I don't much like doing that, and I don't actually like having lines of code wrap at arbitrary points either, so this solution is out the window.

Thus we end up with the solution I eventually used as you can see in the previous post. I used scrollbars.

The mechanism to create scrollbars, namely overflow:auto has its own problems. You see, CSS 2 does not tell browsers where these scrollbars should go, and as a result everybody does it differently. CSS 2.1 rectified this oversight by saying the scrollbars belong on the inside of the box with the overflow style, i.e. the box does not grow to accomodate the scrollbars.

Perhaps surprisingly, the only browser that does this is IE. All the others place the scrollbar outside the box. This means that in IE if overflow:auto mandates a horizontal scrollbar, this scrollbar now obscures part of the content, so a vertical scrollbar is also needed. So setting overflow:auto will cause the code sample to always have two scrollbars in IE, and only one in Firefox et al. Not strictly a problem, especially since I wanted to add a max-height so a vertical scrollbar is needed anyway.

There is, for those interested, a way to avoid the vertical scrollbar even in IE. First, IE will behave differently if the element being scrolled is a table. Second, you can force the scrollbar to the outside using the CSS 3 properties overflow-x:scroll;overflow-y:visible. Unfortunately, that is not a legal combination according to CSS 3, but it works in IE. Firefox, Opera etc. do not support overflow-x/y at all. The drawback is that it only works with overflow-x:scroll, not overflow-x:auto so now the element gets a scrollbar even if it doesn't need one!

IE6 adds additional difficulty. Because of the broken overflow model (thankfully fixed in IE7), it never thinks the <pre> needs a scrollbar unless you give it a specific width. Unfortunately, that prevents IE7, Firefox, et al from automatically adjusting the width if the element is next to the sidebar or not. Even worse, in Firefox, an explicit width that's wider than the space next to the sidebar causes the element to overlap the sidebar (why Firefox doesn't move it below the float like IE does in this case I don't know). So that's out.

So in the end, we have overflow:auto, with the knowledge of the vertical scrollbar that will cause in IE (which is right according to spec), and some extra rules for IE6 (using the "* html" hack so other browsers (including IE7) ignore them). And then I could add the code.

Ah, the joys of cross-browser development...

Categories: Programming
Posted on: 2006-08-04 14:26 UTC. Show comments (7)

Can your programming language do this? C# can!

Joel on Software talks about the Swedish Chef and the advantages of anonymous functions and functional style programming with an example of map and reduce in Javascript.

He notes how terrible this is to implement in C with function pointers, or even worse in Java with functors. Thankfully, C# 2.0, with anonymous delegates and generics, offers a clean, type-safe way to do this, which doesn't require much more code than his javascript version. The only real additions are the declarations of the delegates used, and of course some necessary type specifications, because C# is still a strongly typed language.

So what does this code look like? The answer can be found below, with some more discussion on this Channel9 post made by me.

public delegate T MapDelegate<T>(T input);
public delegate TAggregate ReduceDelegate<TAggregate, TInput>(TAggregate aggregate, TInput input);

public static void Map<T>(IList<T> list, MapDelegate<T> function)
{
    for( int x = 0; x < list.Count; ++x )
        list[x] = function(list[x]);
}

public static TAggregate Reduce<TAggregate, TInput>(IEnumerable<TInput> list, TAggregate initial, ReduceDelegate<TAggregate, TInput> function)
{
    TAggregate aggregate = initial;
    foreach( TInput item in list )
        aggregate = function(aggregate, item);

    return aggregate;
}

public static void Foo()
{
    List<int> list = new List<int>(new int[] { 1, 2, 3 });

    // Multiply each element by 2.
    Map(list, delegate(int x) { return x * 2; });
    // Sum values: result with be 12
    int sum = Reduce(list, 0, delegate(int aggregate, int input) { return aggregate + input; });
    // Concatenate values using a StringBuilder, result will be "246"
    string concat = Reduce(list, new StringBuilder(), delegate(StringBuilder aggregate, int input) { return aggregate.Append(input.ToString()); }).ToString();
}

EDIT 2006-08-04: Added code.

Categories: Programming
Posted on: 2006-08-02 21:00 UTC. Show comments (4)

Dreamfall nominated for MTV Video Music Award

Normally anything involving MTV is about as interesting to me as watching paint dry, but on occasion they do show some glimmer of hope that they might know what good music is.

This time, they have nominated the soundtrack of Dreamfall, the best adventure game in recent years, for an award, as game designer and writer Ragnar Tornquist writes. A worthy choice, as the soundtrack of Dreamfall is indeed very good. See, they can get it right, on occasion.

So please, go and vote for Dreamfall now! Vote, or the owl will eat you!

Categories: Personal
Posted on: 2006-08-01 13:27 UTC. Show comments (1)

Burning up!

Who turned on the heat? Really, it's like 30C outside, unbearably hot for someone like me (I've always been better at coping with cold rather than hot weather). How am I supposed to get any work done in temperatures like this? Fortunately it'll get a little cooler soon.

In case you hadn't noticed yet, I've done a pretty big update on the El Goonish Shive section of the site. I've updated the look, got a new version of the Uryuomoco Translator out, and put some new stuff on the character statistics page. For full details, I refer to this post on the Keenspot forums. Or you could just check it out for yourself.

Categories: Site news
Posted on: 2006-06-12 21:13 UTC. Show comments (0)

The beginning of the end

For the past semester I, six students and three teachers from Leiden University and the Delft University of Technology have been conducting an unusual type of seminar. Instead of the usual University seminars where everybody holds a presentation about some existing topic and also does a project, we've been doing some real research. Our goal was to look at some of the optimization challenges faced by restructuring compilers in the presence of certain kinds of datastructures (most notably, pointer structures, which a restructuring compiler really can't do anything with), and also for certain notoriously hard to optimize algorithms (the focal point has been Tarjan's algorithm for finding strongly connected components in a graph, which is nearly impossible to parallelize).

Last Tuesday, we had the last of our meetings, the formal end of the seminar. While we didn't solve the problem, we did get some nice results. And more importantly for me, this seminar has been the foundation for what will become my thesis, and I finally have a real clear picture of what I'll be doing. Specifically, I will be continuing on the pointer structure work, and currently I'm focussing on transforming a linked-list representation of a matrix algorithm into something a restructuring compiler could work with.

What that means is that if all goes well, it'll be only a few more months and then, finally, I'll get my Masters. Here's to hoping!

I've been getting a lot of work done this week, I finally feel like I'm getting out of my usual Spring slump. It feels good!

Categories: University
Posted on: 2006-06-01 21:31 UTC. Show comments (0)

Latest posts

Categories

Archive

Syndication

RSS Subscribe

;