构想
按钮组件是UI库中最基础的组件之一,所以这个组件应该尽可能灵活地提供可配置项,那我们怎样才能轻松便捷地去配置按钮呢?有两种方法,一种是通过js去获取按钮的属性,从而为不同类型的按钮加上相应的样式,第二种则是通过css的选择器去匹配所配置的样式,从而利用样式去控制按钮的表达,很明显第二种方案能将按钮组件从js中剥离解耦,更加能达到理想中的效果。
使用纯css去控制按钮基本上就可以满足业务的开发,不要担心这个问题,除非是一些非常定制化的需求。
按钮的设计
基础结构
首先,根据想要达到的效果,可以这样去写一个按钮
//btn.html
<button className="btn-normal">SluckyUI</button>
//btn.css
.btn-normal{
display: inline-block;
border-radius: 3px;
text-align: center;
cursor: pointer;
outline: none !important;
position: relative;
overflow: hidden;
border: none;
}
很简单,一个按钮就这样成型了。
但新的问题又出现了,在平常的业务开发中,这样一个简单的按钮是不足以支撑开发的,因为一个功能完备的按钮通常会有一些额外的属性和状态,比如等待状态,比如禁止点击状态。然而css伪类是无法去‘监听’这些状态的生命周期的,那应该怎么办呢?
答案就是通过属性去控制按钮的状态(类似于暴露一个接口,只不过这个接口是由css去实现的)
//btn.css
[loading='true']{
width: 25px;
height: 25px;
animation: loadingTypeA infinite .75s linear;
border: 2px solid #888;
border-top-color: transparent;
border-radius: 100%;
}
[disabled='true']{
...
}
@keyframes loadingTypeA {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
//btn.html
<button className="btn-normal" loading='true'>SluckyUI</button>
这样我们就可以通过loading属性的值去控制按钮的样式(状态),无论在react还是vue,angular中,我们都能很轻松地去控制。当然到这个步骤就并非纯css了,我们需要在业务逻辑中去控制这个组件,毕竟这些组件的生命周期状态是无法单靠css去走完一个完整的流程的。
Note:虽然可以通过样式去灵活配置所需的效果,但还是建议在同一套UI中统一制定出s,m,l三种size,这样更能在团队中配合使用。
动画特效
动画特效是组件必不可少的交互之一,能给与用户良好的交互体验。而几乎所有的效果都可以封装成css类。
//animate.scss
//下划线动画,因为已经与具体的组件完全解耦,这些动画可以用在任何组件中,后面会有专门的章节聊一聊神奇的动画
.regularLineMove {
&::before {
content: "";
position: absolute;
right: 0;
bottom: 0;
width: 0;
height: 1px;
background-color: #000;
transition: .2s all;
}
&:hover::before {
left: 0;
width: 100%;
}
}
//btn.html
<button className="btn-normal regularLineMove">SluckyUI</button>
按钮加上regularLineMove动画类之后,当鼠标悬浮上去,就会有下划线效果出现了。
但为什么说是几乎所有效果呢?因为仅靠css无法对display设置为none前作出有效的响应,比如淡出效果。细节会在弹窗篇里讲到。
进一步完善我们的按钮
一个完善的按钮组件应该能应对大部分情况,减轻我们的开发量。 比如当按钮处于disabled状态时,鼠标应该要显示一个禁止的标志,并且按钮颜色也应该要做出相应的改变等等。下面我们将大部分可能遇到的情况封装一下。
// btn.scss
.btn-status {
//鼠标普通悬浮
cursor: pointer;
//禁止状态
&:disabled {
cursor: not-allowed;
background-color: $disable !important;
}
//点击后的状态
&:active {
opacity: .8;
}
//将不美观的样式去除
outline: none !important;
&:focus {
outline: none !important;
}
...
}
Bingo,就这样button组件就基本设计好了,其实并不复杂,就是要考虑的情况比较多。
结尾
这些组件的想法已经实践到了 SluckyUI 当中,更多有趣的按钮效果能在 SluckyUI 首页的按钮标签中能找到,还有很多欠缺的地方,欢迎多多交流。以后会有更多新奇好玩的东西越来越多地融入其中。
从零开始系列传送门
- 《Re从零开始的UI库编写生活之规范制定》
- 《Re从零开始的UI库编写生活之按钮》
- 《Re从零开始的UI库编写生活之表单》
- 《Re从零开始的UI库编写生活之表格》
- 《Re从零开始的UI库编写生活之加载进度条》
- 《Re从零开始的UI库编写生活之分页》
- 《Re从零开始的UI库编写生活之菜单导航栏》
- 《Re从零开始的UI库编写生活之消息弹窗》
- 《Re从零开始的UI库编写生活之步骤管理器》
- 《Re从零开始的UI库编写生活之面包屑》
- 《Re从零开始的webpack4实用向全实践》
- 《Re从零开始的高效React+Redux项目架构搭建》
- Re从零开始的后端学习之配置Ubuntu+Ngnix+Nodejs+Mysql环境