Firefox CSS Hacks Collection

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

IT Director/Senior Software Engineer, Photographer I test and create new CSS web page formatting hacks for BrowserHacks.com for the purpose of repairing web sites. PS-- CSS hacks are fun, but please attempt good CSS first unless in a bind. See Test Pages: https://browserstrangeness.bitbucket.io and https://browserstrangeness.github.io

Tagged with: , , , , , , , ,
Posted in Computers, Cool Code, CSS, CSS Hacks, Firefox, Firefox-All, Hacks, Software, Tech, Web, Web Browser, Web Browsers
18 comments on “Firefox CSS Hacks Collection
  1. […] Note: Check the live test page, or my newer post with more Firefox hacks. […]

    Like

  2. […] on January 16, 2016 by Jeff Clayton — Leave a comment [ View All Firefox CSS Hacks […]

    Like

  3. […] on January 18, 2016 by Jeff Clayton — Leave a comment [ View All Firefox CSS Hacks […]

    Like

  4. Christian Semrau says:

    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.

    Like

    • Jeff Clayton says:

      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.

      Like

  5. Jeff Clayton says:

    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.

    Like

    • Jeff Clayton says:

      _:-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

      Like

Leave a comment