A button that does not change the mouse icon on hover leaves a doubt hanging: is it clickable, or just a piece of coloured text? cursor answers that question before the click even happens, changing the mouse's appearance to announce what is about to occur.
This property becomes essential the moment a clickable element is not a native HTML tag built for that purpose, such as a <div> turned into a button with a simple click handler.
Definition
cursor chooses the icon shown by the mouse when it hovers over an element, usually working alongside the :hover pseudo-class for the appearance changes that go with it. The browser offers several dozen predefined values, each tied to a precise meaning that most operating systems recognise instantly.
The most commonly used values
| Value | Icon shown | Typical use |
|---|---|---|
pointer | A pointing hand | Clickable element |
default | The standard arrow | Text or non-interactive area |
not-allowed | A crossed-out circle | Disabled action |
grab | An open hand | Draggable element |
text | An I-beam cursor | Selectable text area |
wait | A loading indicator | Action being processed |
Concrete example: a div turned into a button
.clickable-card {
cursor: pointer;
}
.clickable-card.disabled {
cursor: not-allowed;
}On a fully clickable product card, this cursor clearly signals the possible interaction, without requiring precise hovering over a text link buried in the middle of the image. The disabled version warns the user before they even click, instead of leaving them to discover that nothing happened.
Beyond the click: signalling other kinds of interaction
cursor is not limited to announcing a click. A reorderable drag-and-drop list often switches between grab at rest and grabbing during the actual drag, to visually distinguish the two moments. An asynchronous action, such as submitting a form that waits for a server response, can show cursor: wait across the whole page while it loads, a discreet way of signalling that another click would not help. An image gallery sometimes uses zoom-in to indicate that clicking will enlarge the hovered photo.
The trap: redundant on a link, essential on a div
On an <a href>, cursor: pointer is already the browser's default behaviour: adding it changes nothing. On a native <button>, the result varies across browsers, some keeping the standard arrow, which pushes many teams to force pointer for consistency with links. On a <div> made clickable through JavaScript, however, nothing happens without manual intervention: no adapted cursor, no keyboard accessibility. cursor stays purely visual, unlike pointer-events, which actually controls an element's ability to react to a click.
Frequently asked questions
Is cursor: pointer really useless on every link?
On a plain <a href>, yes, the browser's default value already handles it. It becomes useful again on a link whose default behaviour has been overridden elsewhere in the CSS, or on an element that behaves like a link without technically being one, for instance one carrying a role="button" attribute.
Is the cursor enough to make a div keyboard accessible?
No, not at all. cursor only affects what a mouse user sees; it grants no keyboard focus, no way to trigger a click with the Enter key, and no information at all to a screen reader. Those aspects are handled separately, with a tabindex attribute, an appropriate role, and a keyboard event handler in addition to the click.
Can a custom image be used as the cursor?
Yes, cursor accepts an image URL followed by a fallback value, for example cursor: url("hand.png"), pointer;. The fallback value stays essential: if the image fails to load, the browser falls back to a standard cursor instead of showing no icon at all.