I noticed that buttons on my page did not have the pointer cursor and it annoyed me. I looked up the Tailwind docs and saw that in v4, buttons now use the default cursor. So I did some research on why the default cursor is not pointer.
It started with desktop GUIs
It started with desktop GUIs in the 1980s and 1990s. They had a shadowing effect that gave a skeuomorphic impression of physical buttons. The raised border mimicked something you could press. The design communicated clickability directly, no cursor change required. And if you were born in those years, you just know you can click on them.
In most of those systems, buttons kept the arrow cursor. The hand was more strongly associated with navigation and links, not controls. It was not a strict rule across every platform, but a convention that converged that way across Windows, macOS, and most major desktop environments.
Then came the early web
When hypertext emerged, the clickable bits of text were indicated through underlining and, when colour was available, different colours from the surrounding text. The web was not the first example of hypertext, but it was the application so compelling that it brought the concept to a wide audience. The visual signal was still relatively weak as a physical cue, so the hand-shaped cursor was added as a further indication that this text would take you somewhere.
That is the origin of the association. The hand cursor meant navigation. It appeared on links because links were the thing that needed it. Buttons already had their raised border doing the work.
Welcome to my home page. I am a frontend developer based in Croatia.
I collect refrigerator magnets from places I have visited. You can see them on my magnets page.
CSS standardization
When the W3C formalized CSS in the late 1990s and 2000s, they did not override the cursor conventions that browsers and operating systems had already established for controls like buttons.
Part of that was about respecting platform conventions. Browsers were trying to behave like native desktop applications, and OS buttons had typically used the arrow cursor. Diverging from that would have meant introducing an inconsistency between web controls and the rest of the user's desktop.
There was also a practical concern. Changing cursor defaults would have visually altered millions of existing pages and broken UX assumptions that sites had already been built around. Browser vendors were careful about that kind of change. The web was large enough by then that adjusting defaults had real consequences.
The deeper reason is that the cursor was never meant to be the primary affordance for a button. A well-designed button should look clickable on its own. The visual design carries that signal. The cursor change on a link exists because a line of underlined text needs extra help. A button, designed well, does not.
What the spec says
The CSS UI specification defines pointer as "the cursor is a pointer that indicates a link." It does not strictly say buttons cannot use it, but the framing is link-oriented. Browsers took that and ran with the convention they already had. Pointer for navigation, arrow for controls.
The shift: web apps (2005+)
Gmail launched in 2004. jQuery in 2006. React in 2013. Each of them pushed the web further away from documents and closer to applications. Interfaces that once loaded a new page for every action now updated in place. Buttons were everywhere, doing everything. And developers started treating cursor: pointer as a universal signal for "this is clickable," applying it to buttons, cards, and plain div elements alike.
The original distinction between navigation and action stopped mattering to most people building interfaces. Consistency across every interactive element felt more important than correctness. Everything clickable got the hand cursor, and after enough years of that, the arrow on a button started reading as broken rather than intentional.
What to do about it
Tailwind's preflight does not add cursor: pointer to buttons, following browser defaults. When I noticed that, I added this to my global styles:
button {
cursor: pointer;
}This research reminded me to go through all the buttons on my page and make sure each one has styling that actually communicates what it does.