← Back to CSS Course | Chapter 9: Modern CSS Features | Lesson 15 of 25

CSS Cursor

Imagine walking into a store where every door looks identical, so you can never tell which ones open and which are locked until you push on them. The cursor property is the little visual sign above each doorway. It changes the mouse pointer's shape to hint at what will happen, a hand means you can click, a text beam means you can type, and a crossed-out circle means the action is blocked. Setting the right cursor for each interactive element quietly tells visitors what is clickable before they even try, which makes an interface feel more predictable and trustworthy.

Standard Cursor Values

CSS defines many built-in cursor keywords beyond pointer and default, including text, move, grab, help, wait, crosshair, and directional resize cursors like ns-resize. Choosing the right cursor keyword is a small but meaningful signal to users about what an element does before they even click it.

Note: Use cursor: help on elements with a tooltip so users know hovering will reveal more information.

Warning: Overusing exotic cursor values like crosshair or wait outside their expected context can confuse users about what the interface is doing.

Example: Standard Cursor Values

css
<style>
.help { cursor: help; background: #eef; padding: 6px 12px; display: inline-block; }
.move { cursor: move; background: #efe; padding: 6px 12px; display: inline-block; }
.grab { cursor: grab; background: #fee; padding: 6px 12px; display: inline-block; }
</style>
<span class="help">Help</span>
<span class="move">Move</span>
<span class="grab">Grab</span>

Custom Cursor Images

cursor accepts one or more image URLs followed by a required fallback keyword, letting you use a branded custom cursor while still degrading gracefully. If none of the image URLs load successfully, the browser silently falls back to the required keyword at the end of the list.

Note: Keep custom cursor images small, roughly 32 by 32 pixels, so they render crisply and load quickly.

Warning: Always end a custom cursor declaration with a standard keyword like pointer, without a fallback the cursor silently disappears if the image fails.

Example: Custom Cursor Images

css
<style>
.box {
  cursor: url('custom-cursor.png'), pointer;
  background: lightblue;
  padding: 20px;
}
</style>
<div class="box">Falls back to pointer if the image fails</div>

cursor: pointer on Buttons

pointer is the most common cursor value, showing a hand icon over anything clickable, and is especially important on non-native interactive elements like styled divs and spans acting as buttons.

Note: Native button and a elements already show pointer by default in most browsers, but adding it explicitly documents the intent clearly in your stylesheet.

Warning: Setting cursor: pointer does not make an element keyboard accessible or add a click handler, it only changes the visual hint.

Example: cursor: pointer on Buttons

css
<style>
.fake-button {
  cursor: pointer;
  background: royalblue;
  color: white;
  display: inline-block;
  padding: 10px 20px;
}
</style>
<div class="fake-button">Styled div acting as a button</div>

cursor: not-allowed for Disabled Elements

not-allowed shows a circle with a line through it, clearly communicating that an element exists but cannot currently be interacted with, commonly paired with disabled form controls.

Note: Combine cursor: not-allowed with reduced opacity on disabled buttons so the disabled state is obvious both visually and through the cursor.

Warning: Native disabled buttons already show not-allowed automatically in most browsers, manually setting it on a non-disabled element can send a false signal.

Example: cursor: not-allowed for Disabled Elements

css
<style>
button:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}
</style>
<button disabled>Can't click me</button>

Cursor on Interactive States and Overlays

You can change cursor dynamically with pseudo-classes like :hover, or apply it globally to full-page overlays such as loading screens or modal backdrops. A cursor change on hover is often the only visual cue that an otherwise plain-looking element is actually clickable.

Note: Set cursor: wait on a full-page loading overlay so users understand the interface is busy processing something.

Warning: A cursor set on a parent overlay is inherited by its children unless a child explicitly overrides cursor itself.

Example: Cursor on Interactive States and Overlays

css
<style>
.card {
  background: lightblue;
  padding: 10px;
  margin-bottom: 8px;
}
.card:hover {
  cursor: pointer;
}
.overlay {
  background: #333;
  color: white;
  padding: 10px;
  cursor: wait;
}
</style>
<div class="card">Hover to see the pointer cursor</div>
<div class="overlay">Full-page loading overlay</div>
Common Mistakes
  1. Leaving the default cursor on custom-styled clickable divs, visitors may not realize a styled div is interactive without a pointer cursor.
  2. Using cursor: pointer on elements that are not actually clickable, which misleads users into expecting an action.
  3. Forgetting a fallback keyword after a custom cursor image, if the image fails to load the browser has nothing to fall back to.
Chapter Summary
  • cursor changes the mouse pointer shape to communicate what will happen when a user interacts with an element.
  • Custom cursor images can be set with a URL followed by a fallback keyword like pointer or auto.
  • cursor: pointer signals clickable elements, while cursor: not-allowed signals a disabled or blocked action.
Browser Support

The cursor property and its standard keyword values are supported by all modern and legacy browsers; custom image cursors are supported everywhere except very old browser versions.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.