Reputation: 34632
A default select input looks like this in FF 37:
When I try to give it a different border color like this:
select { border: 1px solid silver; }
It results into this:
For some reason when you give a select input a different border it also adds a background and border to the arrow button.
A similar thing happens when I do the following:
select { background: transparent; }
It ends up like this:
Why is this happening and how can I just change the border or background of a select input without it changing the arrow down button?
Upvotes: 5
Views: 11720
Reputation: 563
To remove this problem just set a border.
select {
border:1px solid black;
}
Upvotes: 0
Reputation: 6783
Answer given by Damian is not bad, but I prefered something what is easier to maintain. Basically, I also need to have a possibility to prepare one style, which I could change a color depending on theme, therefore png image (in base64) was not a good option.
This is how this can be done with SVG:
select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
/* SVG background image */
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='%23FF0000'><polygon points='20,0 80,0 50,52'/></svg>");
background-size: 12px;
background-position-x: right;
background-position-y: calc(100% - 10px);
background-repeat: no-repeat;
}
I use scss to generate styles based on variables, so i wanted to use $base-font-color
as a color of triangle. The problem was encoding.
Chrome can handle simple .. fill='"+ $base-font-color +"' ..
in:
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='"+ $base-font-color +"'><polygon points='20,0 80,0 50,52'/></svg>");
but firefox needed %23
. That was a problem, bacause I store colors in variables as: $base-font-color: #3e4f5e;
and not as a $base-font-color: '3e4f5e'
. Solution was to convert color to string and use string replacement to replace '#' to '%23'
@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
@function to-string($value) {
@return inspect($value);
}
select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
/* SVG background image */
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='"+ str-replace(to-string($base-font-color), '#', '%23') +"'><polygon points='20,0 80,0 50,52'/></svg>");
background-size: 12px;
background-position-x: right;
background-position-y: calc(100% - 10px);
background-repeat: no-repeat;
}
Upvotes: 0
Reputation: 86
To start with, styling form elements is extremely complicated and troublesome. Some progress has been made lately, but behaviour is inconsistent from browser to browser. The problem comes from the way browser have historically handled form elements (letting the OS decide the element appearance).
Now to your question: for some reason, whenever you modify FF default stylesheet, the browser applies a different style to the dropdown (this may be a bug, a bad implementation or planned behaviour, but it's clearly annoying).
One solution would be to get rid of all the "chrome" altogether, using a vendor property -x-appearance: none
, like this:
select {
border: 1px solid silver;
-webkit-appearance: none;
-moz-appearance: none;
padding-right: 25px;
background: url(data:image/gif;base64,R0lGODlhCwALAJEAAAAAAP///xUVFf///yH5BAEAAAMALAAAAAALAAsAAAIPnI+py+0/hJzz0IruwjsVADs=);
background-repeat: no-repeat;
background-position: 95% 42%;
}
Note that you have to re-apply the down arrow (I did this by inserting an image as a background, encoded in base64.) You can use any image of your liking.
The problem with this approach is that it doesn't work in IE: http://caniuse.com/#search=appearance
Here you have a Fiddle to test it: https://jsfiddle.net/81L844p4/4/
Hope it helps.
Upvotes: 7