In modern browsers it's relatively painless to style the <select>
in CSS. With appearance: none
the only tricky part is replacing the arrow (if that's what you want). Here's a solution that uses an inline data:
URI with plain-text SVG:
select {_x000D_
-moz-appearance: none;_x000D_
-webkit-appearance: none;_x000D_
appearance: none;_x000D_
_x000D_
background-repeat: no-repeat;_x000D_
background-size: 0.5em auto;_x000D_
background-position: right 0.25em center;_x000D_
padding-right: 1em;_x000D_
_x000D_
background-image: url("data:image/svg+xml;charset=utf-8, \_x000D_
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 40'> \_x000D_
<polygon points='0,0 60,0 30,40' style='fill:black;'/> \_x000D_
</svg>");_x000D_
}
_x000D_
<select>_x000D_
<option>Option 1</option>_x000D_
<option>Option 2</option>_x000D_
</select>_x000D_
_x000D_
<select style="font-size: 2rem;">_x000D_
<option>Option 1</option>_x000D_
<option>Option 2</option>_x000D_
</select>
_x000D_
The rest of the styling (borders, padding, colors, etc.) is fairly straightforward.
This works in all the browsers I just tried (Firefox 50, Chrome 55, Edge 38, and Safari 10). One note about Firefox is that if you want to use the #
character in the data URI (e.g. fill: #000
) you need to escape it (fill: %23000
).