一.CSS与表单元素
CSS 2.1规范(3.2 UA一致性)里有这样一段话:
CSS 2.1 does not define which properties apply to form controls and frames, or how CSS can be used to style them. User agents may apply CSS properties to these elements. Authors are recommended to treat such support as experimental. A future level of CSS may specify this further.
简单翻译下:CSS 2.1没有定义哪些属性适用于表单控件和frame,以及怎样用CSS给他们设置样式,用户代理可能会给这些元素应用CSS属性,建议编写者把此类支持当做实验性的,CSS后续版本可能会进一步指定这些
也就是说,规范不保证表单元素身上的CSS样式正常生效,为什么?
因为表单元素有一些特殊性,这些控件是由操作系统渲染的,而不是浏览器。尤其是checkbox
和radio group
,尝试对它们设置样式时会遇到各种问题
确实会出现某些CSS属性在表单元素身上失效的问题,比如input
上的display: table-cell
无效,详细见display:table-cell not working on an input element
二.真实案例
先上图:
可以看到文字颜色的明显差异,对应的HTML结构与CSS样式如下:
<!-- 左边 -->
<textarea class="txtLetter" disabled="true">颜色浅不浅,应该不浅了吧</textarea>
<!-- 右边 -->
<div class="txtLetter">颜色浅不浅,应该不浅了吧</div>
textarea {
-webkit-appearance: none;
}
.txtLetter {
resize: none;
border: none;
display: block;
width: 100%;
height: 4.5rem;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 0.8rem 0.6rem;
color: #f26135;
font-size: 12px;
background-color: transparent;
outline: none;
}
div
与textarea
共用一份样式,文本颜色渲染效果却差异很大,后来定位到原因是disabled
,正常可输入的input, textarea
的color
是准确无误的,如果是disabled
状态,那么color
就不可靠了,感觉“禁用”状态是对整个输入控件盖了一层透明度滤镜(猜测)。如果是这样,也在情理之中,因为表单元素无法交互了应该给用户以强感知,应该与可交互状态的表现有明显差异
这也提醒我们,对于自定义的表单控件(非原生),配色需要注意这些细节,禁用状态不仅要对背景色灰化,文本颜色,边框颜色,图标装饰等都应该考虑进去
比较隐蔽的一点是,表单元素的这种差异在开发环境无法发现,如下图:
Chrome下disabled
文本颜色没有差异(Firefox下也没有差异),Safari下似乎有肉眼不可见的差异(放大n倍后能发现取色差异)。当然,在开发过程中尽早真机自测很容易发现问题,但更应该从实现方案上避免这种情况
P.S.这个案例场景主要是因为偷懒,可交互的表单页与不可交互的分享页共用了相同的HTML结构,所以直接给textarea
设置了disabled
,期望它看起来和div
一样,结果发现了这个隐蔽的问题
三.去掉表单元素默认样式
在移动端或者兼容性允许的环境,可以使用下面的CSS去掉文本框默认样式:
input, textarea {
-webkit-appearance: none;
-moz-appearance: none;
outline: none;
/* remove highlight outline on samsung */
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-webkit-tap-highlight-color: transparent;
/* android 4.0.4 */
-webkit-user-modify: read-write-plaintext-only;
}
P.S.三星GT-S7562i(android4.0.4)下输入框获得焦点时,高亮黄框去不掉,不是outline,需要通过user-modify
去掉,详细见Disable orange outline highlight on focus
另外,-webkit-appearance: none;
存在2个问题:
不一定能完全去掉所有想去掉的东西,比如input高亮黄框
不一定会保留想保留的东西,比如select的箭头图标、checkbox无法选中
四.结论
有人专门深入研究过这个问题,并做了很多实验:
using CSS to style form controls to look exactly the same across browsers and platforms is impossible. It also shows that most browsers ignore many CSS properties when they are applied to form controls.
总之:
对表单控件应用CSS样式,需要特别小心,因为规范不保证有效,那么在多平台下效果可能不一致
不建议对表单元素大幅度定制样式,环境兼容性很脆弱,要么保留原生样式,要么完全自定义(比如手动实现select),不用表单元素