Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
How to hide <select> dropdown's arrow in Firefox when using "-moz-appearance: none;".

This is no longer a bug. I'm keeping the gist for historical reasons, as it helped to get it fixed. Make sure to read the edits below.

Edit 4: Mozilla released Firefox v35 and, indeed, the bug is patched. https://developer.mozilla.org/en-US/Firefox/Releases/35

Edit 3: Mozilla addressed the issue! Target milestone is v35. Yay!

Edit 2: Todd Parker from Filament Group tweeted about a CSS only alternative that works pretty much everywhere. You can check it here.

Edit: this trick stopped working as of Firefox 30 realeased in 2014-06-10. Join the comments section to help finding an alternative, and please upvote the bug on Bugzilla for a definitive fix. If you now have double arrows on Firefox, this might solve your issue.

Don't use any other value of -moz-appearance as the styles inherited are not customisable.


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 discovered something 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 workaround with a grain of salt when developing your crossbrowser solution.

Support

Tested on latest versions of Ubuntu, Windows, Mac and Android.

Follow me

@joaocunha

Thanks

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

[2]RussellUresti for noticing the white space.

[3]MathiasaurusRex for noticing the zoom issue.

@joaocunha
Owner

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

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

you should add before/after screenshots to this

@joaocunha
Owner

Just added. Thanks for checking, @paulirish.

@laukstein

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

@Qtax

@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.

@joaocunha
Owner

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

@joaocunha
Owner

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

@woren94

You are insane, thanks! It works!

@AkashSaikia

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

@vladakilov

What about IE 8 & 9?

@joaocunha
Owner

@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(...).

@omar-G

thanks from Russia)

@eddiesel

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

@JonDum

This is excellent. Thanks.

@Marcoevich

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!

@nathansmith

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: "";
  }
}
@voodoocode

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)

@joaocunha
Owner

@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 :)

@FDiskas

This does not work on android firefox.

@joaocunha
Owner

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

@yisibl

Very detailed tests, thank you very much!

@wenjul

Great!

@HosseinKarami

Awesome! :)

@MartinSandholt

Thanks :)

@danielgolden

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

@joaocunha
Owner

@danielgolden give <3 back to the community :)

@kimili

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

@revxx14

You sir, are amazing. Thank you.

@MathiasaurusRex

Thanks for posting this!

@jefsnare

Thank you for sharing this!

@yashodhand

Cool thank you

@kat2014

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

@joaocunha
Owner

@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.

@emitstop

This trick has stopped working as of firefox 31 (currently in nightlies).

@itsclockwork

Confirmed, in FirefoxNightly (31), the hack no longer works.
With the appearance: none, not working as desired and the hack no longer functioning, maybe we could be a little more vocal to Mozilla. I know I didn't feel inclined to upvote the bug when I had a workaround. So if you're about to feel the pain or feeling it now, you can vote up the priority on the bug: https://bugzilla.mozilla.org/show_bug.cgi?id=649849

@blaise-io

In case anyone finds a solution, can you answer my question on stackoverflow?

@pwlin

If anything, this bug -and the subsequent fragile workaround- proves that it's better to stand up against browser vendors and demand standard conformity instead of writing quick and dirty hacks.

There was a constant outcry on the original bug report in bugzilla where people were voicing their concerns and were asking for a real fix.

Until someone came along, felt clever, and implemented a dirty hack which resulted in people stop complaining anymore and got happy with the trick.

Now, a couple of months later, the "clever" trick doesn't work anymore, there is no real fix in the pipeline by Mozilla, and above all, almost all the previous objections by the users are dispersed. It will now take much longer to once again rally people around this bug and ask for a fix.

Don't treat yourself like we are still in the IE6 era. By advocating a hack to fix a standard-compliant bug in an open source browser you are actually doing a disservice to the community. It will decrease the pressure on the browser vendor's shoulders to actually fix the issue based on standard specs.

Please go to the original bug report in bugzilla and demand a real fix.

@joaocunha
Owner

@pwlin,

  • The bug has been there for three years and it's not even in the pipeline to be solved, and you propose people should wait longer?
  • Maybe we still are in the "IE6 era". That is, at least for people who write real websites for real people.
  • There are several ways of styling <select> elements. If you're not happy with resetting its' styles, just do something else.
  • This fix is not dirty by any means. It's completely unobtrusive, and even if it stops working, it will not break anything, except from showing double arrows. You can media-query FF to ignore the background declaration if you want.
  • I was adamant on making this gist as clear and complete as possible, so people can make a proper decision on why to use it. I didn't spread the word as a definitive fix - quite the opposite, I always called it a trick, a workaround.
  • There is no such thing as demanding in the OSS world. You either politely ask for a fix, or either jump in and collaborate.

Bottomline: browser specific hacks/workarounds have been there for ages. If you don't use them, you either have a better solution or it's just a big, massive FUD. Please try to be a bit more polite next time you give your opinion.

@pwlin

I am sorry if my comment made you feel hurt. This is not a personal attack on you or anything like that.

Now back to the point I was making:
these kind of temporary hacks/tricks/workarounds will only delay the release of the real fix. Because people will implement these workarounds and get on with their life, while the underlying bug still exists in the code. And it just makes it more difficult to fix the real bug.

As a clear evidence, just look at what itsclockwork said a couple of comments above mine:

I didn't feel inclined to upvote the bug when I had a workaround. 
So if you're about to feel the pain or feeling it now,
you can vote up the priority on the bug

That's exactly what I pointed out in my previous comment. Many people had no reason to complain when there was a workaround. In a sense, it served as a painkiller to them, while what actually needed here is a cure. Now that there is no workaround, people are more motivated to look for a real fix.

@QWp6t

@pwlin, there's nothing wrong with developing a workaround while we wait for a fix. If users decide not to ask for a proper fix, that's on them. It is not @joaocunha's fault that @itsclockwork didn't upvote the bug. It's unreasonable to hold him responsible for the actions or inactions of random people online. Your argument is junk.

@pwlin

@QWp6t Talking about being polite .....
Dude, I didn't hold anybody responsible for someone's else actions. But you can not deny the fact that temporary workarounds only help arrogant browser vendors to delay releasing a real fix even longer.

This hack does not work anymore, so I feel myself beating a dead horse. Enjoy doing wahtever you feel good to do.

@joaocunha
Owner

If you are using this trick to provide a custom arrow and FF is now showing both the custom and the native ones, there are two ways to get rid of the custom arrow on it.

Option 1:
If your arrow is tiny, you can use it as background-image and hide it under the native arrow, as I proposed to Foundation.

Option 2:
Remove the custom styles on Firefox only through a url-prefix media query, like:

@-moz-document url-prefix() {
  /* If you use a background image */
  select {
     background-image: none;
  }

  /* If you use a wrapper label with :after */
  .select-label:after {
    content: none;
  }
}

You can also hide the native arrow by making the select element larger than it's container. Example:

.select-wrapper {
    width: 200px;
    overflow: hidden;
}

select {
    width: 110%;
}
@kencaron

@joaocunha Thanks, I'm able to use your first option myself. Hoping we see a solution surface now that 30 is released.

@jakmany

Thanks +1:

@thom-nic

Any ideas how to "fix" this now that it's broken again in FF30? :(

@sorahn

-moz-appearance: tabpanels; clears out the arrow, but it adds an inset shadow and border radius that I'm not sure how to get rid of.

jsfiddle

Edit: It appears this is only for FF30/OSX. No luck on windows yet.

More Edit: Here's an image of something I did for a project I was working on. The downside is that the select box is wider than the space, but it works no problem.

I just made the select box 110% of the width of it's container, and have overflow hidden on the container.

Edit All The Things: Here's a codepen of the example above: http://codepen.io/drbrts/pen/JAbyF

@YemSalat

Doesn't work anymore, your codepen demo as well. Win7, firefox 30

@barnettjw

@YemSalat, @hom-nic

In firefox 30 this works:

<div class="styled-select">
     <select>
         <option>Here is the first option</option>
         <option>The second option</option>
         <option>The thrid option</option>
     </select>
</div>
.styled-select { 
  overflow: hidden; 
  width: 200px;
}

@-moz-document url-prefix(){
  .styled-select select { width: 110%; }
}

For a cross-browser solution (Tested in IE 8-11, Firefox 30, Chrome 35), here's what I use: http://codepen.io/jamesbarnett/pen/JhHjK

@sorahn

@barnettjw the problem with your solution is that you cannot click the arrow.

I have an updated solution that I've implemented at work, but I haven't had time to build a pen yet.

// Strip away all the browser styles for a select box.
// The syntax for this needs to be as follows.
//
// <div class="select--clean">
//   <select>...</select>
//   <i class="fa fa-caret-down">
// </div>
//
// To add custom style overrides, either wrap the whole div inside another
// class, or add a class to the div with 'select--clean'.
//
// Example: http://codepen.io/drbrts/pen/JAbyF

.select--clean
  display: inline-block
  overflow: hidden
  position: relative

  select
    @include appearance(none)
    width: 100%

    border: 0
    outline: 0
    border-radius: 0
    margin: 0
    padding-right: 15px

    letter-spacing: inherit
    background: transparent

    &:-moz-focusring
      color: transparent

    &::-ms-expand
      display: none

    &,x:-moz-any-link,x:default
      padding-right: 0
      width: -moz-calc(100% + 17px)
      width: calc(100% + 17px)

  option
    border: 0

  i
    pointer-events: none
    position: absolute
    right: 0
    top: 2px
    color: inherit

@mixin select-colors($color: #000000, $bg: #ffffff)
  color: $color
  background: $bg

  select
    color: $color

    &:-moz-focusring
      text-shadow: 0 0 0 $color

  option
    color: $color
    background: $bg

  i
    color: $color
@joaocunha
Owner

Guys, don't use any other value of -moz-appearance (like window, tabpanels, etc) as the inherited styles are not customisable.

@samira-ranjbar

Hi, is there any way to remove the default select arrow in firefox and use our image? I have put these two code, but still doesn't work.
-moz-appearance: none;
-webkit-appearance: none;
thanks

@sanarena

I have used suggestion from barnettjw and it works on Firefox 30

@anupjon

Here is a work around

<div class="selectwrap">
      <select>
        <option>Option 1</option>
        <option>Option 1</option>
        <option>Option 1</option>
      </select>
</div>
select{
border:1px solid #ccc;
height: 34px;
width: 250px;
padding: 6px 12px;
}
.selectwrap{
position: relative;
float: left;
}
.selectwrap:after{
content:"";
text-align: center;
line-height:32px;
position: absolute;
width: 32px;
height: 32px;
background: #fff;
right: 1px;
top: 1px;
pointer-events: none;
}

http://codepen.io/anoopjohn/pen/GcJoL

@keksa

Hi, I managed to find way to hide select arrow in Firefox 31.0 (beta), I actually don't really know how it works, but it works. Here is pen: http://codepen.io/keksa/pen/hpqyx

@joaocunha
Owner

Nice finding, @keksa!

@nathankc

@aj9666 code works for me - the only thing I did different was modified:

content: " "; //didn't want the arrow at all
color: #fff; //ensure there is no character visible

@marcospita

Hi.
Do someone found a way not including div?

@iamalfonse

Unfortuantely with @keska's fix, you can't apply padding or margins to the actual <select> tag else the arrow will show up again.

@Rodrigo-Ludgero

Hi,
if you are interested, my solution is using vendor pseudo class :-moz-any() and pointer events only for mozilla because both is valid since version 3.6.

here is a jsbin example
http://jsbin.com/pozomu/4/edit

@kwarkjes

Rodrigo-Ludgero's solution works also

@sstur

@iamalfonse: I was able to sort of emulate border and padding in @keska's solution by using inset box-shadow for border and color: transparent with an offset text-shadow for padding. See: http://jsfiddle.net/sstur/2EZ9f/

@VR51

@anupjon's solution worked for me.

@Matt633

@joaocunha - Just used your URL prefix method to hide my custom arrow in FF33. Thanks a ton.

@vienhoang

This issue is quite annoying, tested a couple hacks from here and there, but @anupjon's solution works for me as well in Win 7, FF32.
However I haven't figured out to make it appear as a working cursor, "cursor: pointer;" doesn't seems to work with "pointer-events: none;". If anyone figured that out let me know :)

@iLenElFuerte

This solution is elegant ;)

@-moz-document url-prefix() {
 select {
    overflow:hidden; /* optional */
    width: 120%;
 }
}
@Martskin

Short option labels (like numbers 1, 2, 3...) were causing the select arrow to peak out with width: 120% for me.
This seems to be more flexible:

@-moz-document url-prefix() {
 select {
   width: calc(100% + 16px);
 }
}
@rdebeasi

-moz-appearance: none; will support select elements in Firefox 35. That version comes out in January, and the Developer Edition has this feature now. Here's the Bugzilla ticket.

Edit: Whoops, just realized that the content at the top of the gist already explains that. Sorry for the extra comment!

@lagden

Well, well!!!

The solution is very near of us... maybe in next Firefox release!!!
I made a workaround in the meantime:

Tested on Chrome 39, Safari 8 and FF 33 and FF 35 Developer Edition

:beers:

@seleckis

Solution does not work if border: 0.
FF 33.1, Win7

@l4ci

A modified combination of @Martskin and @iLenElFuerte comment worked best for me, as overflow: hidden would break the layout for me:

@-moz-document url-prefix() {
   select{
        overflow: -moz-hidden-unscrollable;
        width: calc(100% + 16px);
    }
}
@gijsroge

Use this codepen if you want to support firefox: http://codepen.io/gijs/pen/MYKreR
It uses pseudo child's to hide the down arrows. (firefox, ie10+, chrome, safari, etc..)

@MPMoughan

@anupjon FTW!!! Thanks for posting that solution it worked for me. Just need to adjust to account for screen breaks.

UPDATE - If you are following @anupjon 's solution, just be aware of the float: left; set on the "selectwrap" div - It will cause a slight issue with various breakpoints.

@webdev20

Too much words...

It should be formatted like this for faster and better reading!
-- code example with few names --
-- very long explanation goes after all of the primary codes --

anyway, thank you for sharing... :blush:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.