代码我同样放到了codepen,大家可以在线研究,或下载收藏。
关键在于使用css selectors levle4里的一些伪类实现表单验证,这些伪类有:
上面的案例就是使用了:in-range和:out-of-range,接下去我们来一一解读下。
:required可以选中具有required属性的表单元素,可以是input、select和textarea,例如下面这些元素都会被选中。
<code class="language-html hljs " style="box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; padding: 0.5em; color: rgb(0, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; display: block; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-tag" style="box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">input</span> <span class="hljs-attribute" style="box-sizing: border-box;">type</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"name"</span> <span class="hljs-attribute" style="box-sizing: border-box;">required</span>></span> <span class="hljs-tag" style="box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">input</span> <span class="hljs-attribute" style="box-sizing: border-box;">type</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"checkbox"</span> <span class="hljs-attribute" style="box-sizing: border-box;">required</span>></span> <span class="hljs-tag" style="box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">input</span> <span class="hljs-attribute" style="box-sizing: border-box;">type</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"email"</span> <span class="hljs-attribute" style="box-sizing: border-box;">required</span>></span> <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);"><!-- and other input types as well.. --></span> <span class="hljs-tag" style="box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">textarea</span> <span class="hljs-attribute" style="box-sizing: border-box;">name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"name"</span> <span class="hljs-attribute" style="box-sizing: border-box;">id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"message"</span> <span class="hljs-attribute" style="box-sizing: border-box;">cols</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"30"</span> <span class="hljs-attribute" style="box-sizing: border-box;">rows</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"10"</span> <span class="hljs-attribute" style="box-sizing: border-box;">required</span>></span><span class="hljs-tag" style="box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">textarea</span>></span> <span class="hljs-tag" style="box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">select</span> <span class="hljs-attribute" style="box-sizing: border-box;">name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"nm"</span> <span class="hljs-attribute" style="box-sizing: border-box;">id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"sel"</span> <span class="hljs-attribute" style="box-sizing: border-box;">required</span>></span> <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);"><!-- options --></span> <span class="hljs-tag" style="box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">select</span>></span></code>
:optional则选中不具有required属性的表单元素,利用这两个伪类我们可以实现下面这个有意思的效果。代码同样放在了codepen,在线研究or下载收藏,悉听尊便。
本代码主要利用:required和:optional两个伪类对必选和选填的两种表单实施不同的样式,不同的提示文字。核心代码如下所示。
<code class="language-css hljs " style="box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; padding: 0.5em; color: rgb(0, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; display: block; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">/*可选表单样式*/</span> <span class="hljs-tag" style="box-sizing: border-box;">input</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:optional</span>, <span class="hljs-tag" style="box-sizing: border-box;">select</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:optional</span> <span class="hljs-rules" style="box-sizing: border-box;">{ <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">border-right</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);"> <span class="hljs-number" style="box-sizing: border-box;">3</span>px solid <span class="hljs-hexcolor" style="box-sizing: border-box; color: rgb(0, 136, 0);">#888</span></span></span>; <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">background-color</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);"> <span class="hljs-hexcolor" style="box-sizing: border-box; color: rgb(0, 136, 0);">#f8f8f8</span></span></span>; <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">color</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);"> <span class="hljs-hexcolor" style="box-sizing: border-box; color: rgb(0, 136, 0);">#888</span></span></span>; <span class="hljs-rule" style="box-sizing: border-box;">}</span></span> <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">/*必选表单样式*/</span> <span class="hljs-tag" style="box-sizing: border-box;">input</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:required</span>, <span class="hljs-tag" style="box-sizing: border-box;">textarea</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:required</span> <span class="hljs-rules" style="box-sizing: border-box;">{ <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">border-right</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);"> <span class="hljs-number" style="box-sizing: border-box;">3</span>px solid <span class="hljs-hexcolor" style="box-sizing: border-box; color: rgb(0, 136, 0);">#aa0088</span></span></span>; <span class="hljs-rule" style="box-sizing: border-box;">}</span></span> <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">/*可选表单提示文字*/</span> <span class="hljs-tag" style="box-sizing: border-box;">input</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:optional+label</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">::after</span><span class="hljs-rules" style="box-sizing: border-box;">{ <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">content</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);"><span class="hljs-string" style="box-sizing: border-box;">"(可选)"</span></span></span>; <span class="hljs-rule" style="box-sizing: border-box;">}</span></span> <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">/*必选表单提示文字*/</span> <span class="hljs-tag" style="box-sizing: border-box;">input</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:required+label</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">::after</span><span class="hljs-rules" style="box-sizing: border-box;">{ <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">content</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);"><span class="hljs-string" style="box-sizing: border-box;">"(必填)"</span></span></span>; <span class="hljs-rule" style="box-sizing: border-box;">}</span></span> <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">/*可选表单激活效果*/</span> <span class="hljs-tag" style="box-sizing: border-box;">input</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:optional</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:focus</span>, <span class="hljs-tag" style="box-sizing: border-box;">select</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:optional</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:focus</span> <span class="hljs-rules" style="box-sizing: border-box;">{ <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">box-shadow</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);"> <span class="hljs-number" style="box-sizing: border-box;">0</span> <span class="hljs-number" style="box-sizing: border-box;">0</span> <span class="hljs-number" style="box-sizing: border-box;">2</span>px <span class="hljs-number" style="box-sizing: border-box;">1</span>px <span class="hljs-hexcolor" style="box-sizing: border-box; color: rgb(0, 136, 0);">#aaa</span></span></span>; <span class="hljs-rule" style="box-sizing: border-box;">}</span></span> <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">/*必选表单激活效果*/</span> <span class="hljs-tag" style="box-sizing: border-box;">input</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:required</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:focus</span>, <span class="hljs-tag" style="box-sizing: border-box;">select</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:required</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:focus</span>, <span class="hljs-tag" style="box-sizing: border-box;">textarea</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:required</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:focus</span> <span class="hljs-rules" style="box-sizing: border-box;">{ <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">outline</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);"> <span class="hljs-number" style="box-sizing: border-box;">0</span></span></span>; <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">box-shadow</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);"> <span class="hljs-number" style="box-sizing: border-box;">0</span> <span class="hljs-number" style="box-sizing: border-box;">0</span> <span class="hljs-number" style="box-sizing: border-box;">2</span>px <span class="hljs-number" style="box-sizing: border-box;">1</span>px <span class="hljs-hexcolor" style="box-sizing: border-box; color: rgb(0, 136, 0);">#aa0088</span></span></span>; <span class="hljs-rule" style="box-sizing: border-box;">}</span></span></code>
这两个伪类分别选中表单属性值在范围内、范围外两个状态,这两个伪类可以用在接受数字范围的元素上,例如type为number的表单或者sliders。案例效果如上面“案例欣赏”版块所示,我们这里仅仅展示核心代码,借以帮助大家理解两个伪类的使用。
<code class="language-css hljs " style="box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; padding: 0.5em; color: rgb(0, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; display: block; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-tag" style="box-sizing: border-box;">input</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:out-of-range</span><span class="hljs-rules" style="box-sizing: border-box;">{ <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">border</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);"> <span class="hljs-number" style="box-sizing: border-box;">1</span>px solid tomato</span></span>; <span class="hljs-rule" style="box-sizing: border-box;">}</span></span> <span class="hljs-tag" style="box-sizing: border-box;">input</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:in-range</span>~ <span class="hljs-tag" style="box-sizing: border-box;">label</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">::after</span> <span class="hljs-rules" style="box-sizing: border-box;">{ <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">content</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);"> <span class="hljs-string" style="box-sizing: border-box;">"输入一个正确的从1到10的数字"</span></span></span>; <span class="hljs-rule" style="box-sizing: border-box;">}</span></span> <span class="hljs-tag" style="box-sizing: border-box;">input</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:out-of-range</span> ~ <span class="hljs-tag" style="box-sizing: border-box;">label</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">::after</span> <span class="hljs-rules" style="box-sizing: border-box;">{ <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">content</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);"> <span class="hljs-string" style="box-sizing: border-box;">"枣糕,你傻了!"</span></span></span>; <span class="hljs-rule" style="box-sizing: border-box;">}</span></span></code>
这两个伪类针对具有type的input表单而立,比如有一个type=email的表单,当它的值不是有效的邮箱格式时触发:invalid伪类,值为有效的邮箱格式时触发:valid伪类。
同样,放在了codepen,请在线研究或下载收藏,然后我们来看看核心代码,如下所示。
<code class="language-css hljs " style="box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; padding: 0.5em; color: rgb(0, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; display: block; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-tag" style="box-sizing: border-box;">input</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:invalid</span><span class="hljs-rules" style="box-sizing: border-box;">{ <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">border</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);"> <span class="hljs-number" style="box-sizing: border-box;">1</span>px solid tomato</span></span>; <span class="hljs-rule" style="box-sizing: border-box;">}</span></span> <span class="hljs-tag" style="box-sizing: border-box;">input</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:valid</span>~ <span class="hljs-tag" style="box-sizing: border-box;">label</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">::after</span> <span class="hljs-rules" style="box-sizing: border-box;">{ <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">content</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);"> <span class="hljs-string" style="box-sizing: border-box;">"耶,一个邮箱!"</span></span></span>; <span class="hljs-rule" style="box-sizing: border-box;">}</span></span> <span class="hljs-tag" style="box-sizing: border-box;">input</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">:invalid</span> ~ <span class="hljs-tag" style="box-sizing: border-box;">label</span><span class="hljs-pseudo" style="box-sizing: border-box; color: rgb(136, 136, 255);">::after</span> <span class="hljs-rules" style="box-sizing: border-box;">{ <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">content</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);"> <span class="hljs-string" style="box-sizing: border-box;">"枣糕,邮箱邮箱,是邮箱吗?"</span></span></span>; <span class="hljs-rule" style="box-sizing: border-box;">}</span></span></code>
下面这些元素可以激活:read-only伪类。
例如下面代码代码所示的元素,都可以激活:read-only伪类选择器。
<code class="language-html hljs " style="box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; padding: 0.5em; color: rgb(0, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; display: block; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-tag" style="box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">input</span> <span class="hljs-attribute" style="box-sizing: border-box;">type</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"text"</span> <span class="hljs-attribute" style="box-sizing: border-box;">disabled</span>></span> <span class="hljs-tag" style="box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">input</span> <span class="hljs-attribute" style="box-sizing: border-box;">type</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"number"</span> <span class="hljs-attribute" style="box-sizing: border-box;">disabled</span>></span> <span class="hljs-tag" style="box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">input</span> <span class="hljs-attribute" style="box-sizing: border-box;">type</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"number"</span> <span class="hljs-attribute" style="box-sizing: border-box;">readonly</span>></span> <span class="hljs-tag" style="box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">textarea</span> <span class="hljs-attribute" style="box-sizing: border-box;">name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"nm"</span> <span class="hljs-attribute" style="box-sizing: border-box;">id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"id"</span> <span class="hljs-attribute" style="box-sizing: border-box;">cols</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"30"</span> <span class="hljs-attribute" style="box-sizing: border-box;">rows</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"10"</span> <span class="hljs-attribute" style="box-sizing: border-box;">readonly</span>></span> <span class="hljs-tag" style="box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">textarea</span>></span> <span class="hljs-tag" style="box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">div</span> <span class="hljs-attribute" style="box-sizing: border-box;">class</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(136, 0, 0);">"random"</span>></span> <span class="hljs-tag" style="box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">div</span>></span> <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);"><!-- regular element that is not editable with contenteditable --></span></code>
:read-write元素恰恰与:read-only元素相反。
这个比较简单,就不再做案例。谢谢。
上述的几个伪类选择器在标准浏览器(chrome、safari、opera、firefox)里支持良好,IE支持不好。