使用 Sass 美化表单控件
表单控件在网页设计中无疑是占有重要地位的。由于表单控件是用户频繁使用到的页面元素,所以有必要使用 Sass 来快速美化项目中的表单控件。
占位符
占位符,可以用来提示用户当前输入框所需要的信息。只有当 type
类型为 text
,search
,tel
,url
或 email
时,表单控件的占位符属性才会生效,其他类型下会被自动忽略。不足之处在于,使用占位符需要配合恰当的浏览器伪元素前缀,所以,开发者需要手动为主流浏览器添加前缀,包括 IE,Firefox,Safari,Chrome 和 Opear。
占位符混合宏示例
占位符混合宏可以应用到形形色色的上下文环境中,就可以独立使用,也可以配合其他选择器使用。此外,我还声明了一个 Sass map,用来配置所需的样式。
index.html
<label for=“username”>Name</label>
<input type=“text” name=“username” id=“username” placeholder=“first, last”>
_placeholder-mixin.scss
在下述的混合宏中,@at-root
指令被用来将嵌套的样式声明到选择器链的最外层。
**注意:**本文发布时,由于解析插值存在的问题(比如 @at-root #{&}#{$pseudo}
),node-sass 尚不能编译占位符选择器。
$pseudo-phprefix: “::-webkit-input-placeholder” “::-moz-placeholder” “:-ms-input-placeholder” “::placeholder”;
$ph-styles: (
font-family: sans-serif,
font-size: medium,
font-style: normal,
font-weight: normal,
color: inherit,
letter-spacing : normal,
line-height: normal,
text-align: inherit,
text-decoration: inherit,
padding: 0
);
@mixin placeholder-theme($styles) {
@each $pseudo in $pseudo-phprefix {
@at-root #{&}#{$pseudo} {
@each $key, $value in $styles {
#{$key}: #{$value};
}
}
}
}
@mixin placeholder {
@each $pseudo in $pseudo-phprefix {
@at-root #{&}#{$pseudo} {
@content
}
}
}
定义完必须的混合宏之后,我们就可以独立地引用这些混合宏,使其根据参数将所有的占位符渲染为统一的风格。上面的第二个混合宏可以按需配置特定的选择器,同时也无需加载全局的统一样式。
_placeholder-mixin.scss
@include placeholder { color: red; }
input {
@include placeholder-theme($ph-styles);
}
CSS Output
::-webkit-input-placeholder {
color: red;
}
::-moz-placeholder {
color: red;
}
:-ms-input-placeholder {
color: red;
}
::placeholder {
color: red;
}
input::-webkit-input-placeholder {
font-family: sans-serif;
font-size: medium;
font-style: normal;
font-weight: normal;
color: inherit;
letter-spacing: normal;
line-height: normal;
text-align: inherit;
text-decoration: inherit;
padding: 0;
}
input::-moz-placeholder {
font-family: sans-serif;
font-size: medium;
font-style: normal;
font-weight: normal;
color: inherit;
letter-spacing: normal;
line-height: normal;
text-align: inherit;
text-decoration: inherit;
padding: 0;
}
input:-ms-input-placeholder {
font-family: sans-serif;
font-size: medium;
font-style: normal;
font-weight: normal;
color: inherit;
letter-spacing: normal;
line-height: normal;
text-align: inherit;
text-decoration: inherit;
padding: 0;
}
input::placeholder {
font-family: sans-serif;
font-size: medium;
font-style: normal;
font-weight: normal;
color: inherit;
letter-spacing: normal;
line-height: normal;
text-align: inherit;
text-decoration: inherit;
padding: 0;
}
**提醒:**不要使用占位符属性替代标签元素。这两者之前存在明显的差异:标签元素用来描述表单空间的角色定位,提示当前表单控件的信息类型;占位符属性则是用来提示内容的格式。由于各种原因,占位符属性并不一定会展示给用户,所以必须设想没有占位符属性时的用户体验。
占位符跳跃动效
这动效棒极了!稍有不足的是只能在基于 WebKit/Blink 引擎的浏览器下有效果。由于其首次亮相时吸引众人热论的动效表现,也有人称之为 “Floating Label”。
index.html
<label for=“phone”>Cell Phone</label>
<input type=“tel” name=“phone” class=“jpinput” id=“phone” placeholder=“(555) 555-5555”>
这个特效的魔力来源于来源于伪元素选择器 ::-webkit-input-placeholder[style*=hidden]
:一旦用户开始填写信息时,该选择器就可以修改占位符元素的状态。我非常期望找到适用于 Mozilla 的等效选择器,但这个愿望最终落空了。在本段的下方,我引用了 David Bushell 所实现的一种方式,该方式充分利用了伪元素选择器,但也存在一些其他的问题。
_js-input.scss
$jpinput-height: 40px;
$jpinput-radius: 4px;
$jpinput-padding: 10px 16px;
$jpinput-bg: #8DAA91;
$jpinput-color: #4F4137;
$jpinput-ph-color: $jpinput-color;
$jpinput-phide-color: $jpinput-bg;
input {
appearance: none;
box-sizing: border-box;
border-radius: $jpinput-radius;
display: inline-block;
outline: 0;
width: 100%;
}
.jpinput {
height: $jpinput-height;
padding: $jpinput-padding;
transition: transform 225ms ease-in-out;
background: $jpinput-bg;
color: $jpinput-color;
@include placeholder {
position: relative;
top: 0;
left: 0;
transition: all 300ms ease-in-out;
color: rgba($jpinput-ph-color, .5);
}
}
.jpinput::-webkit-input-placeholder[style*=hidden] {
transform: translateY(-$jpinput-height);
opacity: 1;
visibility: visible !important;
color: $jpinput-phide-color;
}
当然也有其他的方法可以实现这种动效,希望你能深入理解其中的优点和不足。即使不说你也会理解,有一种解决方案叫做 “JavaScript 无所不能系列”。更多参考资料:
- FloatLabels.js
- Tympanus TextInputEffects
- How the Float Label Pattern Started
- Float Label Pattern
- Form Label Design
- Float Labels Collection by Chris Coyier
- David Bushell Demo
Label
HTML 中的 Label 为界面中与之相关联的控件提供了一个标题,常用来提示当前空间所需的信息类型。
安全输入模式
当输入框失去焦点时,我们可以将 Label
标签拟化为一个滑动门,遮盖住输入框中的数据。这种动效既华丽又实用,可以隐藏类似信用卡号和安全码等隐私数据。该示例中同样使用了上述的混合宏。随你喜欢,Label
可以放在控件前后左右的任意位置。
index.html
<div class=“slabel”>
<input id=“credit-card” type=“text” pattern=“[0-9]{13,16}” placeholder=“xxxx-xxxx-xxxx-xxxx”>
<label for=“credit-card”>Credit Card</label>
</div>
_slabel-input.scss
$slabel-theme: (
border: 0,
radius: 0,
padding: 0,
font: inherit,
bg: white,
label-bg: white,
label-color: inherit,
error-color: #E82C0C,
placeholder-color: #B9E0D6,
success-color: #5C832F
);
更多有关 Label
的特效,点击这里!
输入框
输入框可以用来创建表单的交互控件或接收用户输入的表单数据。表单的输入框类型通常包括:文本、邮箱地址、数字、单选按钮、复选按钮,甚至是单纯的按钮类型。
下拉框
这一部分将会介绍一种简洁的方法美化下拉框,而不使用那些冗杂妥协的技巧。在大多数情境下,下拉框都是使用 JavaScript 设置为 display: none
,然后制成多个 div
而实现的。用户喜欢这样的表现,但是开发者对此会非常痛恨。在可以使用 CSS 实现相关样式之前,我认为下面的这个方法,无论是对于开发者还是用户,都具有一定的吸引力。它允许开发者为支持相关属性的浏览器做出合理的美化,又不会影响其他浏览器的渲染和体验。
index.html
<select>
<option>Property Closing*</option>
<option>open</option>
<option>closed</option>
</select>
_select-input.scss
$select-arrow: ‘data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDQ4IDQ4IiB3aWR0aD0iNDgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTE0LjgzIDE2LjQybDkuMTcgOS4xNyA5LjE3LTkuMTcgMi44MyAyLjgzLTEyIDEyLTEyLTEyeiIvPjxwYXRoIGQ9Ik0wLS43NWg0OHY0OGgtNDh6IiBmaWxsPSJub25lIi8+PC9zdmc+’;
$select-padding: 0;
select {
border-radius: 0;
-webkit-appearance: none; // autoprefixer won’t add this and we still need it
appearance: none;
cursor: pointer;
padding: $select-padding;
width: 100%;
@media screen and (-webkit-min-device-pixel-ratio: 0) {
background-image: url(#{$select-arrow});
background-position: right 0 top 50%;
background-repeat: no-repeat;
}
}
更多细节请阅读 Lea Verou 的文章,也可以查看 Tympanus 创建的下拉框特效集合。
单选按钮
单选按钮常用于选择一系列项目中的一个。相比较复选框可以选择多个选项,单选框只允许用户选择单一的选项。
下面的这个自定义单选按钮是基于 Sass 实现的,是对 Mark Otto 在 WTF,forms? 一文中单选按钮的改进版本。该版本中包含了一些使用 CSS 变形实现的定位技巧,并且具有良好的扩展性和定制能力。
index.html
<label for=“radioa” class=“input-control radio”>
<input type=“radio” id=“radioa” name=“radio” value=“radio-value”>
<span class=“input-control__indicator”></span> Send Me Stuff!
</label>
<label for=“radiob” class=“input-control radio”>
<input type=“radio” id=“radiob” name=“radio” value=“radio-value”>
<span class=“input-control__indicator”></span> Don’t send a friggin’ thing.
</label>
_input-radio.scss
$input-radius: 0 !default;
$input-unit: 16px !default; // accepts px, em, rem
$input-spacing: $input-unit * 1.5 !default; // adjust depending on font-family
$input-font: sans-serif !default;
$radio-bg: white !default;
$radio-txt-color: #AACCFF !default;
$radio-checked-custom: (
background: #0081D0
) !default;
$radio-checked: #222233 !default;
$radio-checked-focus: white !default;
更多特效请查看 Samurai 的单选输入框动效集合。
多选按钮
多选按钮的输入框类型为 checkbox
,描述了一种可触发的状态。
SVG Checkbox
下面的 SVG 多选按钮是由 Sara Soueidan 创建的,通过 svg
为创建后的按钮增加了 X
形状。该元素使用了 SVG 的 stroke-dasharray
和 stroke-dashoffset
属性,并辅以 CSS 动画属性实现了选择动效。除了根据 Sara Soueidan 的示例之外,我还添加了 :focus
状态和其他一些细节的优化,有助于开发者定义和扩展。
index.html
<input type=“checkbox” id=“optiona” name=“optiona”>
<label for=“optiona”>Click Me
<svg viewBox=“0 0 100 100” xmlns=“http://www.w3.org/2000/svg”>
<path d=“M 10 10 L 90 90”></path>
<path d=“M 90 10 L 10 90”></path>
</svg>
</label>
_checkbox-input.scss
$font-size: 2em; // adjust accordingly
$ratio: 1; // adjust accordingly
$size: $ratio + em;
$ratio: $ratio;
$gutter: 5px; // adjust accordingly
$stroke-dash: 270;
$stroke: (
thickness: $gutter/3,
style: solid,
color: #fff
);
$mark-ischecked: (
stroke-dashoffset: 0
); // define css properties
$label-ischecked: (); // define css properties
$svg-ischecked: (); // define css properties
滑动多选按钮
下面这个多选按钮曾被我用到了 Transformicons 项目中,看起来很像一个滑门。虽然它是基于 Sass 实现的,但在可复用的同时还很精简。值得注意的是,该动效还支持键盘操作:可以使用 tab
键选中该按钮,使用空格键来切换状态。
index.html
<div class=“slider-checkbox”>
<input type=“checkbox” id=“option” aria-checked=“false” role=“checkbox”>
<label for=“option”>Label Text</label>
</div>
在这个实例中使用 Sass 的全局变量,为开发者提供了两种样式:rounded
和 null
。使用 null
,可以取消按钮的 border-radius
属性,使其呈现一种方形。
_slider-checkbox.scss
$checkbox-style: rounded; // accepts ‘rounded’ or ‘null’
$checkbox-sizing-unit: 6rem; // adjust this value for sizing
$checkbox-height: $checkbox-sizing-unit / 1/4;
$checkbox-position-unit: $checkbox-sizing-unit * 3/4;
$checkbox-speed: 150ms;
$checkbox-off-bg: #E8DFE7;
$checkbox-on-bg: #4fbe79;
$checkbox-btn-bg: #FFFFFD;
有效性状态
有效性伪类选择器通常被用于交互元素,以验证用户的输入状态,最常用的就是::invalid
和 :valid
。下面的 Sass 混合宏就包含了这些状态。值得注意的是,当输入框中内容不存在或不符合要求时,:invalid
选择器都会生效。
@mixin valid {
&:valid,
&:empty:valid,
&:focus:empty:valid {
@content;
}
}
@mixin invalid {
&:invalid,
&:focus:invalid {
@content;
}
}
更多表单控件的伪类资料请参考参考这里。
:required
:optional
:enabled
:disabled
:not(:checked)
:in-range
:out-of-range
:user-error
:empty
:blank
总结
如果你想更深入的理解美化本地表单控件的技术,可以参考这个跨浏览器伪类选择器一揽子详细总结。如果你想学习更多有效性状态,那么可以深读 W3C 的官方文档。
本文根据@Dennis Gaebel的《Theming Form Elements with Sass》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://www.sitepoint.com/theming-form-elements-sass/。
如需转载,烦请注明出处:https://www.fedev.cn/preprocessor/theming-form-elements-sass.htmlnike air max 2019 dress