User-Agent: Opera/9.00 (Windows NT 5.0; U; en)
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-GB; rv:1.8.1b1) Gecko/20060710 Firefox/2.0b1
When using a linear gradient, pixels outside the range of the defined set of colour stops are filled with the colour of the nearest stop. This seems to disagree with the specification, which says "Immediately before the 0 offset and immediately after the 1 offset, transparent black stops are assumed" and "any points beyond the start or end points are a transparent black".
Steps to Reproduce:
1. Visit the linked URL.
When a linear gradient has two color stops added, red at 0.0 and green at 0.5, and is used to fill a rectangle which extends outside the gradient's specified start and end points, then pixels at offsets below 0.0 are drawn red and those above 0.5 are drawn green.
Offsets below 0.0 and above 1.0 should definitely be drawn as transparent black. I believe offsets between 0.5 and 1.0 should be fading from green into transparent black, given the specified assumption that there are transparent black colour stops at 0.0-epsilon and 1.0+epsilon.
Hrm, that might be challenging to do; apple seems to do black in that case (at least in a WebKit that supports gradients, one of the nightlies). I'm not sure I agree with that part of the spec -- I believe it should behave like it does now, where the first/last color stops extend before/beyond their points. With that behaviour, it's easy to get transparent black outside some range (just by specifying those stops explicitly), but it's impossible to get the other behaviour, other than by filling separate paths beforehand.
Updated the URL to show the output of Safari 2.0, with a fillRect on the left (which that version of Safari doesn't do gradients in - I guess that's what the recent nightlies added?) and a filled path on the right (where it does do gradients). It appears to have solid black stops at 0 and 1 unless you define your own stops on top of them, and it extends the first/last colours out forever. (I also added IE+ExplorerCanvas, which completely ignores the stop positions and end points and just fills with the outermost two colours - it's sufficiently wrong that I'll ignore its existence.)
So, to write code with the maximum cross-browser support now, it's necessary to always define stops at 0 and 1 and to never draw outside that range. As long as you know how far outside that range might ever possibly be drawn, it's not hard to just stretch the gradient's end points outwards and squash the colour stops back inwards, to get exactly the same gradient in the middle while still having well-defined results further out. (I've done that for my specific use of the canvas gradients: it's shading floors/ceilings and there's a limit to how far you can look up or down, so I can move the gradient end points to cover the maximum possible viewing range. It'd be a pain if there was no limit, though.)
Since every current browser works differently, there doesn't seem much benefit in changing the implementation here, particularly given that it's more powerful than the other implementations and the draft spec. On the other hand, it would be nice if code behaved the same between browsers in the future and if that behaviour was documented in the spec. I'm not sure what resolution would be best.
This is not a bug any more - the spec has been changed to match Gecko's behaviour here.