CSS :enabled和:disabled的用法
:enabled 伪类和 :disabled 伪类从 IE9 浏览器就已经开始支持,可以放心使用。
由于在实际项目中 :disabled 伪类用得较多,因此我们先介绍 :disabled 伪类。
图 1 输入框处于禁用状态时背景置为浅灰色(使用:disabled伪类实现)
实际上,直接使用属性选择器也能设置禁用状态的输入框的样式,例如:
图 2 输入框处于禁用状态时背景置为浅灰色(使用属性选择器实现)
后一种方法的兼容性更好,IE8 浏览器也支持。
对于常见的表单元素,:enabled 伪类与 :disabled 伪类确实是对立的,也就是说,如果这两个伪类样式同时设置,有且只有一个伪类样式匹配。
下面以输入框元素为例,CSS 代码如下:
HTML 代码如下:
readonly(只读)状态也认为是 :enabled,最终效果如下图所示。
图 3 :enabled与:disabled两种样式中必定渲染其一
之前提到过,在 Chrome 浏览器下,:enabled 伪类也可以匹配带有 href 属性的 <a> 元素,这其实是不对的,现在 Chrome 浏览器已经解决了此问题,大家在使用 :enabled 伪类的时候可以无须顾虑 <a> 元素了。
对于 <select> 下拉框元素,无论是 <select> 元素自身,还是其后代 <option> 元素, :enabled 伪类和 :disabled 伪类都能匹配,所有浏览器都支持。
例如有如下 HTML 代码和 CSS 代码:
图 4 :disabled伪类匹配<option>元素
在 IE 浏览器下,:enabled 伪类与 :disabled 伪类并不匹配 <fieldset> 元素,这是有问题的,但其他浏览器没有这个问题。因此,如果使用 <fieldset> 元素一次性禁用所有表单元素,就不能通过 :disabled 伪类识别(如果要兼容IE浏览器),可以使用 fieldset[disabled] 选择器进行匹配。
设置 contenteditable="true" 的元素虽然也有输入特性,但是 :enabled 伪类不能匹配,所有浏览器都不支持。同样,:enabled 伪类也不能匹配设置 tabindex 属性的元素。
设置 visibility:hidden 或者 display:none 的元素依然能够被 :enabled 伪类和 :disabled 伪类匹配。
例如,可以像下面这样做:
而无须多此一举,再写上 :enabled 伪类:
例如我们可以使用 document.querySelectorAll ('form :enabled') 查询所有可用表单元素,以实现自定义的表单序列化方法。
至于 :disabled 伪类,最常用的应该就是按钮了。只要你的网页项目不需要兼容旧版本的 IE 浏览器,就可以使用原生的 <button> 按钮实现,这样做的优点非常多。
以按钮禁用为例,点击按钮发送 Ajax 请求是一个异步过程,为了防止重复点击请求,通常的做法是设置标志量。实际上,如果是原生的按钮(无论是 <button> 按钮还是 <input> 按钮),只要设置按钮 disabled = true,点击事件自然就会失效,无须用额外的 JavaScript 代码进行判断,同时语义更明确,而且可以使用 :disabled 伪类精确控制样式。
例如:
由于历史遗留原因,网页中的按钮多使用 <a> 元素。对于禁用状态,很多人会用 pointer- events:none 来控制,虽然用鼠标点击它确实无效,但是按 Tab 键依然可以访问它,按 Enter 键也依然可以触发点击事件,所以用这种方法实现的其实是伪禁用。同时,设置了 pointer-events:none 的元素无法显示 title 提示,可用性反而降低了。因此,尽量使用原生按钮实现交互效果。
由于在实际项目中 :disabled 伪类用得较多,因此我们先介绍 :disabled 伪类。
:disabled的基本用法
最简单的用法是实现禁用状态的输入框,HTML 代码如下:<input disabled>此时,我们就可以使用 :disabled 伪类设置输入框的样式。例如,设置背景色为浅灰色:
:disabled { border: 1px solid lightgray; background: #f0f0f3; }效果如下图所示。
图 1 输入框处于禁用状态时背景置为浅灰色(使用:disabled伪类实现)
实际上,直接使用属性选择器也能设置禁用状态的输入框的样式,例如:
[disabled] { border: 1px solid lightgray; background: #f0f0f3; }效果是一样的,如图 2 所示。
图 2 输入框处于禁用状态时背景置为浅灰色(使用属性选择器实现)
后一种方法的兼容性更好,IE8 浏览器也支持。
:enabled和:disabled的细节知识
我们需要先搞明白 :enabled 伪类与 :disabled 伪类是否对立。对于常见的表单元素,:enabled 伪类与 :disabled 伪类确实是对立的,也就是说,如果这两个伪类样式同时设置,有且只有一个伪类样式匹配。
下面以输入框元素为例,CSS 代码如下:
:disabled { border: 1px solid lightgray; background: #f0f0f3; } :enabled { border: 1px solid deepskyblue; background: lightskyblue; }
HTML 代码如下:
<input disabled value="禁用"> <input readonly value="只读"> <input value="普通">
readonly(只读)状态也认为是 :enabled,最终效果如下图所示。
图 3 :enabled与:disabled两种样式中必定渲染其一
之前提到过,在 Chrome 浏览器下,:enabled 伪类也可以匹配带有 href 属性的 <a> 元素,这其实是不对的,现在 Chrome 浏览器已经解决了此问题,大家在使用 :enabled 伪类的时候可以无须顾虑 <a> 元素了。
对于 <select> 下拉框元素,无论是 <select> 元素自身,还是其后代 <option> 元素, :enabled 伪类和 :disabled 伪类都能匹配,所有浏览器都支持。
例如有如下 HTML 代码和 CSS 代码:
<select multiple> <option>选项1</option> <option disabled>选项2</option> <option>选项3</option> <option>选项4</option> </select> option:disabled { color: silver; }最终的渲染效果如下图所示,可以看到设置了 disabled 属性的 <option> 元素中的文字是银色的。
图 4 :disabled伪类匹配<option>元素
在 IE 浏览器下,:enabled 伪类与 :disabled 伪类并不匹配 <fieldset> 元素,这是有问题的,但其他浏览器没有这个问题。因此,如果使用 <fieldset> 元素一次性禁用所有表单元素,就不能通过 :disabled 伪类识别(如果要兼容IE浏览器),可以使用 fieldset[disabled] 选择器进行匹配。
设置 contenteditable="true" 的元素虽然也有输入特性,但是 :enabled 伪类不能匹配,所有浏览器都不支持。同样,:enabled 伪类也不能匹配设置 tabindex 属性的元素。
设置 visibility:hidden 或者 display:none 的元素依然能够被 :enabled 伪类和 :disabled 伪类匹配。
:enabled和:disabled的实际应用
:enabled 伪类在 CSS 开发中是略显鸡肋的伪类,因为表单元素默认就是 enabled 状态的,不需要额外的 :enabled 伪类匹配。例如,可以像下面这样做:
.cs-input { border: 1px solid lightgray; background: white; } .cs-input:disabled { background: #f0f0f3; }
而无须多此一举,再写上 :enabled 伪类:
/* :enabled多余 */ .cs-input:enabled { border: 1px solid lightgray; background: white; } .cs-input:disabled { background: #f0f0f3; }但是 :enabled 伪类在 JavaScript 开发中很有用,因为 JavaScript 没有 CSS 这样的语句覆盖特性,必须精准匹配对应的元素才行。所以,我们要想获取表单中的可用控件元素,只能使用 :enabled 伪类。
例如我们可以使用 document.querySelectorAll ('form :enabled') 查询所有可用表单元素,以实现自定义的表单序列化方法。
至于 :disabled 伪类,最常用的应该就是按钮了。只要你的网页项目不需要兼容旧版本的 IE 浏览器,就可以使用原生的 <button> 按钮实现,这样做的优点非常多。
以按钮禁用为例,点击按钮发送 Ajax 请求是一个异步过程,为了防止重复点击请求,通常的做法是设置标志量。实际上,如果是原生的按钮(无论是 <button> 按钮还是 <input> 按钮),只要设置按钮 disabled = true,点击事件自然就会失效,无须用额外的 JavaScript 代码进行判断,同时语义更明确,而且可以使用 :disabled 伪类精确控制样式。
例如:
<button id="csButton" class="cs-button">删除</button> /* 按钮处于禁用状态时的样式 */ .cs-button:disabled {} csButton.addEventListener('click', function () { this.disabled = true; // 运行ajax // ajax完成后设置按钮disabled为false });充分利用浏览器内置行为会使代码更简洁,功能更健壮,语义更明确,因此没有不使用它的理由。
由于历史遗留原因,网页中的按钮多使用 <a> 元素。对于禁用状态,很多人会用 pointer- events:none 来控制,虽然用鼠标点击它确实无效,但是按 Tab 键依然可以访问它,按 Enter 键也依然可以触发点击事件,所以用这种方法实现的其实是伪禁用。同时,设置了 pointer-events:none 的元素无法显示 title 提示,可用性反而降低了。因此,尽量使用原生按钮实现交互效果。