Reference

CSS cursor: every value, with a live preview

The cursor property sets the pointer a reader sees over an element. Here are all 36 keywords and url(), grouped by what they tell the reader. Move your mouse over any row to see the cursor your browser draws for it.

Syntax

How the property works

CSS
/* A keyword */
button {
  cursor: pointer;
}

/* Your own image: a hotspot (x y) and a keyword to fall back on */
.canvas {
  cursor: url("pen.png") 4 28, crosshair;
}

Give cursor one keyword, or a list of images followed by one keyword. The browser uses the first image it can load and show, and the keyword at the end is required: it is what readers see if no image works.

The two numbers after an image are its hotspot, the pixel that does the clicking, counted from the top-left corner. Leave them out and the browser uses the hotspot stored in the file if it has one (a .cur does), or the top-left pixel if it does not (a PNG or SVG).

Keep cursor images at 32 × 32 pixels where you can. Firefox and Chromium-based browsers will not show a cursor image larger than 128 × 128.

3 values

General

Let the browser decide, show the plain arrow, or show nothing at all.

Value Try it What it tells the reader
auto The browser picks for you: a text cursor over selectable text, an arrow almost everywhere else.
default The normal arrow of the operating system.
none No cursor is drawn at all.

4 values

Selection

Selecting text, table cells, and exact points.

Value Try it What it tells the reader
cell A table cell, or a range of cells, can be selected.
crosshair You can pick an exact point, as in a drawing or cropping tool.
text Text can be selected, usually an I-beam.
vertical-text Vertical text can be selected, usually an I-beam turned on its side.

7 values

Drag and drop

Grabbing, moving, copying, and refusing a drop.

Value Try it What it tells the reader
alias Dropping here makes a shortcut or alias to the item.
copy Dropping here makes a copy of the item.
move The item under the pointer can be moved.
no-drop The item you are dragging cannot be dropped here.
not-allowed The action you are trying will not happen.
grab Something can be grabbed and dragged, usually an open hand.
grabbing Something is being dragged right now, usually a closed hand.

15 values

Resize and scroll

Edges, corners, columns, rows, and panning.

Value Try it What it tells the reader
all-scroll The content can be scrolled or panned in any direction.
col-resize A column can be made wider or narrower.
row-resize A row can be made taller or shorter.
n-resize The top (north) edge can be moved.
e-resize The right (east) edge can be moved.
s-resize The bottom (south) edge can be moved.
w-resize The left (west) edge can be moved.
ne-resize The top-right (north-east) corner can be moved.
nw-resize The top-left (north-west) corner can be moved.
se-resize The bottom-right (south-east) corner can be moved.
sw-resize The bottom-left (south-west) corner can be moved.
ew-resize Something can be resized to the left and right.
ns-resize Something can be resized up and down.
nesw-resize Something can be resized along the top-right to bottom-left diagonal.
nwse-resize Something can be resized along the top-left to bottom-right diagonal.

2 values

Zoom

Zooming in and zooming out.

Value Try it What it tells the reader
zoom-in Clicking zooms in, usually a magnifier with a plus.
zoom-out Clicking zooms out, usually a magnifier with a minus.

1 values

Custom images

Your own image, with a hotspot and a fallback keyword.

Value Try it What it tells the reader
url() Your own image as the cursor, with an optional hotspot and a keyword to fall back on.

Custom images

Custom cursor images, browser by browser

Every desktop browser accepts custom cursor images. Keep them at 32x32, end the list with a keyword, and expect the fallback near the edges of the page.

Support

Support for cursor: url() custom image cursors, by browser
Browser Engine url() from version Hotspot numbers from version Uses the hotspot in a .cur file
Chrome Blink 1 1 Yes
Edge Blink 12 12 Yes
Firefox Gecko 1.5 1.5 Yes
Safari (macOS) WebKit 3 3 Yes
Safari on iPad WebKit 13.4 No Not tested
Chrome for Android Blink 18 18 Not tested

Image formats

Which image formats each browser accepts as a cursor
Browser PNGSVG.curGIF.ani Other formats
Chrome YesYes, needs a natural size (width and height)Yes, including the hotspot stored in the fileYes, first frame only (no animation)No Any still image format Chrome displays elsewhere, such as JPEG and WebP.
Edge YesYes, needs a natural size (width and height)Yes, including the hotspot stored in the fileYes, first frame only (no animation)No Same as Chrome.
Firefox YesYes, needs a natural size (width and height)Yes, including the hotspot stored in the fileYes, first frame only (no animation)No Any still image format Firefox displays elsewhere, such as JPEG and WebP.
Safari (macOS) YesYesYes, including the hotspot stored in the file (not in Lockdown Mode)Yes, first frame only (no animation)No TIFF, BMP, ICO, JPEG and WebP. In Lockdown Mode only PNG, JPEG, GIF and WebP load.
Safari on iPad YesNot testedNot testedNot testedNo Not tested.
Chrome for Android YesNot testedNot testedFirst frame only (not tested)No Not tested.

Size limits

The largest cursor image each browser shows, and what happens near the edges of the page
Browser Largest image Near the edges of the page
Chrome 128x128 CSS pixels. Larger images are skipped. From Chrome 156, any custom cursor that would stick out of the visible page is skipped and the next value is used. Chrome 75 to 155 applied this only to images larger than 32x32.
Edge 128x128 CSS pixels, as in Chrome. Follows Chrome: from version 156 any custom cursor that would stick out of the visible page is skipped; earlier versions skipped only images larger than 32x32.
Firefox 128x128 CSS pixels, per MDN. Since Firefox 67, a cursor larger than 32x32 CSS pixels is skipped when it would stick out of the page's viewport (the layout.cursor.block.max-size setting, 32 by default). Cursors of 32x32 or smaller are never skipped for this reason.
Safari (macOS) 128x128 CSS pixels. Larger images are skipped. Any custom cursor that would not fit entirely inside the visible page is skipped, whatever its size.
Safari on iPad Not documented. Not documented.
Chrome for Android Not documented; assume the desktop Chrome limit of 128x128. Not documented; assume desktop Chrome behaviour.

Which format to use

PNG
The safe default. Every desktop browser accepts it. Use 32x32 with a transparent background.
SVG
Sharp at any screen density. Give the root svg element width and height attributes; the spec only requires browsers to accept SVG cursors that state their own size.
.cur
The Windows cursor format. Browsers read it and use the hotspot stored inside, so you can leave out the coordinates in CSS.
GIF
Accepted, but every browser shows a single frame. An animated GIF does not animate as a cursor.
.ani
The Windows animated cursor format. No current browser accepts it in CSS; it is for installing on Windows.

Size advice

  • 32x32 is the size to design for. It matches the default system cursor and avoids every edge rule.
  • Anything above 128x128 is ignored by Chrome, Edge, Firefox and Safari.
  • Between 33 and 128 pixels, Firefox and Chrome before 156 swap your cursor for the fallback near the edges of the page.
  • From Chrome 156, and in Safari, any custom cursor is swapped for the fallback when it would stick out of the page, so keep the hotspot near the image's top-left if you want it to work right up to the edges.

The hotspot

Syntax
url("file.png") X Y, keyword
Units
Image pixels, measured from the top-left corner (0 0).
Without numbers
The hotspot stored in a .cur file, otherwise 0 0.
Numbers outside the image
Chrome and Firefox clamp values outside the image to its edges, as the spec asks. Safari ignores a hotspot outside the image and falls back to the hotspot stored in the file, or 0 0.
On iPad
Ignored on iPad.

Browser notes

Chrome
  • SVG cursors are drawn at the screen's pixel density, so they stay sharp.
  • image-set() is accepted inside cursor for 1x and 2x files.
Edge
  • Edge 79 and later share Chrome's engine. Edge 12 to 18 used Microsoft's older engine.
Firefox
  • Hotspot coordinates are rounded and clamped to the image.
  • Firefox 4 added url() cursors on macOS.
Safari (macOS)
  • An SVG without its own size is treated as 32x32.
Safari on iPad
  • Only applies to iPads with a trackpad or mouse. iPhones have no pointer.
  • MDN's data lists hotspot coordinates as unsupported: the image is placed by its top-left corner.
Chrome for Android
  • Cursors only appear with a mouse or trackpad connected.
  • Version numbers mirror desktop Chrome in MDN's data.

Windows and macOS

What each value becomes on Windows and macOS

Which system cursor each CSS keyword turns into. Windows names come from the registry and Mouse Properties; macOS names describe what Chrome asks macOS for. Safari and Firefox can differ on macOS.

A Windows role
Windows draws one of its 17 roles, so a custom Windows scheme changes it.
Drawn by the browser
Windows has no matching role; the browser draws its own image, and a Windows scheme cannot change it.
Hidden
No cursor is drawn.
Your image
Your own image.
Each CSS cursor value and the Windows and macOS cursor it turns into
CSS value Windows Windows file macOS macOS cursor in code Note
auto Normal Select(Arrow) aero_arrow.cur Arrow or I-beam NSCursor.arrowCursor / NSCursor.IBeamCursor Over selectable text the IBeam role is used instead.
default Normal Select(Arrow) aero_arrow.cur Arrow NSCursor.arrowCursor None
none Hidden None Hidden (empty cursor) None
context-menu Normal Select(Arrow) aero_arrow.cur Contextual menu NSCursor.contextualMenuCursor Windows has no context-menu cursor; Chrome, Edge and Firefox show the Arrow.
help Help Select(Help) aero_helpsel.cur Help private system cursor None
pointer Link Select(Hand) aero_link.cur Pointing hand NSCursor.pointingHandCursor None
progress Working in Background(AppStarting) aero_working.ani Busy but clickable private system cursor Animated on Windows.
wait Busy(Wait) aero_busy.ani Busy but clickable private system cursor Animated on Windows. Chrome on macOS shows the same cursor as progress.
cell Drawn by the browser None Cell private system cursor None
crosshair Precision Select(Crosshair) built-in Crosshair NSCursor.crosshairCursor None
text Text Select(IBeam) built-in I-beam NSCursor.IBeamCursor None
vertical-text Drawn by the browser None Vertical I-beam NSCursor.IBeamCursorForVerticalLayout None
alias Drawn by the browser None Drag link NSCursor.dragLinkCursor None
copy Drawn by the browser None Drag copy NSCursor.dragCopyCursor None
move Move(SizeAll) aero_move.cur Move private system cursor The look on macOS varies by browser.
no-drop Unavailable(No) aero_unavail.cur Operation not allowed NSCursor.operationNotAllowedCursor Drawn the same as not-allowed in Chrome, Edge and Firefox.
not-allowed Unavailable(No) aero_unavail.cur Operation not allowed NSCursor.operationNotAllowedCursor None
grab Drawn by the browser None Open hand NSCursor.openHandCursor None
grabbing Drawn by the browser None Closed hand NSCursor.closedHandCursor None
all-scroll Move(SizeAll) aero_move.cur Move private system cursor Chrome shows the move cursor on every platform; Firefox does on Windows.
col-resize Drawn by the browser None Column resize NSCursor.columnResizeCursor (macOS 15+), NSCursor.resizeLeftRightCursor before Closest Windows role: SizeWE.
row-resize Drawn by the browser None Row resize NSCursor.rowResizeCursor (macOS 15+), NSCursor.resizeUpDownCursor before Closest Windows role: SizeNS.
n-resize Vertical Resize(SizeNS) aero_ns.cur Resize up frame resize cursor, top edge, outward (macOS 15+) None
e-resize Horizontal Resize(SizeWE) aero_ew.cur Resize right frame resize cursor, right edge, outward (macOS 15+) None
s-resize Vertical Resize(SizeNS) aero_ns.cur Resize down frame resize cursor, bottom edge, outward (macOS 15+) None
w-resize Horizontal Resize(SizeWE) aero_ew.cur Resize left frame resize cursor, left edge, outward (macOS 15+) None
ne-resize Diagonal Resize 2(SizeNESW) aero_nesw.cur Resize up-right frame resize cursor, top-right corner, outward (macOS 15+) None
nw-resize Diagonal Resize 1(SizeNWSE) aero_nwse.cur Resize up-left frame resize cursor, top-left corner, outward (macOS 15+) None
se-resize Diagonal Resize 1(SizeNWSE) aero_nwse.cur Resize down-right frame resize cursor, bottom-right corner, outward (macOS 15+) None
sw-resize Diagonal Resize 2(SizeNESW) aero_nesw.cur Resize down-left frame resize cursor, bottom-left corner, outward (macOS 15+) None
ew-resize Horizontal Resize(SizeWE) aero_ew.cur Resize left-right frame resize cursor, left edge, both ways (macOS 15+) None
ns-resize Vertical Resize(SizeNS) aero_ns.cur Resize up-down frame resize cursor, top edge, both ways (macOS 15+) None
nesw-resize Diagonal Resize 2(SizeNESW) aero_nesw.cur Diagonal resize, top-right to bottom-left frame resize cursor, top-right corner, both ways (macOS 15+) None
nwse-resize Diagonal Resize 1(SizeNWSE) aero_nwse.cur Diagonal resize, top-left to bottom-right frame resize cursor, top-left corner, both ways (macOS 15+) None
zoom-in Drawn by the browser None Zoom in NSCursor.zoomInCursor (macOS 15+) None
zoom-out Drawn by the browser None Zoom out NSCursor.zoomOutCursor (macOS 15+) None
url() Your image None Your image custom NSCursor from your image None

Windows roles no CSS value asks for: Handwriting (NWPen) , Alternate Select (UpArrow) , Location Select (Pin) and Person Select (Person) . Browsers never show them; they are for desktop apps. The table of all 17 roles lists what each one is for.