不同浏览器处理表单样式的方式一直存在很大差异。这可能永远都会存在——因为 UI 设计选择在规范中没有描述。浏览器制造商可能认为这是他们能够稍微区分用户体验的方式之一。选择(下拉)菜单尤其奇怪。
当我说下拉菜单时,我的意思是
<select>
<option>Apples</option>
<option>Oranges</option>
<option>Banannas</option>
</select>
在 CSS 完全不干预的情况下,这将在浏览器之间一致呈现。在 Mac 上,为 11px Lucida Grande。

自从这篇文章撰写以来,选择样式发生了一些细微变化。2020 年年中,我们仍然没有惊人的样式控制,但您可以 使用此技巧很好地设置外部样式。
如果您更改字体系列会怎样?
select {
font-family: Cursive;
}
WebKit 浏览器(Safari、Chrome)将忽略您。Firefox、Opera 和 IE 将尊重您的更改。但是,font-family
不会级联到选择中,您必须在其中显式声明它。
如果您更改字体大小会怎样?
select {
font-size: 32px;
}
这很有趣。在 WebKit 中,如果字体大小在 0 到 10px 之间,它将呈现字体大小为 10px。从 11px 到 15px,它将呈现为 11px,而 16px 或更大则呈现为(等等),14px。此行为类似于 他们处理搜索输入的方式。
Firefox、Opera 和 IE 将尊重您的更改,但同样,只有在选择中显式声明时才会生效,它不会级联。

你能让 WebKit 尊重你的更改吗?
有点。您可以对选择设置 border: 0;
,它会使它看起来像下拉菜单的某种糟糕版本,但仍然具有一些 UI。它还将允许您的字体大小和样式选择生效。

您还可以设置 -webkit-appearance: none;
,您将获得类似圆角输入框的外观,但仍然具有选择交互(单击以显示菜单、键盘命令等)。它也将以这种方式尊重您的字体选择。

我认为 appearance 是完全自定义下拉菜单的最佳选择,但它将仅限于 WebKit,因为虽然 -moz-appearance: none;
有效,但它不会删除所有 chrome,只删除一些。Opera 完全不支持 appearance
。
下拉菜单本身呢?
就像激活时显示选择项的内容一样。据我所知,没有任何浏览器可以对其进行样式设置。甚至粗体或斜体也不行。您可以获得的最接近的样式是使用 对其进行分组。这可能主要是一个 UI 问题,但也可能是安全问题。您不希望人们使用字体进行一些复杂的操作,从而使所选选项不清楚。
如果您想要完全的界面控制权会怎样?
首先,尝试尽一切可能避免这种情况。默认表单元素很熟悉并且效果很好。使下拉菜单与品牌的字体和颜色匹配通常没有必要,充其量是令人讨厌的,最坏的情况是糟糕的 UX。
如果您认为自定义下拉菜单绝对是一个好主意,那么您应该使用 JavaScript 来
- 以可访问的方式隐藏原始选择。
- 使用自定义标记(可能是定义列表)重建选择,并根据需要进行样式设置。
- 复制默认选择具有的所有功能,包括:向上和向下箭头键以及返回以选择的键盘事件、长列表的滚动、当选择靠近屏幕底部时向上打开菜单,等等。
- 对于移动设备,触发本机选择菜单的打开,因为该功能几乎不可能复制。例如,iOS 翻转轮。
- 您可能也希望考虑为桌面使用“点击穿透”样式。默认情况下,选择采用自定义样式,但当您单击它时,它会打开本机下拉菜单(就地)。当您选择一个选项时,它会再次显示自定义样式并显示所选内容。
这是一项非常繁重且容易出错的工作,因此请注意。 本教程 处理了一些这样的难题。 这是一个笔,其中包含本文的一些测试内容。
不错。可惜下拉菜单本身的样式出现得这么晚。我仍然不明白——为什么到目前为止只有选择框无法用 CSS 编辑。所有输入元素很久以前就可以修改,但选择框不行:)。我仍然使用 JS 为所有浏览器执行相同的操作,就像您在最后一段中提到的那样,我想这种解决方案至少还需要几年时间
不仅选择外观不可编辑——复选框、单选按钮和文件输入(根本不可编辑)也是如此。问题在于这些表单元素不是由浏览器控制的,而是由操作系统控制的。即使在 Windows、Linux 和 Mac OS 上的 Firefox 中,默认的选择、复选框、单选按钮或文件输入看起来也大不相同(其他浏览器在不同的操作系统上也是如此)。
如果您想设置复选框的样式或具有其他文件输入外观,您仍然需要一些 JS 库来实现目标。
哇,时机太好了。我刚刚在一个新项目中研究了这个问题。谢谢!
对我来说,Chrome(Win)中让我感到困扰的事情之一是字体。它们最终总是看起来参差不齐,然后我不得不使用所有这些技巧才能使它看起来更好。就像这个网站的字体现在看起来很参差不齐。尤其是顶部的菜单字体。
社区已经向 Chrome 抱怨这个问题超过一年了,但他们对此没有采取任何措施。
这主要是因为微软将字体抗锯齿留给了用户(为什么?不知道,他们做了奇怪的事情,但他们至少可以将其默认设置为看起来不错)。转到控制面板 -> 外观和个性化 -> 调整 ClearType 文本,然后确保已启用它。现在,网络上的字体整体看起来应该好多了。
在我看来,即使启用了 ClearType,OS X 也会更漂亮地呈现字体,但它至少应该对您有所帮助。
Smashing Magazine 有一篇关于此的精彩文章:http://www.smashingmagazine.com/2012/04/24/a-closer-look-at-font-rendering/
Chrome 仍然使用 Windows 的旧字体渲染,而 Firefox 和 IE9 使用新的 DirectWrite 渲染方法。在我看来,DirectWrite 看起来很棒,我希望 Chrome 支持它。
ClearType 对 Chrome 如何渲染文本没有影响。但 Chrome 在渲染大多数字体方面确实很糟糕。
哦,我刚刚意识到 Windows Safari 中的 css-tricks 坏了,Chris。我会为您提供屏幕截图/详细信息,以便您进行检查。
只想指出,一些下拉插件并没有真正起到作用。我还没有找到一个可以在真实(隐藏)下拉菜单和样式化(DIV)下拉菜单上同时触发事件的插件。状态通常会正确更新,但事件不会像预期的那样传递。
到目前为止,我最喜欢的技巧是 jQuery Mobile 的方法,它将一个不可见的原生下拉菜单放置在一个样式化的下拉菜单之上。事件和行为发生在真正的下拉菜单上,你只需要用选定的值更新样式化的 DIV 即可。唯一的缺点是你仍然无法为选项设置样式(不过在移动设备上这不是缺点)。
看看我和一个朋友做的,似乎可以解决问题。
http://andrew-jones.me/blog/styling-select-items/
我通常建议不要设置元素的样式,因为很容易出错。
但是,最近我使用 Modernizr 检测一个非常新的属性(例如 border images),然后使用 -webkit-appearance: none; 并使用 :before 和 :after 元素重新设置下拉菜单的样式,取得了不错的成功。
使用 @moz-document-url-prefix 修复一些 Firefox 问题(即 Firefox 对表单元素中的行高和填充属性的反应不同)
效果还不错:IE9、IE10、Chrome 和 Firefox 都得到了不错的选择效果。当你点击它时,你会得到原生的选项(这些选项是不可样式化的)。
然而,它也不太具有前瞻性:一旦 Opera 开始支持“模糊属性”,计划就会失败。
不建议使用 JS 创建自定义下拉菜单,但有时你必须这样做:也许你想要一个超级下拉菜单,或者你想要在下拉菜单中显示除列表之外的不同内容。
人们在编写自定义下拉菜单时会忘记很多东西,例如文章中提到的演示没有实现 (1) ESC 键关闭 (2) 点击外部关闭。然后是 (3) 一个页面上的多个下拉菜单 (4) 与模态和其他覆盖元素的 z-index 冲突。等等。
我希望浏览器制造商在“Shadow DOM”上做好工作,使每个 UI 元素都可设置样式。这将有助于 Web 作为真正的应用程序平台(相对于原生应用程序)发展。
我现在已经处理了很长一段时间的下拉框项目。主要在 Linux 上,我注意到(通常)更新的浏览器更好地遵守 CSS 规则。
这是 Chrome、Firefox 和 Opera 的一些 屏幕截图,在 Ubuntu 12.10 上拍摄。
我非常不同意最后一部分。“使下拉菜单与品牌的字体和颜色相匹配通常没有必要,充其量令人讨厌,最坏的情况是糟糕的用户体验。”
它之所以成为“糟糕的用户体验”,仅仅是因为过去的技术有限。许多 Web 上的“标准”做法之所以成为标准,就是因为这些限制,而现在这些限制已经解除,我认为是时候开始扩展了。并非所有选择菜单都需要看起来相同。可以设计一个仍然像选择菜单一样的选择菜单,同时又不像是默认的操作系统。
如果我们继续以用户期望的方式做事,那么 Web 设计将永远不会进步。我说只要合适,就尽可能地突破界限。尽力确保它适用于旧版浏览器的用户,但也要迎合那些保持最新状态的用户,只要他们不是极少数。未来不会充满默认样式的任何东西。未来是开放的。
当然,这并不是它成为糟糕的用户体验的唯一原因。任何偏离表单控件默认操作系统样式的行为都肯定会在某些人那里造成困惑。考虑到你完全不知道用户使用的是什么操作系统,因此也不知道该默认操作系统样式是什么。
你无法确定用户是否会认为你作为页面作者的偏好足够直观,以至于能够理解你的外星下拉菜单到底是什么。尤其是在用户已在其操作系统中自定义了表单控件的情况下。
关键是要围绕表单元素进行稳健的设计,而不是修改表单元素本身。坦率地说,如果你不喜欢特定操作系统渲染其表单控件的方式,那么就不要使用该操作系统。
表单元素不必以一种方式才能直观。并非所有手机看起来都一样,但你仍然可以根据上下文将它们识别为手机。偶尔你会看到一部手机,你会想,“哇,我没想到那是一部手机。”但总的来说,只要人们不过度,人们就能在看到手机时识别出来。即使形状、颜色、按钮等不同。如果我们允许表单元素也一样。从大局来看,表单元素非常新。你想锁定它们并保持现状吗?我想保持开放,为人们留出创新的空间。也许我们还没有做到这一点?
你关于不喜欢默认操作系统表单元素的评论也可以说适用于网站。你不喜欢网站的表单元素?不要使用该网站。:D
一般来说,自定义表单元素会变成无法访问的表单元素,这很不公平,而且是彻头彻尾的糟糕开发。残疾人士需要能够使用你提供给他们的任何东西。不要忘记这一点。
我个人讨厌那些不允许我完全使用键盘填写表单的表单。非常令人分心,而且不得不把手从键盘上拿开并点击一个响应缓慢的 JavaScript“漂亮”下拉菜单(然后当然不允许我通过按“M”来缩小 50 个州)令人沮丧。
出于同样的原因,很容易理解为什么将表单元素保留为用户“期望”的样子是更好的用户体验。人们期望表单看起来像表单。无需对其进行“美化”。为什么要让用户学习使用你的新界面,这可能会导致沮丧,以便它“与你的品牌相匹配”?用户真的会说,“好吧……那是一个无聊的下拉菜单!我想我不会再使用这个网站了。”?我认为不会。
你说得对,它们不必以一种方式才能直观,这就是为什么你不应该设置它们的样式。设置它们的样式就是试图使它们“以一种方式”。修改它们会增加某些人不会与之交互的可能性。
如果你希望 Web 在表单字段设计方面“进步”,那么就开始关注操作系统。任何偏离原生操作系统设计的应用程序都注定要失败。
随着时间的推移,我的默认操作系统主题表单字段将跟上多年来取得的任何进步。但是,你的自定义表单字段将永远保持不变,并且有一天会看起来或表现得比我的更过时。那么进步在哪里呢?
不要试图耍聪明,保持简单。
@Lee – 你绝对歪曲了我的意思。当我提到“表单元素不必以一种方式才能直观”时,你知道我的意思。我的意思是,所有网站上的所有表单元素在给定的操作系统上看起来都一样。从设计的角度来看,我仍然认为出于你们任何一方提出的任何原因,这都没有必要。
看看 Mint.com。他们拥有庞大的用户群,并且使用带有自定义功能的自定义样式下拉菜单。Chosen 来自 Harvest 的优秀团队是另一个自定义表单元素的绝佳示例,这些表单元素仍然非常用户友好,并且可以说更容易使用。
@Merne – 看起来你被一些自定义下拉菜单的糟糕实现给坑了。但那是糟糕的技术和糟糕的代码。设计本身不一定是问题。
你们两人似乎都非常关注现在有效的方法,而不是我们如何塑造未来。而且我不认为如果有人想改变表单元素的世界,就需要为操作系统进行设计。每个人似乎都同意自定义文本字段,但这仅仅是因为该技术已经存在很长时间了。
多年来,用户已经习惯了各种表单文本字段的外观,这似乎没有问题(甚至这个网站也这样做)。随着技术的进步,所有其他表单元素也将发生同样的情况。看看 Web 排版发生了什么。我们终于取得了进步。它还没有完美,但正在变得越来越好,因为人们进行了创新,并且没有将系统默认值视为最终结果。我们尝试推动 Web 发展的人越多,它前进的速度就越快。我将帮助推动。
不过,最终,我想我们只能就此意见不一。假设这个网站还在,10 年后再回顾这次讨论将很有趣:D
但如果你指的是它们不必与操作系统匹配才能直观,那么你就错了,因为它们确实需要匹配。任何偏差都会分散对可供性的注意力。由于真正的直觉在人机交互中并不真正存在,因此一切都必须学习。
工作假设是操作系统最直观,因为在他们访问你的网站之前,他们很可能已经学习过它。偏离的操作系统无法宣称更直观,它们有时可以更友好,但这并不相同。即使你的网站更好,但它与众不同的事实也会让用户绊倒。
例如,Chosen 插件创建的自定义选择框(http://harvesthq.github.com/chosen/),虽然非常好,并且目前比操作系统好得多,但并不支持原生选择框支持的所有键盘快捷键,例如 Page Up/Page Down(可能是疏忽)。
无论如何,在标准下拉菜单中,我希望通过重复按“U”来获取“英国”,因为键入“United K”通常需要更多工作(并且使用鼠标意味着在填写表单时移动我的手),但在增强的 Chosen 下拉菜单中,重复按“U”不受设计支持,并且会失败。
当然,这些问题都可以解决,但需要付出很多努力,才能让这些“更好的”下拉菜单完全按照每个人的预期工作,而使用现有的下拉菜单则是另一种更简单的选择。此外,你无法让自定义设计完全符合每个人的预期,因为这些控件在不同的操作系统上表现不同,这几乎是一项不可能完成的任务。
我没有发现mint.com上的表单设计有什么特别之处,不过由于我在英国,所以不允许我使用它。我只能看到他们在注册页面上的国家/地区下拉菜单,在我看来,它一点也不特别(这很好)。
就在这个周末,我在play.com上订购了一些东西,由于按钮的背景颜色,我多花了几秒钟才找到完成结账的按钮——而人们会认为这是一个极其微小且无害的偏差,我也这么认为。
底线是,如果你对自己的表单字段重新设计风格感到满意,那肯定说明你是在为自己设计它们。
请注意:我这里只指的是文章末尾5个步骤中描述的那类活动。做一些完全不同或新的东西是合理的,但你不能说仅仅为了实现你自己的品牌或相同功能的设计而重新设计现有机制是具有创造性、进步性或正当性的。没有一个用户会感激你的努力,我的意思是,如果他们不想使用你的网站,那肯定不是因为你使用了默认的操作系统表单字段,而是其他什么原因。
这并不完全正确。在一个项目中,我更改了
option
的背景,以表示选项的状态。(可用选项为绿色背景,可能可用选项为橙色或其他颜色。)跨浏览器兼容性非常差,而且在Mac上根本无法使用。在Windows浏览器中,你可以更改
option
的背景颜色。Firefox/Chrome和IE的行为略有不同。在设置select
和option
样式时,我发现了两个奇怪的事情。IE10中,如果将
option
的样式设置为background: white;
,则当前选定的选项将无法读取:http://jsfiddle.net/HQLAR/在iOS上,如果使用
-webkit-gradient
设置select
的样式,则将消除指示它是选择框的箭头。如果不需要,就不要重新发明轮子。如果你使用jQuery或Prototype,可以尝试使用Chosen。它易于设置样式,并在许多方面改进了
<select>
的功能。110%同意。
不用担心这或那是否适用于这个或那个渲染引擎或这个或那个操作系统。
Chosen是最好的选择,如果你需要设置下拉菜单/选择框的样式。
我也同意,Chosen绝对是最好的选择。它是我个人见过的最好的下拉菜单样式插件。
我一直在尝试一些关于选择框的东西,我发现了一些我无法解释的事情,它们看起来完全是随机的。
字体样式只有在以下情况下才会应用于选择框:
* 设置背景。例如:
background: green;
,但background: none;
也可以。* 将边框半径设置为超过5像素。如果将边框半径设置为6,则样式将应用于选择框。更改边框半径根本不起作用,但它以某种方式触发了选择框。而且将边框半径设置为20px或100px没有任何区别,它可以让一些样式应用于选择框,但选择框的大小和实际的边框半径根本不会改变。
所有这些操作都是在Mac上的最新Chrome版本中进行的。我无法弄清楚为什么这些设置会使选择框响应表示标记……
请查看我制作的笔(从Chris那里复制的):http://codepen.io/anon/full/HofDw
我也尝试过在webkit中设置此元素的样式,即使select是一种容器元素,继承和伪元素也不能应用。至于opt groups和options本身,你可以更改背景颜色,但仅此而已。
就像Chris所说,如果你真的需要它与你的品牌相匹配,那么JavaScript是最好的选择——使用像jquery这样的流行框架,你可以轻松做到这一点……
或者,如果你不关心兼容性,则可以使用纯CSS3中的:target来尝试实现。请查看我的演示http://jsfiddle.net/alexh58/wymny/embedded/result/
是的,它很臃肿且不实用,但可以做到!
嗯……是我一个人,还是Pen显示的行为与Chris所说的完全不同?我使用的是Chrome 22.0.1229.94 m,Windows 7,字体正在正确缩放(一直到1px!),即使没有边框hack,字体系列也被应用了,样式也被应用到了下拉列表中!
评论似乎吞掉了我的图片链接;让我们看看这次是否有效。
是的,你是对的。即使在相同的浏览器版本上,
select
和option
在不同的操作系统上的行为也大不相同。Chris只在Mac上查看了这些内容。首先,这是一篇很棒的文章。接下来,它可能不是设置选项样式的最佳解决方案,但你可以通过每个选项上的style属性来为选项应用样式。
http://codepen.io/Pmac627/pen/kodDx
我只在一次设置字体大小时这样做过。如果有很多选项(例如州选择),这将是一件很麻烦的事情,但如果样式相同,循环可以解决这个问题。
@Pat,
为单个选择选项设置样式在Firefox中可以正常工作,但在Chrome中不行,这就是这篇文章的要点。
Drupal用户:http://drupal.org/project/select_with_style
@RdeBoer,
为什么背景颜色可以工作,而其他样式不行(在Chrome中)?即使使用!important也无法覆盖Chrome。
我昨天还在寻找关于这方面的信息!你在监视我吗?
你好,
我尝试使用Chrome将此文档保存为pdf,但当我查看pdf时,文本完全乱了。我是一个离线用户,也是你网站的忠实粉丝。
@Pat——不知道为什么颜色只在某些时候有效。正如@Stefan在本线程中前面提到的……似乎有很多因素在某些情况下会产生影响,而在其他情况下则不会……在下拉选择器方面,浏览器和操作系统之间似乎没有多少一致性。
时机太好了!刚好在讨论为一个新项目自定义下拉菜单的最佳方法——非常有帮助!
Mozilla相关bug https://bugzilla.mozilla.org/show_bug.cgi?id=649849
我曾经在一个主要支持webkit的CRM软件上工作过。
用户可以通过
<select>
选择帮助台条目的状态。由于每个状态都有自己的标签背景颜色,我将状态css类应用于每个<option>
,背景颜色效果很好,这使得选择框在该上下文中非常易用,因为人们可以通过颜色轻松识别状态。我过去也使用这种方法来更改选择菜单的外观,即使在Mac上也是如此:
select
如果我们使用这种方法,会出现什么问题吗?请查看jsfiddle演示{
border: none;
background: none;
-webkit-appearance: initial;
}
Firefox尊重选择框内部的字体样式,特别是旧标签。我制作了一个名为5edit的HTML5编辑器,它使用这些样式进行字体选择。如果你在Firefox中访问该链接,你将看到它的实际效果,当然,在任何其他浏览器中你都看不到。
你好,
我只想将颜色应用于下拉菜单的*字符,例如类别*(星号为红色)。
提前感谢。
这似乎在最新版本的Firefox 30中已损坏。有人知道发生了什么吗?