public

How to hide <select> dropdown's arrow in Firefox when using "-moz-appearance: none;".

  • Download Gist
How To Hide The Select Arrow On Firefox.md
Markdown

How to remove hide the select arrow in Firefox using -moz-appearance:none;

tl;dr (or, the fix)

  1. Set -moz-appearance to none. This will "reset" the styling of the element;
  2. Set text-indent to 0.01px. This will "push" the text a tiny bit[1] to the right;
  3. Set text-overflow to '' (an empty string). This will change anything that extends beyond the element's width to... nothing - and this includes the infamous arrow!

Firefox select element with no arrow

Continue reading for the full lowdown.

Background

I was experimenting on custom styling the <select> elements of a form I was building. One of the things I tried implementing was truncating the text with an ellipsis in case it extended beyond the <select>'s width. It didn't look consistent through browsers, but I've accidentally discovered something really nice.

The bug

Firefox <select> with appearance attribute set to none (Ubuntu):

Buggy select element on Firefox

Chrome <select> with appearance attribute set to none (Ubuntu):

Okay select element on Chrome

As this 2011 bug report states, there is an issue regarding Firefox's -moz-appearance and <select> elements: it was supposed to ditch the <select>'s arrow (like Chrome's implementation) but it simply doesn't. People were raging about the subject all over the internetz.

Live example

http://codepen.io/joaocunha/pen/qLgCG

(Firefox only, duh)

Final considerations

  • Firefox doesn't remove the arrow, it hides it. You will have some white space on the right[2] (same width of the now-hidden arrow);
  • Chrome removes the arrow by default with -webkit-appearance:none; instead of hiding. No white space on the right;
  • Chrome doesn't support the text-overflow:''. No evenly-cut text;
  • Your best bet is to set some padding-right in order to provide right space for your styled version of the arrow. Just keep in mind that Firefox will take the ghost arrow width into account;
  • Turns out that Windows doesn't require the -moz-appearance: none; declaration at all. Tested on 8;
  • Firefox for Android needs the whole width of the arrow as text-indent. It means you need to set it to at least 5px, but take care since Firefox seems to double the text-indent value on <select> elements.
  • Zooming out (ctrl mousewheeldown, ctrl -, etc) reveals[3] the default arrow. No big deal;
  • The appearance attribute is not well supported through browsers, so take this fix with a grain of salt when developing your crossbrowser solution.

Support

Ubuntu, Windows, Mac, Android 4.3.

Follow the guy

@joaocunha

[1] Thanks to Binyamin for improving it from 1px to 0.01px.

[2] Thanks to RussellUresti for noticing the white space.

[3] Thanks to MathiasaurusRex for noticing the zoom issue.

Bonus: remove the select arrow on IE10 using the proprietary -ms-expand pseudo-class

select::-ms-expand {
    display: none;
}

you should add before/after screenshots to this

Just added. Thanks for checking, @paulirish.

João, I want to correct myself - change 0.01px to .01px. It would deliver the same result and save a bit performance.

@laukstein, that's something for your CSS minifier to worry about. If you start to worry about single bytes like that you can continue to remove unneeded ending ;, indentation, etc.

I agree with @Qtax. Plus 0.01px makes up for better readability.

Turns out that Windows doesn't require the -moz-appearance: none; declaration. Windows 8, FF 23.0.1.

You are insane, thanks! It works!

Thanks, it works like charm! I hope someday Mozilla gonna solve this.

What about IE 8 & 9?

@vladakilov they degrade gracefully to the regular arrow, although it might be possible to accomplish some results by playing with position: absolute; and clip: rect(...).

thanks from Russia)

Awesome, it works like charm! Thanks from Germany :)

This is excellent. Thanks.

I've come across this issue several times now. This is the only solution I've seen so far that works. You're amazing Joao, thx a lot!

If you wanted to target only Firefox, you could wrap like so…

@-moz-document url-prefix() {
  select {
    -moz-appearance: none;
    text-indent: 0.01px;
    text-overflow: "";
  }
}

I had the problem that my SASS parser didn't like the text-indent value of 0.01px and rounded it to 0.

I found the very hackerish solution:
-moz-appearance: radio-container;
which actually does look like "none" on my Mac's Firefox (but still fails in Firefox for Android)

@voodoocode, which version of SASS are you using? I'm not having any trouble with it. Anyway, stick with 1px instead of changing the value of -moz-appearance as it may lead to some undesired results. You can always mix it with @nathansmith tip if that 1px annoys you :)

This does not work on android firefox.

@FDiskas check the "final considerations" part. There is a solution for Android FF as well.

Very detailed tests, thank you very much!

You deserve a donation for this. Seriously, where can I donate?

@danielgolden give <3 back to the community :)

Thank you for this, @joaocunha, you beautiful mad genius, you!

You sir, are amazing. Thank you.

Thanks for posting this!

Thank you for sharing this!

Hello,
I have had the following code (image attached) on my select dropdown, for some time, and it was working fine up until about 2 weeks ago, perhaps. When i noticed it was no longer hiding the arrow in Firefox. Has anyone else noticed this, or do you notice anything strange in my code? It's strange because it was definitely working before, and now suddenly it's not :(
Katrina
Snapshot: http://i.imgur.com/7wB88wt.jpg

@kat2014 what version is yours? I've heard some comments about a Nightly version that doesn't support the trick but didn't have time to actually test yet.

It works just fine on my v.28 on Ubuntu, which happens to be the latest.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.