美化表单的CSS高级技巧
学习一些新的和旧的选择器,你可以根据需求、有效性和更多的方式来美化表单。
表单一直以来对于CSSer来说都是一件不易的事情,很难用CSS处理好表单要样式。但是有一些很少使用的选择器,却赋予我们不一样的能力,可以让我们很好的控制input
元素和其周边元素的样式,而且是根据功能来调整不同的样式,这些往往都是通过JavaScript辅助完成的。而这些选择器中有一些是较新的,而另一些是老的选择器,只不过没有过多的被重视,甚至没什么人使用。以至于这么强大的功能就这样被忽视。
先来看一个示例:
:placeholder-shown
第一个要介绍的选择器相对较新的,还没有完全得到浏览器的支持。然而,这似乎可以轻松地作为一个渐进的增强工作。选择器允许我们检测用户当前是否可见占位符。如果我们想动态的隐藏和显示input
对应的label
,这将非常方便。
在这里,用户在input
输入之前,label
是被隐藏的,而当input
在输入时,placeholder
被隐藏,label
可见。另外在label
上使用了transition
,让效果变得更美。请注意,对于这个效果,label
必须放在input
标签之后。
<!-- HTML -->
<div class="form-group">
<input type="text" id="dynamic-label-input" placeholder="Enter some text">
<label for="dynamic-label-input">Enter some text</label>
</div>
/* CSS */
.form-group {
position: relative;
padding-top: 1.5rem;
}
label {
position: absolute;
top: 0;
font-size: var(--font-size-small);
opacity: 1;
transform: translateY(0);
transition: all 0.2s ease-out;
}
input:placeholder-shown + label {
opacity: 0;
transform: translateY(1rem);
}
:required
使用此选择器表示input
具有required
属性。这里我还用了一个空的span
标签,并且给这个标签定义了一个.help-text
类名。使用::before
伪元素动态的添加一些内容。如果input
没有输入任何内容,提交表单时,这个.help-text
的::before
就会有内容显示出来。实际上,这是用JavaScript来完成的,但是这里我仅使用了CSS方法就实现了这个效果:
<!-- HTML -->
<label for="required-input">Required input</label>
<input type="text" id="required-input" required>
<span class="help-text"></span>
/* CSS */
input:required + .help-text::before {
content: '*Required';
}
:optional
这个选择器执行和:required
相反的操作。我再次使用了一个.help-text
的span
标签。如果所需的属性不存在,可显示一些文本。
input:optional + .help-text::before {
content: '*Optional';
}
:disabled
这个对于大多数人来说应该很熟悉,但仍然要记住。input
是否对用户禁止输入是非常重要的:
&:disabled {
border-color: var(--gray-lighter);
background-color: var(--gray-lightest);
color: var(--gray-light);
}
:read-only
与disabled
的input
相比,readonly
的input
传达的含义应该稍有不同。幸运的是,我们有这个选择器来帮助我们做样式上的区别。
<!-- HTML -->
<input type="text" value="Read-only value" readonly>
/* CSS */
input:read-only {
border-color: var(--gray-lighter);
color: var(--gray);
cursor: not-allowed;
}
:valid
虽然很多表单的验证都是使用JavaScript来完成,但是我们可以利用HTML5表单验证]。这个选择器使我们有机会对当前具有本地浏览器验证规则的任何input
进行样式美化。
如果input
输入的value
是符合要求的,也就是说有效的。在这里,我使用一个svg
,通过background-image
属性来设置input
有效的样式,input
有一个√
在右侧显示:
input:valid {
border-color: var(--color-primary);
background-image: url("data:image/svg+xml,%3Csvg width='45px' height='34px' viewBox='0 0 45 34' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cg transform='translate%28-56.000000, -59.000000%29' fill='%232EEC96'%3E%3Cpolygon points='70.1468531 85.8671329 97.013986 59 100.58042 62.5664336 70.1468531 93 56 78.8531469 59.5664336 75.2867133'%3E%3C/polygon%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A");
}
:invalid
根据本地浏览器验证规则,如果输入的内容是无效的,比如,输入的电子邮件地址不是真正的电子邮件地址。通过base64
,给input
添加一个x
的背景图,也同样放置在右侧。
input:invalid {
border-color: var(--color-error);
background-image: url("data:image/svg+xml,%3Csvg width='30px' height='30px' viewBox='0 0 30 30' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cg transform='translate%28-128.000000, -59.000000%29' fill='%23F44336'%3E%3Cpolygon points='157.848404 61.9920213 145.980053 73.8603723 157.848404 85.7287234 154.856383 88.7207447 142.988032 76.8523936 131.119681 88.7207447 128.12766 85.7287234 139.996011 73.8603723 128.12766 61.9920213 131.119681 59 142.988032 70.8683511 154.856383 59'%3E%3C/polygon%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A");
}
还可以为每种输入类型定制一些验证消息。同样使用.help-text
的span
元素的伪元素::before
来处理:
<!-- HTML -->
<label for="invalid-email">Invalid input</label>
<input type="email" id="invalid-email" value="notanemail">
<span class="help-text"></span>
/* CSS */
input[type='email']:invalid + .help-text::before {
content: 'You must enter a valid email.'
}
:in-range/:out-of-range
这些选择器用来检测number
的input
输入的值是否是min
和max
指定范围内的值。
<!-- HTML -->
<label for="out-of-range-input">Out-of-range input</label>
<input type="number" id="out-of-range-input" min="1" max="10" value="12">
<span class="help-text"> (value must be between 1 and 10)</span>
/* CSS */
input:out-of-range + .help-text::before {
content: 'Out of range';
}
:checked
这个选择器对于大多数人来说并不陌生。在制作自定义复选框和单选按钮的样式时,这个选择器能够很好的帮助我们检测到复选框和单选按钮被选中的状态,再设置选中的样式。示例中的复选框和label
放在一个容器中,并且label
放在input
后。
<div class="checkbox">
<input type="checkbox"/>
<label>Option</label>
</div>
在视觉上隐藏input
,让它从视图中消失,但仍然可以点击。然后使用label::before
看起来像复选框(未选中)和使用label::after
看起来像选中的复选框。我们使用:checked
的选择器将这两个伪元素添加适当的样式:
&:checked + label::before {
background-color: var(--color-primary);
}
&:checked + label::after {
display: block;
position: absolute;
top: 0.2rem;
left: 0.375rem;
width: 0.25rem;
height: 0.5rem;
border: solid white;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
content: '';
}
总结
这篇文章通过一些我们熟悉和不熟悉,甚至是从未见过的选择器。这些选择器能帮助我们对表单做更好的样式美化,甚至以前一些需要通过JavaScript来辅助完成的,也可以直接使用纯CSS来完成。是不是很有意思,如果你在这方面有更好的建议或经验,欢迎在下面的评论中与我们一起分享。
本文根据@HarrellofDurham 的《Advanced CSS-Only Form Styling》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:https://jonathan-harrell.com/advanced-css-form-styling。
如需转载,烦请注明出处:https://www.fedev.cn/css/advanced-css-form-styling.htmlIrene Garcia Noren