173

I'm trying to style a select element using CSS3. I'm getting the results I desire in WebKit (Chrome / Safari), but Firefox isn't playing nicely (I'm not even bothering with IE). I'm using the CSS3 appearance property, but for some reason I can't shake the drop-down icon out of Firefox.

Here's an example of what I'm doing: http://jsbin.com/aniyu4/2/edit

#dropdown {
 -moz-appearance: none;
 -webkit-appearance: none;
 appearance: none;
 background: transparent url('example.png') no-repeat right center;
 padding: 2px 30px 2px 2px;
 border: none;
}

As you can see, I'm not trying for anything fancy. I just want to remove the default styles and add in my own drop-down arrow. Like I said, great in WebKit, not great in Firefox. Apparently, the -moz-appearance: none doesn't get rid of the drop-down item.

Any ideas? No, JavaScript is not an option

John
  • 1
  • 13
  • 98
  • 177
RussellUresti
  • 6,211
  • 4
  • 28
  • 26
  • 3
    There is a bug report about this now: https://bugzilla.mozilla.org/show_bug.cgi?id=649849 – sneilan Jul 25 '11 at 21:07
  • 3
    [Chosen](http://harvesthq.github.com/chosen/) is a JavaScript library that styles your selects for you and makes them look really fancy. Might be worth looking into although it probably won't solve your problem. – stephenmurdoch Aug 02 '11 at 09:33
  • You might find this blog post useful: http://red-team-design.com/making-html-dropdowns-not-suck/ – Rui Marques Dec 12 '14 at 19:52
  • 1
    Looks like they've added the `-moz-appearance` CSS3 property, I'm using `-moz-appearance: none;` and it appears to be working in version 35.0.1. – Tony M Feb 19 '15 at 16:45
  • A simple fix would be to make the select element wider than the container. And wrap a mozilla url-prefix so the options are only wider in firefox. `@-moz-document url-prefix() { select { width: 105%; overflow: hidden; } }` – Luke Femur Jun 16 '15 at 11:20

30 Answers30

165

Update: this was fixed in Firefox v35. See the full gist for details.


Just figured out how to remove the select arrow from Firefox. The trick is to use a mix of -prefix-appearance, text-indent and text-overflow. It is pure CSS and requires no extra markup.

select {
    -moz-appearance: none;
    text-indent: 0.01px;
    text-overflow: '';
}

Tested on Windows 8, Ubuntu and Mac, latest versions of Firefox.

Live example: http://jsfiddle.net/joaocunha/RUEbp/1/

More on the subject: https://gist.github.com/joaocunha/6273016

João Cunha
  • 3,776
  • 3
  • 22
  • 33
  • 1
    I have a special place in my usually cold heart for hacky fixes like this. It's rather brilliant. The only downside is that FF leaves a space at the end of the dropdown text area (between the actual text and the end of the select box), which creates an inconsistent spacing between FF and the other browsers, but that's only a minor quibble. Nice find. – RussellUresti Aug 20 '13 at 19:02
  • Nice catch, @RussellUresti. But considering the whole idea might be to provide a modified arrow, the space actually proves itself useful. I played a bit with it, and adding `padding-right:10px;` to the ` – João Cunha Aug 21 '13 at 17:21
  • I added an bit of a crossbrowser (haven't tested in old versions of IE) as an answer so you can update yours – Daniël Tulp Nov 27 '13 at 09:42
  • 2
    Best solution for me, as `-moz-appearence: window` doesn't work with transparent backgrounds (draw an ugly bg in place, at least on firefox linux) – kik Dec 13 '13 at 15:44
  • Because this removes the arrow altogether, the resulting – thom_nic Jun 10 '14 at 18:56
  • But it's not ideal, @Foreever. It inherits a lot of default styles from the "statusbar" appearance and you can't override them. – João Cunha Jun 17 '14 at 07:55
  • @JoãoCunha Thank you for notifying me. I removed my comment. – Foreever Jun 17 '14 at 08:19
79

Okay, I know this question is old, but 2 years down the track and mozilla have done nothing.

I've come up with a simple workaround.

This essentially strips all formatting of the select box in firefox and wraps a span element around the select box with your custom style, but should only apply to firefox.

Say this is your select menu:

<select class='css-select'>
  <option value='1'> First option </option>
  <option value='2'> Second option </option>
</select>

And lets assume the css class 'css-select' is:

.css-select {
   background-image: url('images/select_arrow.gif');
   background-repeat: no-repeat;
   background-position: right center;
   padding-right: 20px;
}

In firefox, this would display with the select menu, followed by the ugly firefox select arrow, followed by your nice custom looking one. Not ideal.

Now to get this going in firefox, add a span element around with the class 'css-select-moz':

   <span class='css-select-moz'>
     <select class='css-select'>
       <option value='1'> First option </option>
       <option value='2'> Second option </option>
     </select>
   </span>

Then fix the CSS to hide mozilla's dirty arrow with -moz-appearance:window and throw the custom arrow into the span's class 'css-select-moz', but only get it to display on mozilla, like this:

.css-select {
   -moz-appearance:window;
   background-image: url('images/select_arrow.gif');
   background-repeat: no-repeat;
   background-position: right center;
   padding-right: 20px;
}

@-moz-document url-prefix() {
.css-select-moz{
     background-image: url('images/select_arrow.gif');
     background-repeat: no-repeat;
     background-position: right center;
     padding-right: 20px;
  }
} 

Pretty cool for only stumbling across this bug 3 hours ago (I'm new to webdesign and completely self-taught). However, this community has indirectly provided me with so much help, I thought it was about time I give something back.

I have only tested it in firefox (mac) version 18, and then 22 (after I updated).

All feedback is welcome.

Jordan Young
  • 924
  • 7
  • 4
  • 2
    And after 2 years, this is the best answer that's been posted to achieve my desired result. I've put a JSBin of the code here: http://jsbin.com/aniyu4/2440/edit for others to view, and made only 1 minor CSS update. The span was wider than the select in FF, due to the right padding - this meant clicking the arrow didn't activate dropdown. To adjust for this, I've put a negative right margin on the select element to pull the width of the span back in, to overlap the width of the select. – RussellUresti Jul 18 '13 at 18:18
  • 5
    Didn't work for me on FF 23-24 in Windows (I tried the jsbin in the comment). Ended up using tis workaround http://stackoverflow.com/questions/6787667/what-is-the-correct-moz-appearance-value-to-hide-dropdown-arrow-of-a-select#answer-18327666 – Esteban Sep 20 '13 at 10:35
  • A message for the future: while this is the accepted answer, also check out the higher-scoring one from João Cunha, below – Steve Jalim Mar 04 '14 at 12:42
  • 4
    It doesn't work on FF 30 anymore. Please go ahead and submit a ticket on Mozilla's website: https://bugzilla.mozilla.org/show_bug.cgi?id=649849. The more people complain about it, the better chance we have of them fixing it. – Stan Jul 04 '14 at 18:38
  • 1
    Works on FF 31 on Mac only. – Erwin Wessels Aug 12 '14 at 05:42
  • Dang – yep, worked for the latest Firefox (v 33) on OS X but not (v 34) on Windows. – Joel Farris Dec 05 '14 at 23:19
  • This is a great answer so +1 for the time. But the next answer works for v36+ as of today. Thanks for the info however! – Cayce K May 20 '15 at 00:57
  • this somehow messes up the rendering on other browsers for me. I added this to my style sheet but since then all styles after that point are "ignored" by Opera, Safari and IE. – Kolja Aug 30 '15 at 01:39
  • how can i remove the white backround from the arrow(in mozilla) and not the entire arrow – Faizal Hussain Jun 28 '18 at 07:36
59

The trick that works for me is to make select width more than 100% and apply overflow:hidden

select {
    overflow:hidden;
    width: 120%;
}

This is the only way right now to hide dropdown arrow in FF.

BTW. if you want beautiful dropdowns use http://harvesthq.github.com/chosen/

opengrid
  • 1,942
  • 4
  • 16
  • 25
27

Important Update:

As of Firefox V35 the appearance property now works !!

From firefox's official release notes on V35:

Using -moz-appearance with the none value on a combobox now remove the dropdown button (bug 649849).

So now in order to hide the default arrow - it's as easy as adding the following rules on our select element:

select {
   -webkit-appearance: none;
   -moz-appearance: none;
   appearance: none;
}

DEMO

select {
  margin: 50px;
  border: 1px solid #111;
  background: transparent;
  width: 150px;
  padding: 5px;
  font-size: 16px;
  border: 1px solid #ccc;
  height: 34px;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
}
<select>
  <option>Apples</option>
  <option selected>Pineapples</option>
  <option>Chocklate</option>
  <option>Pancakes</option>
</select>
Danield
  • 121,619
  • 37
  • 226
  • 255
20

We've found a simple and decent way to do this. It's cross-browser,degradable, and doesn't break a form post. First set the select box's opacity to 0.

.select { 
    opacity : 0;
    width: 200px;
    height: 15px;
}

<select class='select'>
    <option value='foo'>bar</option>    
</select>

this is so you can still click on it

Then make div with the same dimensions as the select box. The div should lay under the select box as the background. Use { position: absolute } and z-index to achieve this.

.div {
    width: 200px;
    height: 15px;
    position: absolute;
    z-index: 0;
}

<div class='.div'>{the text of the the current selection updated by javascript}</div>
<select class='select'>
    <option value='foo'>bar</option>    
</select>

Update the div's innerHTML with javascript. Easypeasy with jQuery:

$('.select').click(function(event)) { 
    $('.div').html($('.select option:selected').val());
}

That's it! Just style your div instead of the select box. I haven't tested the above code so you'll probably need tweak it. But hopefully you get the gist.

I think this solution beats {-webkit-appearance: none;}. What browsers should do at the very most is dictate interaction with form elements, but definitely not how their initially displayed on the page as that breaks site design.

Igor Ivancha
  • 3,413
  • 4
  • 30
  • 39
Shaun
  • 311
  • 3
  • 5
  • 6
    It's not a bad solution, and is similar to a pattern I've seen for styling the file upload input element, but there are several disadvantages. First, it relies on JS, which isn't ideal. Second, if the form has a reset button, you then have to script that functionality in as well (right now, the JS only listens to the click for the select element, but doesn't respond to a form.reset event). Replacing the select element with a div will work, but, ideally, we could just style the appearance of form elements. There are also accessibility issues concerned with both JS and default form behavior. – RussellUresti Mar 11 '12 at 23:22
14

Try this way:

-webkit-appearance: button;
-moz-appearance: button;

Then, you can use a different image as background and place it:

background-image: url(images/select-arrow.png);
background-position: center right;
background-repeat: no-repeat;

There is another way for moz browsers:

text-indent:10px;

If you have a defined a width to you select, this property will push the default dropbox button under the select area.

It works for me! ;)

ninja_corp
  • 448
  • 4
  • 5
6

While not a complete solution I've found that…

-moz-appearance: window;

…works to some extent. You can't change the background (-color or -image) but the element can be rendered invisible with color: transparent. Not perfect but it's a start and you don't need to replace the system level element with a js one.

  • Yeah, I noticed that `window` had that effect, unfortunately, I needed to set the background image. It's unfortunate that this isn't very good in Firefox. – RussellUresti Jun 06 '11 at 17:40
  • It is unfortunate that you can't apply a full reset to form elements yeah. You could always fake the background by having an element beneath the – Stuart Badminton Jun 07 '11 at 10:37
  • 1
    This is *PERFECT* for printing! Just set a `media="print"` css block with `select {-moz-appearance: window;}` and will remove arrows and backgrounds of all selects on FF (for other browsers try appearance or -webkit-appearance) so they look like plain text or titles – FrancescoMM Mar 22 '13 at 15:12
4

I think I found the solution compatible with FF31!!!
Here are two options that are well explained at this link:
http://www.currelis.com/hiding-select-arrow-firefox-30.html

I used option 1: Rodrigo-Ludgero posted this fix on Github, including an online demo. I tested this demo on Firefox 31.0 and it appears to be working correctly. Tested on Chrome and IE as well. Here is the html code:

<!DOCTYPE html>
<html>
    <head>
    <meta charset="utf-8">
    <title>Custom Select</title>
    <link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
        <div class="custom-select fa-caret-down">
            <select name="" id="">
                <option value="">Custom Select</option>
                <option value="">Custom Select</option>
                <option value="">Custom Select</option>
            </select>
        </div>
    </body>
</html>

and the css:

.custom-select {
    background-color: #fff;
    border: 1px solid #ccc;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    margin: 0 0 2em;
    padding: 0;
    position: relative;
    width: 100%;
    z-index: 1;
}

.custom-select:hover {
    border-color: #999;
}

.custom-select:before {
    color: #333;
    display: block;
    font-family: 'FontAwesome';
    font-size: 1em;
    height: 100%;
    line-height: 2.5em;
    padding: 0 0.625em;
    position: absolute;
    top: 0;
    right: 0;
    text-align: center;
    width: 1em;
    z-index: -1;
}

.custom-select select {
    background-color: transparent;
    border: 0 none;
    box-shadow: none;
    color: #333;
    display: block;
    font-size: 100%;
    line-height: normal;
    margin: 0;
    padding: .5em;
    width: 100%;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}

.custom-select select::-ms-expand {
    display: none; /* to ie 10 */
}

.custom-select select:focus {
    outline: none;
}
/* little trick for custom select elements in mozilla firefox  17/06/2014 @rodrigoludgero */
:-moz-any(.custom-select):before {
    background-color: #fff; /* this is necessary for overcome the caret default browser */
    pointer-events: none; 
    z-index: 1; /* this is necessary for overcome the pseudo element */
}

http://jsbin.com/pozomu/4/edit

It works very good for me!

ferocesalatino
  • 126
  • 1
  • 9
  • 2
    Links to external resources are encouraged, but please add context around the link so your fellow users will have some idea what it is and why it’s there. Always quote the most relevant part of an important link, in case the target site is unreachable or goes permanently offline. – Andrew Stubbs Jul 23 '14 at 08:43
  • Thank you for suggests! Sorry for my faults! – ferocesalatino Jul 23 '14 at 09:52
  • Thanks for editing your question, however it still doesn't actually answer the question *by itself*. Please copy the parts of those links that will help the questioner such that they would be able to solve their problem just be reading your Answer. – Andrew Stubbs Jul 23 '14 at 10:08
2
/* Try this in FF30+ Covers up the arrow, turns off the background */ 
/* still lets you style the border around the image and allows selection on the arrow */


@-moz-document url-prefix() {

    .yourClass select {
        text-overflow: '';
        text-indent: -1px;
        -moz-appearance: none;
        background: none;

    }

    /*fix for popup in FF30 */
    .yourClass:after {
        position: absolute;
        margin-left: -27px;
        height: 22px;
        border-top-right-radius: 6px;
        border-bottom-right-radius: 6px;
        content: url('../images/yourArrow.svg');
        pointer-events: none;
        overflow: hidden;
        border-right: 1px solid #yourBorderColour;
        border-top: 1px solid #yourBorderColour;
        border-bottom: 1px solid #yourBorderColour; 
    }
}
Todd Bruss
  • 21
  • 3
2

I am styling the select just likes this

<select style="     -moz-appearance: radio-container;
                -webkit-appearance: none;
                 appearance: none;
">

It works for me in FF, Safari and Chrome in all versions I've tested.

In IE I put:

 select::-ms-expand {
 display: none;
}
/*to remove in all selects*/

Also you can: .yourclass::-ms-expand {display: none; } .yourid::-ms-exapan {display: none; }

Alex Moleiro
  • 1,166
  • 11
  • 13
2

try this css

select {
    /*for firefox*/
    -moz-appearance: none;
    /*for chrome*/
    -webkit-appearance:none;
}

Its working

subindas pm
  • 2,668
  • 25
  • 18
2

Unfortunately for you this is "something fancy". Normally it's not the web authors place to redesign form elements. Many browsers purposely don't let you style them, in order for the user to see the OS controls they are used to.

The only way to do this consistently over browsers and operating systems, is use JavaScript and replace the select elements with "DHTML" ones.

Following article show three jQuery based plugins that allow you to do that (it is a bit old, but I couldn't find anything current right now)

http://www.queness.com/post/204/25-jquery-plugins-that-enhance-and-beautify-html-form-elements#1

RoToRa
  • 37,635
  • 12
  • 69
  • 105
  • 8
    I disagree that this is something fancy, though it is something that's experimental. The entire point of the `appearance` property is to give developers control over the appearance of form elements, because using JavaScript for that is a horrible solution. Browsers shouldn't make the decision about how anything looks in a page -- it's a UX decision, not a browser vendor decision. Unfortunately, it's just not well supported yet. Maybe in another year. – RussellUresti May 06 '11 at 15:53
  • I don't consider "fancy" if I want that when you print the page all the selects look like a field with no arrows. And that should be my choice, not the browser or the os choice. I have a select with months, and when the page is printed I have a special CSS for print that removes the arrow on the printed page so it looks just like a title "March" with no arrows that make no sense on a prited page. – FrancescoMM Mar 22 '13 at 15:08
1

Use the pointer-events property.

The idea here is to overlay an element over the native drop down arrow (to create our custom one) and then disallow pointer events on it. [see this post]

Here is a working FIDDLE using this method.

Also, in this SO answer I discussed this and another method in greater detail.

Community
  • 1
  • 1
Danield
  • 121,619
  • 37
  • 226
  • 255
1

This works (tested on Firefox 23.0.1):

select {
    -moz-appearance: radio-container;
}
User
  • 31,811
  • 40
  • 131
  • 232
  • Worked for me, but I didn't like `radio-container` value for a select object. Browse [-moz-appearance mozilla reference](https://developer.mozilla.org/fr/docs/Web/CSS/-moz-appearance) to get an appropriate value (I used `menulist-text` which hides the select's arrow in FF 31) – sglessard Aug 01 '14 at 15:23
1

building on the answer by @JoãoCunha, one css style that is usefull for more then one browser

select {
    /*for firefox*/
    -moz-appearance: none;
    /*for chrome*/
    -webkit-appearance:none;
    text-indent: 0.01px;
    text-overflow: '';
}
/*for IE10*/
select::-ms-expand {
    display: none;
}
Daniël Tulp
  • 1,745
  • 2
  • 22
  • 51
1

A lot of Discussions Happening here & there but I don't see some proper solution for this problem. Finally Ended up by writing a small Jquery + CSS code for doing this HACK on IE & Firefox.

Calculate Element Width (SELECT Element) using Jquery. Add a Wrapper Around Select Element and Keep overflow hidden for this element. Make sure that Width of this wrapper is appox. 25px less as that of SELECT Element. This could be easily done with Jquery. So Now Our Icon is Gone..! and it is time for adding our image icon on SELECT element...!!! Just add few simple lines for adding background and you are all Done..!! Make sure to use overflow hidden for outer wrapper,

Here is a Sample of Code which was done for Drupal. However could be used for others also by removing few lines of code which is Drupal Specific.

/*
 * Jquery Code for Removing Dropdown Arrow.
 * @by: North Web Studio
 */
(function($) {
  Drupal.behaviors.nwsJS = {
    attach: function(context, settings) {
      $('.form-select').once('nws-arrow', function() {
        $wrap_width = $(this).outerWidth();
        $element_width = $wrap_width + 20;
        $(this).css('width', $element_width);
        $(this).wrap('<div class="nws-select"></div>');
        $(this).parent('.nws-select').css('width', $wrap_width);
      });
    }
  };
})(jQuery);
/*
 * CSS Code for Removing Dropdown Arrow.
 * @by: North Web Studio
 */

.nws-select {
  border: 1px solid #ccc;
  overflow: hidden;
  background: url('../images/icon.png') no-repeat 95% 50%;
}
.nws-select .form-select {
  border: none;
  background: transparent;
}

Solution works on All Browsers IE, Chrome & Firefox No need of Adding fixed Widths Hacks Using CSS. It is all being handled Dynamically using JQuery.!

More Described at:- http://northwebstudio.com/blogs/1/jquery/remove-drop-down-arrow-html-select-element-using-jquery-and-css

Igor Ivancha
  • 3,413
  • 4
  • 30
  • 39
1

Further to Joao Cunha's answer, this problem is now on Mozilla's ToDo List and is targeted for ver 35.

For those desiring, here is a workaround by Todd Parker, referenced on Cunha's blog, that works today:

http://jsfiddle.net/xvushd7x/

HTML:

<label class="wrapper">This label wraps the select
    <div class="button custom-select ff-hack">
        <select>
            <option>Apples</option>
            <option>Bananas</option>
            <option>Grapes</option>
            <option>Oranges</option>
            <option>A very long option name to test wrapping</option>
        </select>
    </div>
</label>

CSS:

/* Label styles: style as needed */
label {
  display:block;
  margin-top:2em;
  font-size: 0.9em;
  color:#777;
}

/* Container used for styling the custom select, the buttom class below adds the bg gradient, corners, etc. */
.custom-select {
  position: relative;
  display:block;
  margin-top:0.5em;
  padding:0;
}

/* These are the "theme" styles for our button applied via separate button class, style as you like */
.button {
  border: 1px solid #bbb;
  border-radius: .3em;
  box-shadow: 0 1px 0 1px rgba(0,0,0,.04);
  background: #f3f3f3; /* Old browsers */
  background: -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 100%); /* FF3.6+ */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#e5e5e5)); /* Chrome,Safari4+ */
  background: -webkit-linear-gradient(top, #ffffff 0%,#e5e5e5 100%); /* Chrome10+,Safari5.1+ */
  background: -o-linear-gradient(top, #ffffff 0%,#e5e5e5 100%); /* Opera 11.10+ */
  background: -ms-linear-gradient(top, #ffffff 0%,#e5e5e5 100%); /* IE10+ */
  background: linear-gradient(to bottom, #ffffff 0%,#e5e5e5 100%); /* W3C */
}

/* This is the native select, we're making everything but the text invisible so we can see the button styles in the wrapper */
.custom-select select {
  width:100%;
  margin:0;
  background:none;
  border: 1px solid transparent;
  outline: none;
  /* Prefixed box-sizing rules necessary for older browsers */
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  /* Remove select styling */
  appearance: none;
  -webkit-appearance: none;
  /* Font size must the 16px or larger to prevent iOS page zoom on focus */
  font-size:16px;
  /* General select styles: change as needed */
  font-family: helvetica, sans-serif;
  font-weight: bold;
  color: #444;
  padding: .6em 1.9em .5em .8em;
  line-height:1.3;
}


/* Custom arrow sits on top of the select - could be an image, SVG, icon font, etc. or the arrow could just baked into the bg image on the select. Note this si a 2x image so it will look bad in browsers that don't support background-size. In production, you'd handle this resolution switch via media query but this is a demo. */

.custom-select::after {
  content: "";
  position: absolute;
  width: 9px;
  height: 8px;
  top: 50%;
  right: 1em;
  margin-top:-4px;
  background-image: url(http://filamentgroup.com/files/select-arrow.png);
  background-repeat: no-repeat;
  background-size: 100%;
  z-index: 2;
  /* These hacks make the select behind the arrow clickable in some browsers */
  pointer-events:none;
}


/* Hover style */
.custom-select:hover {
  border:1px solid #888;
}

/* Focus style */
.custom-select select:focus {
  outline:none;
  box-shadow: 0 0 1px 3px rgba(180,222,250, 1);
  background-color:transparent;
  color: #222;
  border:1px solid #aaa;
}

/* Set options to normal weight */
.custom-select option {
  font-weight:normal;
}
Community
  • 1
  • 1
crashwap
  • 2,846
  • 3
  • 28
  • 62
1

Since Firefox 35, "-moz-appearance:none" that you already wrote in your code, finally remove arrow button as desired.

It was a bug solved since that version.

Luca Detomi
  • 5,564
  • 7
  • 52
  • 77
1

I know this question is a bit old, but since it turns up on google, and this is a "new" solution:

appearance: normal Seems to work fine in Firefox for me (version 5 now). but not in Opera and IE8/9

As a workaround for Opera and IE9, I used the :before pseudoselector to create a new white box and put that on top of the arrow.

Unfortunately, In IE8 this doesn't work. The box is rendered correctly, but the arrow just sticks out anyway... :-/

Using select:before works fine in Opera, but not in IE. If I look at the developer tools, I see it is reading the rules correctly, and then just ignores them (they're crossed out). So I use a <span class="selectwrap"> around the actual <select>.

select {
  -webkit-appearance: normal;
  -moz-appearance: normal;
  appearance: normal;
}
.selectwrap { position: relative; }
.selectwrap:before {
  content: "";
  height: 0;
  width: 0;
  border: .9em solid red;
  background-color: red;
  position: absolute;
  right: -.1em;
  z-index: 42;
}

You may need to tweak this a bit, but this works for me!

Disclaimer: I'm using this to get a good looking hardcopy of a webpage with forms so I don't need to create a second page. I'm not a 1337 haxx0r who wants red scrollbars, <marquee> tags, and whatnot :-) Please do not apply excessive styling to forms unless you have a very good reason.

Martin Tournoij
  • 26,737
  • 24
  • 105
  • 146
  • 3
    `-moz-appearance: normal` doesn't seem to be a valid option in the Fx 9, and `-moz-appearance: none` (which is valid) doesn't remove the down arrow. – Robin Winslow Jan 25 '12 at 12:32
  • Your overlapping span solution works in IE and FF but doesn't work in Chrome. – vulcan raven Jun 09 '13 at 18:36
  • :before and :after pseudo-elements work only on elements that accept inner content. That's not the case of the select, nor the input, nor the fileuploader, etc. They are great for divs, links, paragraphs, etc. The reason for that is that they append the content not before/after THE ELEMENT itself but before IT'S CONTENT. And a select element doesn't support something like ` – João Cunha Aug 21 '13 at 19:47
0

Would you accept minor changes to the html?

Something like putting a div tag containing the select tag.

Take a look.

Galled
  • 4,146
  • 2
  • 28
  • 41
0

Or, you can clip the select. Something along the lines of:

select { width:200px; position:absolute; clip:rect(0, 170px, 50px, 0); }

This should clip 30px of the right side of select box, stripping away the arrow. Now supply a 170px background image and voila, styled select

0

It's a huge hack, but -moz-appearance: menulist-text might do the trick.

Anon
  • 1
  • This did seem to remove the select arrow for me, but as @dendini noted, it also removed all other styling on the element – codestr Sep 08 '16 at 19:43
0

A useful hack for me is to set the (selects) display to inline-flex. Cuts the arrow right out of my select button. Without all of the added code.

  • For Fx only. -webkit appearance still needed for Chrome, etc...
Volker E.
  • 5,911
  • 11
  • 47
  • 64
Andrew Ice
  • 831
  • 4
  • 16
0

I was having the same issue. It's easy to make it work on FF and Chrome, but on IE (8+ that we need to support) things get complicated. The easiest solution I could find for custom select elements that works "everywhere I tried", including IE8, is using .customSelect()

rafaelbiten
  • 6,074
  • 2
  • 31
  • 36
0

Jordan Young's answer is the best. But if you can't or don't want to change your HTML, you might consider just removing the custom down arrow served to Chrome, Safari, etc and leaving firefox's default arrow - but without double arrows resulting. Not ideal, but a good quick fix that doesn't add any HTML and doesn't compromise your custom look in other browsers.

<select>
  <option value='1'> First option </option>
  <option value='2'> Second option </option>
</select>

CSS:

select {
   background-image: url('images/select_arrow.gif');
   background-repeat: no-repeat;
   background-position: right center;
   padding-right: 20px;
}

@-moz-document url-prefix() {
  select {
    background-image: none;
  }
}
squarecandy
  • 4,894
  • 3
  • 34
  • 45
0

hackity hack ... a solution that works in every browser I've tested (Safari, Firefox, Chrome). Don't have any IEs lying around, so it would be nice if you could test and comment:

<div class="wrapper">
  <select>
    <option>123456789</option>
    <option>234567890</option>
  </select>
</div>

CSS, with url-encoded image:

.wrapper { position:relative; width:200px; }
.wrapper:after {
  content:"";
  display: block;
  position: absolute;
  top:1px; height:28px;
  right:1px; width:16px;
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAcCAYAAACH81QkAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowODgwMTE3NDA3MjA2ODExOEE2RENENTU2MTFGMEQ1RCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpGNDE5NDQ3Nzc5ODIxMUU0OEU0M0JFMzgzMkUxOTk3MiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpGNDE5NDQ3Njc5ODIxMUU0OEU0M0JFMzgzMkUxOTk3MiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2IChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDk4MDExNzQwNzIwNjgxMThBNkRDRDU1NjExRjBENUQiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDg4MDExNzQwNzIwNjgxMThBNkRDRDU1NjExRjBENUQiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4o7anbAAAAjklEQVR42uzUsQ3EIAwFUPty7MBOsAoVC7EVYgyUSFcdzn0iJYquAZGSLxnLzatsWERWGsvGP0QGkc+LxvN9AqGJTKQJMcYQM/+VtbZdiTGKUgr3cxbmlJI0ZiW83vsbgrkjB5JzFq11BdAxdyNICKEi6J25kFKKOOdq70We+JS2ufYTacjyxrKMLtsuwAAznzqGLHX9BwAAAABJRU5ErkJggg==);

  pointer-events: none;
}

select {
  width: 100%;
  padding:3px;
  margin: 0;
  border-radius: 0;
  border:1px solid black;
  outline:none;
  display: inline-block;
  -webkit-appearance:none;
  -moz-appearance:none;
  appearance:none;
  cursor:pointer;
  float:none!important;
  background:white;

  font-size:13px;
  line-height: 1em;
  height: 30px;
  padding:6px 20px 6px 10px;
}

http://codepen.io/anon/pen/myPEBy

I'm using the :after-element to cover the ugly arrow. Since select doesn't support :after, i need a wrapper to work with. Now, if you would click on the arrow, the dropdown won't register it ... unless your browser supports pointer-events: none, which everyone except IE10- does: http://caniuse.com/#feat=pointer-events

So for me it's perfect - a nice, clean, low-headache solution, at least compared to all the other options which include javascript.

tl;dr:

If IE10 (or lower) Users click the arrow, it won't work. Works good enough for me...

Sebastian Schmid
  • 589
  • 5
  • 10
0

If you don't mind fiddling with JS, I wrote a small jQuery plugin that helps you do it. With it you don't need to worry about vendor prefixes.

 $.fn.magicSelectBox = function() {
  var $e = this;

  $e.each(function() {
    var $select = $(this);

    var $magicbox = $('<div></div>').attr('class', $select.attr('class')).attr('style', $select.attr('style')).addClass('magicbox');
    var $innermagicbox = $('<div></div>').css({
      position: 'relative',
      height: '100%'
    });
    var $text = $('<span></span>').css({
      position: 'absolute'
    }).text($select.find("option:selected").text());

    $select.attr('class', null).css({
      width: '100%',
      height: '100%',
      opacity: 0,
      position: 'absolute'
    }).on('change', function() {
      $text.text($select.find("option:selected").text());
    });

    $select.parent().append($magicbox);
    $innermagicbox.append($text, $select);
    $magicbox.append($innermagicbox);
  });

  return $e;
};

Fiddle here: JS Fiddle

The condition is that you have to style the select from scratch (this means setting the background and border), but you probably want to do this anyway.

Also since the function substitutes the original select with a div, you will lose any styling done directly on the select selector in your CSS. So give the select element a class and style the class.

Supports most modern browsers, if you want to target older browsers, you can try an older version of jQuery, but perhaps have to replace on() with bind() in the function (not tested)

Hydde87
  • 689
  • 6
  • 6
0

The appearance property from CSS3 does not allow none value. Take a look at the W3C reference. So, what you is trying to do isn't valid (indeed Chrome shouldn't accept too).

Then unfortunatelly we really don't have any cross-browser solution to hide that arrow using pure CSS. As pointed, you will need JavaScript.

I suggest you to consider using selectBox jQuery plugin. It's very lightweight and nicely done.

Erick Petrucelli
  • 14,386
  • 8
  • 64
  • 84
  • 1
    But `none` IS a value that Firefox claims to support: https://developer.mozilla.org/en/CSS/-moz-appearance While styling form elements, in the past, has been only accomplishable through JavaScript, the entire point of the `appearance` property is to move away from that. Browser vendors shouldn't be making UX decisions for developers. Unfortunately, it just seems that this is still a little too new to use effectively. – RussellUresti May 06 '11 at 15:45
  • 1
    @RussellUresti, therefore even though the description from vendor prefix `-moz` accepts `none` (even if that worked) would not be correct to use it. Even more regarding a browser like Firefox, which has always boasted itself by exactly following the standards. – Erick Petrucelli May 06 '11 at 17:30
0

You could increase the width of the box and move the arrow closer to the left of the arrow. this then allows you to cover the arrow with an empty white div.

Have a look: http://jsbin.com/aniyu4/86/edit

mynameisnotallowed
  • 564
  • 1
  • 11
  • 34
-2

The other answers didn't seem to work for me, but I found this hack. This worked for me (July 2014)

select {
-moz-appearance: textfield !important;
    }

In my case, I also had a woocommerce input field so I used this

.woocommerce .quantity input.qty {
-moz-appearance: textfield !important;
 }

Updated my answer to show select rather than input

SolaceBeforeDawn
  • 958
  • 1
  • 8
  • 16