These are my legal CSS Hacks for fixing web browser quirks or outright bugs. Please enjoy, I have been working on them for years. May it help you if you need them. Please read here first: [What are these CSS Hacks Anyway?] Then check my [Live CSS Hacks Test Page] and also [BrowserHacks.com] where I sent new hacks and test submissions for the site.
Most of these here are my own, especially the majority of underscore hacks and a few media query concoctions and more recently @supports combinations. At the bottom of this list you will also see a few older style hacks in new combinations that have withstood the test of time. Here is the complete Firefox collection I have worked out so far. While it would love to find hacks for every version, it may not be possible. These first few of my creations I am rather proud of. They have already come in very handy.
Fall 2015: Firefox for iOS has just been released, but like Chrome for iOS it uses the Safari engine, so does not respond to these hacks. It uses the Safari Hacks.
/* Firefox (all) */ _:-moz-tree-row(hover), .selector { property:value; } Author: Jeff Clayton
/* Anything but Firefox and Internet Explorer 8 */ _::selection, .selector { property:value; } Author: Jeff Clayton
/* Anything but Firefox and Internet Explorer 8- */ _::selection, :root .selector { property:value; } Author: Jeff Clayton
Next are a few others with special purposes: Here is an odd one, as if CSS hacks weren’t all a little strange… This one was provided by Mozilla (inline style curly braces hack – quirk mode only – source: https://developer.mozilla.org/en-US/Firefox/Releases/27)
/* Firefox 26- (and Internet Explorer 7) */Affected Code Here[ View the Live test page. ]
/* Firefox 25+ (Mac Only) */ @supports (-moz-osx-font-smoothing:auto) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 25+ (Windows Only) */ @media screen and (-moz-os-version) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 4+ (Windows Only) */ @media (-moz-windows-theme) { .selector { property:value; } } Author: Jeff Clayton
With only a minor edit required, this next one was provided in an example by Mozilla in their @document resource notes: https://developer.mozilla.org/en-US/docs/Web/CSS/@document – What is interesting about this set of mozilla regex codes is that they are selectors that act on the URL of the page, NOT the source code!
/* Firefox 6+ (SSL Pages Only) */ @-moz-document regexp('https:.*') { .selector { property:value; } } Author: Jeff Clayton
The https method led to the obvious non-https method…
/* Firefox 6+ (Non-SSL Pages Only) */ @-moz-document regexp('http:.*') { .selector { property:value; } } Author: Jeff Clayton
Numbered version-based css hacks follow…
/* Firefox 45+ */ @supports (-moz-appearance:none) and (word-spacing:100%) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 44+ */ @supports (-moz-appearance:none) and (not (-moz-window-shadow:none)) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 44 */ @supports (-moz-appearance:none) and (not (-moz-window-shadow:none)) and (not (word-spacing:100%)) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 43+ */ @supports (-moz-appearance:none) and (hyphens:none) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 43 */ @supports (-moz-window-shadow:none) and (hyphens:none) { .selector { property:value; } } Author: Jeff Clayton
An experimental JavaScript method I created to test for Firefox 42 and up:
/* Firefox 42+ (JavaScript Method) */ var ff42up = (!!window.sidebar && !!(typeof Reflect==='object') && !!(typeof Reflect.isExtensible==='function')); if (ff42up) document.write("Firefox 42+"); Author: Jeff Clayton
Which led to a little more research, for Firefox 41 and 42:
/* Firefox 42 (JavaScript Method) */ var ff42 = (!!window.sidebar && !!(typeof Reflect==='object') && !!(typeof Reflect.isExtensible==='function') && !Array.prototype.includes); if (ff42) document.write("Firefox 42"); Author: Jeff Clayton
/* Firefox 41 (JavaScript Method) */ var ff41 = (!!window.sidebar && !!(typeof Request==='function'))?!!(typeof Symbol.species==='symbol')&&!!(req=new Request(0).context==='fetch'):false; if (ff41) document.write("Firefox 41"); Author: Jeff Clayton
Back to good old CSS…
/* Firefox 41-42 */ @supports (-moz-appearance:none) and (writing-mode:horizontal-tb) and (not (hyphens:none)) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 41+ */ @supports (-moz-appearance:none) and (writing-mode:horizontal-tb) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 40+ */ @supports (-moz-appearance:none) and (scroll-snap-type:none) and (not (-moz-text-decoration-style:inherit)) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 40 */ @supports (-moz-appearance:none) and (not (writing-mode:horizontal-tb)) and (not (-moz-text-decoration-style:inherit)) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 39+ */ @supports (-moz-appearance:none) and (scroll-snap-type:none) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 39 */ @supports (-moz-appearance:none) and (scroll-snap-type:none) and (-moz-text-decoration-style:inherit) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 38+ */ @supports (-moz-appearance:none) and (ruby-position:over) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 38+ */ _:-moz-tree-row(hover), _:unresolved, .selector { property:value; } Author: Jeff Clayton
/* Firefox 38 */ @supports (-moz-appearance:none) and (ruby-position:over) and (not (scroll-snap-type:none)) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 37+ */ @supports (-moz-appearance:none) and (display:contents) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 37 */ @supports (-moz-appearance:none) and (display:contents) and (not (ruby-position:over)) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 36+ */ @supports (-moz-appearance:none) and (will-change:auto) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 36 */ @supports (-moz-appearance:none) and (will-change:auto) and (not (display:contents)) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 35+ */ @supports (-moz-appearance:none) and (mask-type:alpha) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 35 */ @supports (-moz-appearance:none) and (mask-type:alpha) and (not (will-change:auto)) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 34+ */ @supports (-moz-appearance:none) and (font-kerning:none) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 34 */ @supports (-moz-appearance:none) and (font-kerning:none) and (not (mask-type:alpha)) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 33+ */ @supports (-moz-appearance:none) and (list-style-type:any) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 33+ */ @supports (-moz-appearance:none) and (list-style-type:disclosure-open) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 33 */ @supports (-moz-appearance:none) and (not (font-kerning:none)) and (list-style-type:any) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 32+ */ @supports (-moz-appearance:none) and (box-decoration-break:clone) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 32+ */ _:-moz-tree-row(hover), _:scope, .selector { property:value; } Author: Jeff Clayton
/* Firefox 32 */ @supports (-moz-appearance:none) and (box-decoration-break:clone) and (not (list-style-type:any)) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 22-31 */ @supports (display:flex) and (-moz-background-inline-policy:continuous) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 30-31 */ @supports (-moz-background-inline-policy:continuous) and (background-blend-mode:difference,normal) { .selector { property:value; } } Author: Jeff Clayton
Firefox 31 is the first browser to support CSS3 Variables, so here are my first CSS hacks using them. Just make sure that you use a different variable in each definition. They really are variables, not constants, so they can override each other.
/* Firefox 31+ (CSS3 Variable Method) */ _:-moz-tree-row(hover), .selector { --this-variable:value; property:var(--this-variable); } Author: Jeff Clayton
And using @supports…
/* Firefox 31+ (CSS3 Variable Method) */ @supports (-moz-appearance:none) { .selector { --this-variable:value; property:var(--this-variable); } } Author: Jeff Clayton
/* Firefox 31 (CSS3 Variable Method) */ @supports (-moz-background-inline-policy:continuous) { .selector { --this-variable:value; property:var(--this-variable); } } Author: Jeff Clayton
My previous primary @supports specifier for Firefox was (-moz-appearance:meterbar). I have recently replaced it in favor of (-moz-appearance:none). Both of them work, but I prefer the simpler and easier to read CSS.
/* Firefox 30+ */ @supports (-moz-appearance:none) and (background-blend-mode:difference,normal) { .selector { property:value; } } Authors: Guillaume Simons & Jeff Clayton
/* Firefox 30 */ @supports (background-blend-mode:difference,normal) { _::-moz-math-stretchy, .selector { property:value; } } Author: Jeff Clayton
This proposes an alternate method to the variable method that will work to separate Firefox 30 and 31. Using the above Firefox 30+ hack, it is possible to do a 31+ hack by combining them with the _::-moz-math-stretchy hack for Firefox up to version 30 as follows. Showing with color examples:
/* Firefox 31+ */ @supports (-moz-appearance:none) and (background-blend-mode:difference,normal) { /* for Firefox 30+ */ .selector { color:red; } /* then block Firefox 30 */ _::-moz-math-stretchy, .selector { color:black; } } Author: Jeff Clayton
Using the same alternative method, the Firefox 30-31 hack can also be used to create a Firefox 31 hack:
/* Firefox 31 */ @supports (-moz-background-inline-policy:continuous) and (background-blend-mode:difference,normal) { /* for Firefox 30-31 */ .selector { color:red; } /* then block Firefox 30 */ _::-moz-math-stretchy, .selector { color:black; } } Author: Jeff Clayton
/* Firefox 22-30 */ _::-moz-math-stretchy, _::-moz-range-progress, :root .selector { property:value; } Author: Jeff Clayton
/* Firefox 21-30 */ _::-moz-math-stretchy, _::-moz-range-track, :root .selector { property:value; } Author: Jeff Clayton
/* Firefox 4-30 */ _::-moz-math-stretchy, _:-moz-ui-valid, :root .selector { property:value; } Author: Jeff Clayton
/* Firefox 29+ */ @supports (-moz-appearance:none) and (box-sizing:content-box) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 29+ (media query method) */ @media screen and (min--moz-device-pixel-ratio:0) and (min-resolution:3e1dpcm) { .selector { property:value; } } Source: Guillaume Simons
/* Firefox 29 */ @supports (-moz-appearance:none) and (box-sizing:content-box) and (not (background-blend-mode:difference,normal)) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 28+ */ @supports (-moz-appearance:none) and (list-style-type:japanese-formal) { .selector { property:value; } } Authors: Guillaume Simons & Jeff Clayton
/* Firefox 28+ */ _:-moz-tree-row(hover), _::-moz-range-track:hover, .selector { property:value; } Author: Jeff Clayton
/* Firefox 28 */ @supports (-moz-appearance:none) and (list-style-type:japanese-formal) and (not (box-sizing:content-box)) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 27+ */ _:-moz-tree-row(hover), _::-moz-color-swatch, .selector { property:value; } Author: Jeff Clayton
/* Firefox 27+ */ @supports (-moz-appearance:none) and (all:initial) { .selector { property:value; } } Authors: Guillaume Simons & Jeff Clayton
/* Firefox 27 */ @supports (-moz-appearance:none) and (all:initial) and (not (list-style-type:japanese-formal)) { .selector { property:value; } } Authors: Guillaume Simons & Jeff Clayton
/* Firefox 26+ */ _:-moz-devtools-highlighted, :root .selector { property:value; } Author: Jeff Clayton
/* Firefox 26+ */ @supports (-moz-appearance:none) and (image-orientation:90deg) { .selector { property:value; } } Authors: Guillaume Simons & Jeff Clayton
/* Firefox 26 */ @supports (-moz-appearance:none) and (image-orientation:90deg) and (not (all:initial)) { .selector { property:value; } } Authors: Guillaume Simons & Jeff Clayton
/* Firefox 25+ */ @supports (-moz-appearance:none) and (background-attachment:local) { .selector { property:value; } } Authors: Guillaume Simons & Jeff Clayton
/* Firefox 25 */ @supports (background-attachment:local) and (-moz-text-blink:none) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 25 */ @supports (-moz-appearance:none) and (background-attachment:local) and (not (image-orientation:90deg)) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 24+ */ @supports (-moz-appearance:none) and (cursor:zoom-in) { .selector { property:value; } } Authors: Guillaume Simons & Jeff Clayton
/* Firefox 24 */ @supports (-moz-appearance:none) and (cursor:zoom-in) and (not (background-attachment:local)) { .selector { property:value; } } Authors: Guillaume Simons & Jeff Clayton
/* Firefox 22-23 */ @supports (-moz-appearance:none) and (not (cursor:zoom-in)) { .selector { property:value; } } Authors: Guillaume Simons & Jeff Clayton
/* Firefox 22+ */ @supports (-moz-appearance:none) and (display:flex) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 22+ */ @supports (-moz-appearance:meterbar) and (display:flex) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 22+ */ _:-moz-tree-row(hover), _::-moz-range-progress, .selector { property:value; } Author: Jeff Clayton
/* Firefox 21+ */ _:-moz-tree-row(hover), _::-moz-range-track, .selector { property:value; } Author: Jeff Clayton
/* Firefox 19+ */ _:-moz-tree-row(hover), _::-moz-placeholder, .selector { property:value; } Author: Jeff Clayton
Unless a hack for 18 is found, the way to get 18+ is to do a 17+ hack, and then the 17 hack after (to undo or ‘block’ 17). If you wish to get 18 exactly, then do the 19+ hack after that, to ‘block’ 19 and newer. For newer users, say you were to want 18 to be red… Set 17+ to red, 17 to black, and 19+ to black. Then 18 is left red in the result.
/* Firefox 17+ */ _:-moz-dir(ltr), .selector { property:value; } Author: Jeff Clayton
/* Firefox 17 */ _:-moz-dir(ltr), _:-moz-has-handlerref, .selector { property:value; } Author: Jeff Clayton
/* Firefox 16+ */ @media screen and (min--moz-device-pixel-ratio:0) and (min-resolution:.1dppx) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 16+ */ _:-moz-meter-optimum, :root .selector { property:value; } Author: Jeff Clayton
/* Firefox 15+ */ _:-moz-type-unsupported-platform, :root .selector { property:value; } Author: Jeff Clayton
/* Firefox 11+ */ @media screen and (min--moz-device-pixel-ratio:0) { @media (min-width:0px) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 10+ */ _:-moz-full-screen-ancestor, :root .selector { property:value; } Author: Jeff Clayton
/* Firefox 9+ */ _:-moz-full-screen, :root .selector { property:value; } Author: Jeff Clayton
/* Firefox 8+ */ @media screen and (min--moz-device-pixel-ratio:0) and (min-resolution:.001dpcm) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 6+ */ _::-moz-progress-bar, :root .selector { property:value; } Author: Jeff Clayton
/* Firefox 6+ (document method) */ @-moz-document regexp('*') { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 4+ */ _:-moz-ui-valid, :root .selector { property:value; } Author: Jeff Clayton
/* Firefox 4+ */ @media (-moz-device-pixel-ratio) { .selector { property:value; } } Source: My Simplest Version of an Old Query
/* Firefox 3.6+ */ @media screen and (-moz-images-in-menus:0) { body:last-child .selector { property:value; } } Author: Jeff Clayton
/* Firefox 3.6+ */ _:-moz-locale-dir(ltr), .selector { property:value; } Author: Jeff Clayton
/* Firefox 3.6+ (up to 46) */ html:not(:-moz-handler-crashed) .selector { property:value; } Author: Jeff Clayton
/* Firefox 3.6 */ _:not(), _:-moz-handler-crashed, .selector { property:value; } Author: Jeff Clayton
/* Firefox 3.6- (Firefox < 4.0) */ _:not(), .selector { property:value; } Author: Jeff Clayton
/* Firefox 3.5-3.6 */ _:not(), _:-moz-handler-blocked, .selector { property:value; } Author: Jeff Clayton
/* Firefox 3-3.6 (Firefox 3.x) */ _:not(), _:-moz-loading, .selector { property:value; } Author: Jeff Clayton
/* Firefox 1.5-3.6 ( Firefox > 1.0 and < 4.0 ) */ _:not(), _:optional, .selector { property:value; } Author: Jeff Clayton
This old hack is an odd one that rules out some versions of Linux:
/* Firefox 3.6+ (Some Non-Linux) */ @media screen and (-moz-images-in-menus:0) { .selector { property:value; } } Author: Jeff Clayton
/* Firefox 3.5+ (up to 46) */ html:not(:-moz-handler-blocked) .selector { property:value; } Author: Jeff Clayton
/* Firefox 3.5+ */ @media screen and (orientation) { _:-moz-tree-row(hover), .selector { property:value; } } Author: Jeff Clayton
/* Firefox 3+ */ _:-moz-loading, :root .selector { property:value; } Author: Jeff Clayton
/* Firefox 2+ */ _:-moz-is-html, :root .selector { property:value; } Author: Jeff Clayton
/* Firefox 1.5+ */ _:-moz-read-write, :root .selector { property:value; } Author: Jeff Clayton
/* Firefox 1.5+ */ _:-moz-only-whitespace, :root .selector { property:value; } Author: Jeff Clayton
/* Firefox 1.5 (Only) */ _:-moz-read-write, _::-moz-viewport, :root .selector { property:value; } Author: Jeff Clayton
/* Firefox 1.x (only) 1.0-1.5 */ _:-moz-tree-row(hover), _::-moz-viewport, .selector { property:value; } Author: Jeff Clayton
[…] Note: Check the live test page, or my newer post with more Firefox hacks. […]
LikeLike
[…] View All Firefox CSS Hacks […]
LikeLike
[…] View All Firefox CSS Hacks […]
LikeLike
[…] View All Firefox CSS Hacks […]
LikeLike
[…] View All Firefox CSS Hacks […]
LikeLike
[…] View All Firefox CSS Hacks […]
LikeLike
[…] View All Firefox CSS Hacks […]
LikeLike
[…] View All Firefox CSS Hacks […]
LikeLike
[…] View All Firefox CSS Hacks […]
LikeLike
[…] View All Firefox CSS Hacks […]
LikeLike
[…] View All Firefox CSS Hacks […]
LikeLike
[…] View All Firefox CSS Hacks […]
LikeLike
[…] on January 16, 2016 by Jeff Clayton — Leave a comment [ View All Firefox CSS Hacks […]
LikeLike
[…] on January 18, 2016 by Jeff Clayton — Leave a comment [ View All Firefox CSS Hacks […]
LikeLike
I recently noticed that the FF hacks using -moz-handler-blocked and -moz-handler-crashed do not work in FF 47. They work in FF45, and I don’t know about 46.
LikeLike
Thank you for letting me know – these things are actually great, they allow us to target specific versions via precision combinations when they ‘expire’ — I will look into it and make the necessary updates.
LikeLike
Okay they both worked in Firefox 46, and the -moz- prefix on both removed support in version 47. I updated the test page and this one. Thank you again for the notification.
LikeLike
_:-moz-locale-dir(ltr), .selector { property:value; } still does work for 3.6+ however, there are probably many others since 3.5 and 3.6 were rather large updates
LikeLike