CSSVendor Prefixes

Vendor Prefixes

In the 2000s and early 2010s, browser vendors needed a way to let developers experiment with brand-new CSS features while the specification for those features was still being finalized — and without risking that an early, non-standard implementation would conflict with the eventual standardized syntax. Their answer was the vendor prefix.

The Prefixes

Prefix

Vendor / engine

-webkit-

Safari / WebKit, and early Chrome / Blink

-moz-

Firefox / Gecko

-ms-

Internet Explorer / old Edge

-o-

Old Opera / Presto

CSS
/* How prefixed CSS used to look, back when transforms and
   gradients were new and experimental */
.box {
  -webkit-transform: rotate(10deg);
  -moz-transform: rotate(10deg);
  -ms-transform: rotate(10deg);
  -o-transform: rotate(10deg);
  transform: rotate(10deg); /* unprefixed standard syntax, added last */
}

A prefixed property let a browser ship its own interpretation of a feature (say, gradients or transforms) ahead of the spec being locked down, then later add the unprefixed version once the syntax stabilized — at which point the prefixed version was typically kept around for backwards compatibility, then eventually dropped.

Why This Practice Faded

Vendor prefixes caused real problems. Developers started writing the -webkit- version and skipping the others (since WebKit/Blink dominated market share), which pressured other browsers into implementing -webkit- prefixed properties themselves just to render sites correctly — undermining the entire point of prefixing. Having learned from that web-compatibility pain, browser vendors today are far more cautious about shipping unprefixed, experimental CSS at all; features are more often gated behind developer flags or shipped only once a spec is stable, rather than being exposed prefixed to the public web.

Because hand-writing every prefix for every property is tedious and error-prone, most teams never write prefixes by hand today. Instead they rely on automated tooling — see Autoprefixer & Vendor Prefixes, which adds exactly the prefixes still needed for your declared browser support target, and nothing more.
Where Prefixes Still Show Up Today
A handful of properties, mostly around styling browser-native UI rather than CSS layout, still commonly need a -webkit- prefix even in modern browsers — most notably custom scrollbar styling and the appearance property used to reset native form control styling.

CSS
/* Custom scrollbar styling still needs -webkit- in Chromium/Safari */
.scroll-area::-webkit-scrollbar {
  width: 10px;
}
.scroll-area::-webkit-scrollbar-thumb {
  background: #888;
  border-radius: 5px;
}

/* appearance often still needs -webkit- alongside the standard property */
.reset-input {
  -webkit-appearance: none;
  appearance: none;
}
Note
If a tool like autoprefixer is already in your build pipeline (most Next.js, Vite, and Webpack setups include one via PostCSS), you rarely need to think about prefixes at all — write standard, unprefixed CSS and let the build step add whatever is required for your configured browser targets.