是否有CSS唯一的方式来设置<select>下拉列表的样式?

我需要尽可能人性化地设置<select>表单的样式,而不需要任何JavaScript。在CSS中,我可以使用哪些财产来执行此操作?

此代码需要与所有主要浏览器兼容:

Internet Explorer 6、7和8Firefox浏览器游猎

我知道我可以用JavaScript实现:示例。

我说的不是简单的造型。我想知道,我们只能用CSS做什么。

我在Stack Overflow上发现了类似的问题。

还有Doctype.com上的这个。


当前回答

本机解决方案

下面是一个简单的HTML/CSS示例:https://jsfiddle.net/dkellner/e1jdspvb/

诀窍:由于某种原因,当你给select标记一个size属性时,它会突然理解CSS。通常,此属性用于创建始终可见的固定高度列表,但作为一个副作用,您现在可以对其进行样式设置。因此,我们所做的只是给它一个大小,然后实现显示/隐藏机制,以返回下拉列表的感觉。

简约版,不像示例那样时尚,但更容易理解:

<style>

    .stylish > span {position:relative;}
    .stylish select {position:absolute;left:0px;transform:scaleY(0);transform-origin:top center;}
    .stylish.dropped-down select {transform:scaleY(1);}

</style>
...
<div class="stylish">
    <label> Choose your superhero: </label>
    <span>
        <input   onclick  = "this.closest('div').classList.toggle('dropped-down');"><br>
        <select  onclick  = "this.closest('div').classList.remove('dropped-down');"
                 onchange = "this.closest('div').querySelector('input').value=this.value;"
                 size=9
        >
            <optgroup label="Fantasy"></optgroup>

            <option value="gandalf">  Gandalf       </option>
            <option value="harry">    Harry Potter  </option>
            <option value="jon">      Jon Snow      </option>

            ...                
            
        </select>
    </span>
</div>

附加说明

这实际上实现了一个可编辑的下拉列表;使用只读以避免编辑<optgroup>标记是空的(不是围绕选项标记),这样更具风格

其他回答

label {
    position: relative;
    display: inline-block;
}
select {
    display: inline-block;
    padding: 4px 3px 5px 5px;
    width: 150px;
    outline: none;
    color: black;
    border: 1px solid #C8BFC4;
    border-radius: 4px;
    box-shadow: inset 1px 1px 2px #ddd8dc;
    background-color: lightblue;
}

这对选定的元素使用了背景色,我删除了图像。。

从InternetExplorer10开始,您可以使用::-ms-expand伪元素选择器来样式和隐藏下拉箭头元素。

select::-ms-expand {
    display:none;
    /* or visibility: hidden; to keep it's space/hitbox */
}

其余的样式应该与其他浏览器类似。

下面是Danield的jsfiddle的一个基本分支,它应用了对IE10的支持

在现代浏览器中,在CSS中设置<select>的样式相对轻松。外观方面:唯一棘手的部分是替换箭头(如果你想要的话)。下面是一个使用内联data:URI和纯文本SVG的解决方案:

选择{-moz外观:无;-webkit外观:无;外观:无;背景重复:无重复;背景尺寸:0.5em自动;背景位置:右0.25em中心;右侧填充:1em;backgroundimage:url(“data:image/svg+xml;charset=utf-8\<svg xmlns='http://www.w3.org/2000/svg'viewBox='0 0 60 40'>\<多边形点=',0 60,0 30,40'style='fill:black;'/>\</svg>“);}<选择><option>选项1</option><option>选项2</option></选择><select style=“font-size:2rem;”><option>选项1</option><option>选项2</option></选择>

其余的样式(边框、填充、颜色等)相当简单。

这适用于我刚刚尝试过的所有浏览器(Firefox 50、Chrome 55、Edge 38和Safari 10)。关于Firefox的一个注意事项是,如果你想在数据URI中使用#字符(例如,fill:#000),你需要转义它(fill:%23000)。

以下是三种解决方案:

解决方案#1-外观:无-使用Internet Explorer 10-11解决方案(演示)

--

要隐藏默认箭头集外观,请在select元素上选择none,然后添加带有背景图像的自定义箭头

select {
   -webkit-appearance: none;
   -moz-appearance: none;
   appearance: none;       /* Remove default arrow */
   background-image: url(...);   /* Add custom arrow */
}

浏览器支持:

外观:除了Internet Explorer,没有一个浏览器支持非常好(caniuse)。

我们可以通过添加

select::-ms-expand {
    display: none; /* Hide the default arrow in Internet Explorer 10 and Internet Explorer 11 */
}

如果Internet Explorer 9是一个问题,我们没有办法删除默认箭头(这意味着我们现在有两个箭头),但是,我们可以使用一个时髦的Internet Explorer 9选择器。

至少撤销我们的自定义箭头-保留默认的选择箭头不变。

/* Target Internet Explorer 9 to undo the custom arrow */
@media screen and (min-width:0\0) {
    select {
        background-image:none\9;
        padding: 5px\9;
    }
}

所有这些:

选择{边距:50px;宽度:150px;填充:5px 35px 5px 5px;字体大小:16px;边框:1px实心#CCC;高度:34px;-webkit外观:无;-moz外观:无;外观:无;背景:url(https://stackoverflow.com/favicon.ico)96%/15%无重复#EEE;}/*警告:Internet Explorer黑客攻击*/select::-ms扩展{显示:无;/*删除Internet Explorer 10和11中的默认箭头*/}/*以Internet Explorer 9为目标撤消自定义箭头*/@媒体屏幕和(最小宽度:0\0){选择{背景:无\9;填充:5px \9;}}<选择><option>苹果</option><option selected>菠萝</option><option>楔板</option><option>煎饼</option></选择>

这个解决方案很简单,并且具有良好的浏览器支持——通常应该足够了。


如果需要Internet Explorer的浏览器支持,请提前阅读。

解决方案#2截断select元素以隐藏默认箭头(演示)

--

(在此处阅读更多信息)

用固定宽度和溢出:hidden将select元素包装在div中。

然后给select元素的宽度比div。

结果是select元素的默认下拉箭头将被隐藏(由于溢出:隐藏在容器上),您可以在div的右侧放置任何需要的背景图像。

这种方法的优点是它是跨浏览器的(Internet Explorer 8和更高版本、WebKit和Gecko)。然而,这种方法的缺点是选项下拉列表在右侧突出(我们隐藏了20个像素……因为选项元素占用了选择元素的宽度)。

[然而,需要注意的是,如果自定义选择元素仅对移动设备是必要的,那么上述问题就不适用了,因为每个手机都是以本地方式打开选择元素的。因此,对于移动设备来说,这可能是最佳解决方案。]

.styled选择{背景:透明;宽度:150px;字体大小:16px;边框:1px实心#CCC;高度:34px;}.样式{边距:50px;宽度:120px;高度:34px;边框:1px实心#111;边界半径:3px;溢出:隐藏;背景:url(https://stackoverflow.com/favicon.ico)96%/20%无重复#EEE;}<div class=“styled”><选择><option>菠萝</option><option selected>苹果</option><option>楔板</option><option>煎饼</option></选择></div>


If the custom arrow is necessary on Firefox - prior to Version 35 - but you don't need to support old versions of Internet Explorer - then keep reading...

Solution #3 - Use the pointer-events property (demo)

--

(Read more here)

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.

Advantage: It works well in WebKit and Gecko. It looks good too (no jutting out option elements).

Disadvantage: Internet Explorer (Internet Explorer 10 and down) doesn't support pointer-events, which means you can't click the custom arrow. Also, another (obvious) disadvantage with this method is that you can't target your new arrow image with a hover effect or hand cursor, because we have just disabled pointer events on them!

However, with this method you can use Modernizer or conditional comments to make Internet Explorer revert to the standard built in arrow.

NB: Being that Internet Explorer 10 doesn't support conditional comments anymore: If you want to use this approach, you should probably use Modernizr. However, it is still possible to exclude the pointer-events CSS from Internet Explorer 10 with a CSS hack described here.

.notIE {
  position: relative;
  display: inline-block;
}
select {
  display: inline-block;
  height: 30px;
  width: 150px;
  outline: none;
  color: #74646E;
  border: 1px solid #C8BFC4;
  border-radius: 4px;
  box-shadow: inset 1px 1px 2px #DDD8DC;
  background: #FFF;
}
/* Select arrow styling */

.notIE .fancyArrow {
  width: 23px;
  height: 28px;
  position: absolute;
  display: inline-block;
  top: 1px;
  right: 3px;
  background: url(https://stackoverflow.com/favicon.ico) right / 90% no-repeat #FFF;
  pointer-events: none;
}
/*target Internet Explorer 9 and Internet Explorer 10:*/

@media screen and (min-width: 0\0) {
  .notIE .fancyArrow {
    display: none;
  }
}
<!--[if !IE]> -->
<div class="notIE">
  <!-- <![endif]-->
  <span class="fancyArrow"></span>
  <select>
    <option>Apples</option>
    <option selected>Pineapples</option>
    <option>Chocklate</option>
    <option>Pancakes</option>
  </select>
  <!--[if !IE]> -->
</div>
<!-- <![endif]-->

select元素及其下拉功能很难设置样式。

Chris Heilmann的select元素的风格属性证实了Ryan Dohery对第一个答案的评论:

“select元素是操作系统,而不是浏览器chrome。因此风格不可靠,尝试也不一定有意义无论如何"