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

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

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

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

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

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

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

还有Doctype.com上的这个。


当前回答

这是可能的,但不幸的是,根据开发人员的要求,大多数情况下都是基于WebKit的浏览器。以下是通过内置开发人员工具检查器从Chrome选项面板收集的CSS样式示例,该检查器经过改进以匹配大多数现代浏览器中当前支持的CSS财产:

select {
  -webkit-appearance: button;
  -moz-appearance: button;
  -webkit-user-select: none;
  -moz-user-select: none;
  -webkit-padding-end: 20px;
  -moz-padding-end: 20px;
  -webkit-padding-start: 2px;
  -moz-padding-start: 2px;
  background-color: #F07575; /* Fallback color if gradients are not supported */
  background-image: url(../images/select-arrow.png), -webkit-linear-gradient(top, #E5E5E5, #F4F4F4); /* For Chrome and Safari */
  background-image: url(../images/select-arrow.png), -moz-linear-gradient(top, #E5E5E5, #F4F4F4); /* For old Firefox (3.6 to 15) */
  background-image: url(../images/select-arrow.png), -ms-linear-gradient(top, #E5E5E5, #F4F4F4); /* For pre-releases of Internet Explorer  10*/
  background-image: url(../images/select-arrow.png), -o-linear-gradient(top, #E5E5E5, #F4F4F4); /* For old Opera (11.1 to 12.0) */
  background-image: url(../images/select-arrow.png), linear-gradient(to bottom, #E5E5E5, #F4F4F4); /* Standard syntax; must be last */
  background-position: center right;
  background-repeat: no-repeat;
  border: 1px solid #AAA;
  border-radius: 2px;
  box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
  color: #555;
  font-size: inherit;
  margin: 0;
  overflow: hidden;
  padding-top: 2px;
  padding-bottom: 2px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

当您在基于WebKit的浏览器中的任何页面上运行此代码时,它应该更改选择框的外观,删除标准OS箭头并添加PNG箭头,在标签前后放置一些间距,几乎是您想要的任何内容。

最重要的部分是外观属性,它改变了元素的行为方式。

它在几乎所有基于WebKit的浏览器中都能完美工作,包括移动浏览器,尽管Gecko似乎不像WebKit那样支持外观。

其他回答

Danield回答中的第三种方法可以改进,以处理悬停效果和其他鼠标事件。只需确保“button”元素正好位于标记中的select元素之后。然后使用+CSS选择器将其作为目标:

HTML格式:

<select class="select-input">...</select>
<div class="select-button"></div>

CSS:

.select-input:hover+.select-button {
    <Hover styles here>
}

然而,当悬停在select元素上的任何位置时,这将显示悬停效果,而不仅仅是“按钮”上。

我将此方法与Angular结合使用(因为我的项目恰好是Angular应用程序),以覆盖整个select元素,并让Angular在“button”-元素中显示所选选项的文本。在这种情况下,将鼠标悬停在所选对象上的任何位置时,悬停效果都是非常合理的。

如果没有JavaScript,它就无法工作,所以如果您想这样做,并且您的站点必须在没有JavaScript的情况下工作,那么您应该确保您的脚本添加了增强所需的元素和类。这样,没有JavaScript的浏览器只会得到一个正常的、未样式的select,而不是一个无法正确更新的样式徽章。

不建议编辑此元素,但如果您想尝试,它与任何其他HTML元素一样。

编辑示例:

/* Edit select */
select {
    /* CSS style here */
}

/* Edit option */
option {
    /* CSS style here */
}

/* Edit selected option */
/* element  attr    attr value */
option[selected="selected"] {
    /* CSS style here */
}
<select>
    <option >Something #1</option>
    <option selected="selected">Something #2</option>
    <option >Something #3</option>
</select>

仅限CSS和HTML的解决方案

它似乎与Chrome、Firefox和Internet Explorer 11兼容。但请留下您对其他网络浏览器的反馈。

正如Danield的回答所建议的那样,我将我的选择包装在一个div中(甚至两个div用于x浏览器兼容性),以获得预期的行为。

看见http://jsfiddle.net/bjap2/

HTML格式:

<div class="sort-options-wrapper">
    <div class="sort-options-wrapper-2">
        <select class="sort-options">
                <option value="choiceOne">choiceOne</option>
                <option value="choiceOne">choiceThree</option>
                <option value="choiceOne">choiceFour</option>
                <option value="choiceFiveLongTestPurpose">choiceFiveLongTestPurpose</option>
        </select>
    </div>
    <div class="search-select-arrow-down"></div>
</div>

注意两个div包装器。

还请注意,添加了额外的div以将箭头向下按钮放置在您喜欢的位置(绝对位置),这里我们将其放在左侧。

CSS

.sort-options-wrapper {
    display: inline-block;
    position: relative;
    border: 1px solid #83837F;
}

/* This second wrapper is needed for x-browser compatibility */
.sort-options-wrapper-2 {
    overflow: hidden;
}

select {
    margin-right: -19px; /* That's what is hiding the default-provided browser arrow */
    padding-left: 13px;
    margin-left: 0;
    border: none;
    background: none;

    /* margin-top & margin-bottom must be set since some
       browsers have default values for select elements */
    margin-bottom: 1px;
    margin-top: 1px;
}

select:focus {
    outline: none; /* Removing default browsers outline on focus */
}
.search-select-arrow-down {
    position: absolute;
    height: 10px;
    width: 12px;
    background: url(http://i.imgur.com/pHIYN06.png) scroll no-repeat 2px 0px;
    left: 1px;
    top: 5px;
}

纯交叉浏览器CSS选择控件样式

规则#1:切勿使用JAVASCRIPT来设置HTML元素的样式!

如果JS被禁用或阻止,CSS将崩溃并烧录。始终从纯CSS开始,然后在您喜欢的任何额外“脚本胶”上分层。记住<select>控件(如HTML中的所有表单字段)被替换为元素,这意味着设备上的浏览器和操作系统对控件的设计和布局具有一定的控制权。这就是为什么Windows、苹果和移动设备控件看起来都不同!这是有原因的。

不要用JavaScript或CSS黑客劫持控件设计,除非您觉得UI由于某种原因(如删除选择控件上的箭头)必须进行修改。下面的CSS不这样做。它接受了它可以在选择表单控件中重新设计的核心限制。我仍然会从我干净的CSS解决方案开始,然后在顶部覆盖任何自定义“黑客”。如果它们失败了,那么您的CSS将优雅地退回到一个始终适用于20多年浏览器的全局CSS设计。。。加上未来的!

下面的CSS代码跨浏览器(从1990年代到现在)工作,并将所有浏览器(过去和现在)与相同的基本CSS设计对齐。您可以根据需要自定义此代码。你可以在非常旧的浏览器中测试它,它应该给你一个与现代HTML5浏览器相匹配的外观和感觉,这应该一直是目标。

/* This CSS works in 20+ years of browsers without hacks, scripts, or tricks. */

body optgroup,
body optgroup:visited,
body optgroup:hover,
body optgroup:focus,
body optgroup:active {
    margin: 0;
    padding: 0;
    font-style: inherit;
    font-weight: bold;
    cursor: pointer;
    background: #fff;
    border: none;
}

body optgroup:visited,
body optgroup:hover,
body optgroup:focus,
body optgroup:active {
    background: #f9f9ff;
}

body option,
body option:visited,
body option:hover,
body option:focus,
body option:active {
    margin: 0;
    padding: 0;
    cursor: pointer;
    background: #fff;
    border: none;
}
body option:visited,
body option:hover,
body option:focus,
body option:active {
    background: #f9f9ff;
}

body select,
body select:visited,
body select:hover,
body select:focus,
body select:active {
    display: inline-block;
    width: auto;
    height: auto;
    min-width: 0;
    max-width: none;
    padding: .17em .17em;
    margin: 0;
    text-transform: none;
    border-radius: .2em;
    border: 2px solid #bbb;
    background: #fff;
    cursor: pointer;
    -webkit-appearance: listbox;
    -moz-appearance: listbox;
    line-height: normal;
}

body select:visited,
body select:hover,
body select:focus,
body select:active {
    background: #f9f9ff;
    border: 2px solid #999;
}
body select:focus {
    background: #fff;
    border: 2px solid #999;
}

body select:required:visited:valid,
body select:required:valid {
    background: #fff;
    border: 2px solid #7fbe96;
}

body select:required:hover:valid {
    background: #f9f9ff;
    border: 2px solid #278b3d;
}

body select:required:focus:valid {
    background: #fff;
    border: 2px solid #278b3d;
}

body select:required:visited:invalid,
body select:required:invalid {
    background: #fff;
    border: 2px solid #ff6565;
}

body select:required:hover:invalid {
    background: #f9f9ff;
    border: 2px solid #ce2f2f;
}

body select:required:focus:invalid {
    background: #fff;
    border: 2px solid #ce2f2f;
}

body select[disabled],
body select[readonly],
body select[disabled="disabled"],
body select[readonly="readonly"],
body select[disabled]:visited,
body select[readonly]:visited,
body select[disabled="disabled"]:visited,
body select[readonly="readonly"]:visited,
body select[disabled]:hover,
body select[readonly]:hover,
body select[disabled="disabled"]:hover,
body select[readonly="readonly"]:hover,
body select[disabled]:focus,
body select[readonly]:focus,
body select[disabled="disabled"]:focus,
body select[readonly="readonly"]:focus,
body select[disabled]:active,
body select[readonly]:active,
body select[disabled="disabled"]:active,
body select[readonly="readonly"]:active {
    border: 2px solid #bbb;
    background: #f0f0f0;
    color: #999;
    cursor: default !important;
}

我有这个确切的问题,除了我不能使用图像,而且不受浏览器支持的限制。这应该是“符合规范”,幸运的话,最终开始在各地工作。

它使用分层旋转的背景层来“剪切”下拉箭头,因为伪元素不适用于select元素。

编辑:在这个更新版本中,我使用了CSS变量和一个小型主题系统。

:根目录{--半径:2px;--baseFg:灰色;--baseBg:白色;--重音Fg:#006fc2;--重音Bg:#bae1ff;}.主题粉色{--半径:2米;--baseFg:#c70062;--baseBg:#ffe3f1;--重音Fg:#c70062;--重音Bg:#ffaad4;}.主题结构{--半径:0;--baseFg:白色;--baseBg:黑色;--accentFg:黑色;--accentBg:橙色;}选择{字体:400 12px/1.3无衬线;-webkit外观:无;外观:无;颜色:var(--baseFg);border:1px实体变量(--baseFg);线高:1;大纲:0;衬垫:0.65em 2.5em 0.55em 0.75em;边界半径:var(--radius);背景色:var(--baseBg);背景图像:线性梯度(var(--baseFg)、var(--baseFg)),线性梯度(-135度,透明50%,var(--accentBg)50%),线性梯度(-225度,透明50%,var(--accentBg)50%),线性梯度(var(--accentBg)42%,var(--accentFg)42%);背景重复:无重复,无重复,不重复,无反复;背景大小:1px 100%,20px 22px,20px 22 px,20px 100%;背景位置:右20px中心,右下,右下和右下;}选择:悬停{背景图像:线性梯度(var(--accentFg),线性梯度(-135度,透明50%,var(--accentFg)50%),线性梯度(-225度,透明50%,var(--accentFg)50%),线性梯度(var(--accentFg)42%,var(--accentBg)42%);}选择:活动{背景图像:线性梯度(var(--accentFg),线性梯度(-135度,透明50%,var(--accentFg)50%),线性梯度(-225度,透明50%,var(--accentFg)50%),线性梯度(var(--accentFg)42%,var(--accentBg)42%);颜色:var(--accentBg);边框颜色:var(--accentFg);背景色:var(--accentFg);}<选择><option>这么多选项</option><选项></选项></选择><select class=“主题粉色”><option>这么多选项</option><选项></选项></选择><select class=“主题构建”><option>这么多选项</option><选项></选项></选择>