Custom Cursors in CSS

I spend most of my time on networking, performance, and browser security issues, but while working on a test page recently, I came across some interesting behavior and cross-browser differences when using custom cursors in HTML content.

Web developers can choose which cursor is shown when hovering over HTML elements using the cursor property. There are a number of built-in cursors, or they can specify the URL of a Cursor (.cur) or Animated Cursor (.ani) file that should be downloaded and used.

When I specified that IE should use a cursor file containing a 16x16 image, however, I found that IE stretched it to 32x32. Similarly, I found that when I used a 64x64 image, IE scaled it down to 32x32. You’ll see the same scaling behavior for icons of size 20x20, 20x40, 128x128 and 256x256.

It turns out that IE passes the LR_DEFAULTSIZE flag when calling LoadImage on the cursor file, and that means that the image’s intrinsic size is ignored in favor of the default “system metrics” cursor size, which is 32x32 by default. Hence, IE will shrink or stretch cursors to match the size specified by the system metric.

Various browsers have different behaviors, which you can see in action on this test page.

  • Opera 10.52 doesn’t support custom cursors at all.
  • Internet Explorer 8 and below scales all cursors to 32x32.
  • Firefox 3.6 shows 16x16 and 32x32 custom cursors at their native size and ignores other-sized cursors.
  • Safari 4.05 shows 16x16, 20x20, 20x40, 32x32, and 64x64 custom cursors at their native size and ignores other-sized cursors.
  • Firefox 3.7 and Chrome 4.1 show 16x16, 20x20, 20x40, 32x32, 64x64 and 128x128 custom cursors at their native size and ignore 256x256 cursors.


Update: Custom cursors are no longer scaled to 32x32 in IE9 Standards Mode.