美化表单的CSS高级技巧

发布于 大漠

学习一些新的和旧的选择器,你可以根据需求、有效性和更多的方式来美化表单。

表单一直以来对于CSSer来说都是一件不易的事情,很难用CSS处理好表单要样式。但是有一些很少使用的选择器,却赋予我们不一样的能力,可以让我们很好的控制input元素和其周边元素的样式,而且是根据功能来调整不同的样式,这些往往都是通过JavaScript辅助完成的。而这些选择器中有一些是较新的,而另一些是老的选择器,只不过没有过多的被重视,甚至没什么人使用。以至于这么强大的功能就这样被忽视。

先来看一个示例:

:placeholder-shown

美化表单的CSS高级技巧

第一个要介绍的选择器相对较新的,还没有完全得到浏览器的支持。然而,这似乎可以轻松地作为一个渐进的增强工作。选择器允许我们检测用户当前是否可见占位符。如果我们想动态的隐藏和显示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

美化表单的CSS高级技巧

使用此选择器表示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

美化表单的CSS高级技巧

这个选择器执行和:required相反的操作。我再次使用了一个.help-textspan标签。如果所需的属性不存在,可显示一些文本。

input:optional + .help-text::before {
    content: '*Optional';
}

:disabled

美化表单的CSS高级技巧

这个对于大多数人来说应该很熟悉,但仍然要记住。input是否对用户禁止输入是非常重要的:

&:disabled {
    border-color: var(--gray-lighter);
    background-color: var(--gray-lightest);
    color: var(--gray-light);
}

:read-only

美化表单的CSS高级技巧

disabledinput相比,readonlyinput传达的含义应该稍有不同。幸运的是,我们有这个选择器来帮助我们做样式上的区别。

<!-- 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

美化表单的CSS高级技巧

虽然很多表单的验证都是使用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

美化表单的CSS高级技巧

根据本地浏览器验证规则,如果输入的内容是无效的,比如,输入的电子邮件地址不是真正的电子邮件地址。通过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-textspan元素的伪元素::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

美化表单的CSS高级技巧

这些选择器用来检测numberinput输入的值是否是minmax指定范围内的值。

<!-- 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

美化表单的CSS高级技巧

这个选择器对于大多数人来说并不陌生。在制作自定义复选框和单选按钮的样式时,这个选择器能够很好的帮助我们检测到复选框和单选按钮被选中的状态,再设置选中的样式。示例中的复选框和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

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。

如需转载,烦请注明出处:https://www.fedev.cn/css/advanced-css-form-styling.htmlIrene Garcia Noren