CSS Cursor Viewer
The hand. Means "this activates something", not "this is a link".
.element {
cursor: pointer;
}A cursor is not an affordance on touch
Phones and tablets have no pointer, so every one of these is invisible to most visitors. Cursor choice is a refinement for pointer users, never the only signal that something is interactive.
Every CSS cursor keyword, rendered live so you can hover each one and see what your own operating system draws. That is the point of doing this in a browser rather than reading a list: the keywords are standard, the images are not, and a cursor on Windows often looks nothing like the same keyword on macOS.
How it works
The cursor property names a role, and the operating system supplies the image for it. CSS has no say in what the pointer actually looks like, which is why a screenshot in documentation is only ever true for the machine it was taken on.
- pointer is the hand. It means "activating this does something", which includes buttons. Not, as the name suggests, "this is a link".
- progress and wait are different: progress means busy but still usable, wait means busy and blocked. Using wait for a background save tells the visitor the page is frozen when it is not.
- not-allowed and no-drop are also different: not-allowed means the action is unavailable, no-drop means this particular drop target will not accept the thing you are dragging.
- grab and grabbing are a pair. Swapping to grabbing on pointer down is what makes a drag feel responsive.
- The directional resize cursors follow compass points, and the two-headed variants (ew, ns, nesw, nwse) are the ones to use on a splitter.
A default cursor on a clickable element is a real usability problem, and so is a pointer on plain text, which makes people click things that do nothing. Neither is visible to anyone on a touchscreen, so cursor choice can never be the only signal that something is interactive.
Examples
A disabled button
Cursor
not-allowed
Result
cursor: not-allowed;
It tells the visitor the control exists but the action is unavailable, more informative than default, which suggests nothing is there at all.
A draggable card
Cursors
grab, then grabbing
Result
cursor: grab; and cursor: grabbing on :active
The change on pointer down is what makes a drag feel like it has been picked up. Using grab alone leaves the interaction feeling unresponsive.
A column divider
Cursor
col-resize
Result
cursor: col-resize;
Better than e-resize on a splitter, because it shows movement in both directions rather than implying it only widens.
Frequently asked questions
Why do these look different on my machine?
Because CSS only names the role and the operating system draws it. The same keyword renders differently on Windows, macOS and Linux, and differs again with a custom cursor theme or an accessibility setting. This page shows what your system does, which is the only reliable way to know.
Should buttons use cursor: pointer?
It is contested. The HTML specification gives buttons the default arrow, and the original meaning of the hand was specifically "this navigates". In practice most design systems now use pointer on buttons because visitors expect it. Either is defensible; being consistent within one interface matters more than which you pick.
What is the difference between wait and progress?
wait means the interface is blocked and input will be ignored. progress means something is happening in the background but the page still responds. Using wait for a background save is misleading, visitors stop interacting with a page that was never frozen.
Can I use my own image as a cursor?
Yes: cursor: url(pointer.png) 4 4, pointer. The two numbers are the hotspot, the pixel that actually points, and the keyword after the comma is a required fallback. Browsers cap the size at around 128 pixels and ignore images loaded from another origin.
Do any of these matter on a phone?
No. There is no pointer on a touchscreen, so every cursor value is invisible to those visitors. That makes cursor a refinement for pointer users and never the only affordance. Anything interactive still needs to look interactive without it.