CSS 中的简单微交互(第二部分):多状态按钮
先简单介绍一下,这是我的 CSS 微交互文章(或者说微教程)的第二部分。我知道我花了很长时间才终于写到第二部分,但生活真是太疯狂了!
最后一部分专门介绍所有响应式网站和网络应用程序的明星——汉堡图标。
如果您对汉堡图标不是特别感兴趣,让我们来回顾一下微交互是什么(有点像诗歌,嗯,差不多):
微交互是一种克制的练习,用尽可能少的资源做尽可能多的事情。拥抱这些限制,专注于做好一件事。——丹·萨弗
你可能已经从标题猜到了,本部分将讨论按钮——任何网站或应用都离不开它。按钮也是UI中最古老的元素之一,多年来经历了许多视觉变革,从最初的简单方形和小阴影,到3D阶段、扁平化设计时代,再到现在的Material Design外观。现代框架也允许使用按钮作为状态传达器,这正是我们将要探讨的用例。
提醒一下,我正在使用 Slim 和 SCSS,但您始终可以从 codepen 示例中编译并获取 HTML 和 CSS!
多状态按钮
由于实现这样的按钮需要更多精力,而且其他用例在状态切换方面基本上都类似(例如,下载 -> 下载中 -> 完成,或者像 Netflix 那样跳过:禁用 -> 加载中 -> 跳过),所以我们只介绍一个例子。在本例中,我们主要关注消息或电子邮件的发送按钮。
首先,我们将三种可能状态的文本值添加到 DOM 中,然后调整它们的可见性和位置。大多数情况下,你还需要第四种状态来表示错误,但为了简化本例,我不会这样做。
那么让我们仔细看看我们需要做什么。
- 添加图标元素
- 添加 3 个文本值
- 为按钮背景颜色提供 3 种样式
- 根据状态显示单独的图标、切换文本值和背景
按钮的结构如下:
button.button.button--default
.button__icon-wrapper
.button__icon
.button__text-wrapper
.button__text.button__text--default Send
.button__text.button__text--process Cancel
.button__text.button__text--success Sent!
基本样式(您可以在这里查找颜色名称):
.button {
font-size: 1.2em;
text-align: left;
padding: 0.8em 1.4em;
border-radius: 2em;
cursor: pointer;
font-family: 'Montserrat', sans-serif;
font-weight: 600;
border: 0;
color: WHITE;
line-height: 1.6em;
transition: background-color 300ms ease-in-out;
&:focus {
outline: 0;
}
&--default {
background-color: CORNFLOWERBLUE;
}
&--process {
background-color: MEDIUMSLATEBLUE;
}
&--success {
background-color: DARKTURQUOISE;
}
}
最后,让我们添加一个简单的脚本来在 onClick 事件中切换类。在实际应用中,你可能希望类的切换事件由其他事件触发,而且很可能以完全不同的方式触发,但目前我们只使用setTimeout()
。
const button = document.querySelector('.button');
button.addEventListener('click', function(){
button.classList.remove('button--default');
button.classList.add('button--process');
setTimeout(function() {
button.classList.remove('button--process');
button.classList.add('button--success');
}, 2000);
setTimeout(function() {
button.classList.remove('button--success');
button.classList.add('button--default');
}, 4500);
})
此时,您应该有一个带有垂直堆叠文本的按钮,它将onClick
开始改变颜色(和类别):
现在是时候操作文本切换了,我们将为每个元素设置绝对定位.button__text__wrapper
,并根据当前活动的类切换它们的不透明度和变换。
默认值是opacity: 0;
、 和transform: translateY(20px);
,这将为我们带来漂亮的从底部淡入淡出的动画效果(参见下一段)。
&__text-wrapper {
position: relative;
display: inline-block;
width: 120px;
height: 1.6em;
vertical-align: top;
}
&__text {
position: absolute;
opacity: 0;
transform: translateY(20px);
transition: all 250ms ease-in-out;
}
现在是时候根据 中的活动类应用转换了.button
,我们需要将所需的文本转换为transform: translateY(0);
并设置opacity: 1;
,仅此一项就能提供足够漂亮的淡入效果。但如果之前的文本能够淡出,并赋予我们额外的维度感,那就更好了。我们将通过定位之前的类并将其淡出来实现这一点。您始终可以使用选择器或 JavaScripttransform: translateY(-20px);
来定位这些类,但为了简单起见,我更喜欢使用类。nth
&--default {
background-color: CORNFLOWERBLUE;
.button__text--default {
opacity: 1;
transform: translateY(0);
}
.button__text--success {
transform: translateY(-20px);
}
}
&--process {
background-color: MEDIUMSLATEBLUE;
.button__text--process {
opacity: 1;
transform: translateY(0);
}
.button__text--default {
transform: translateY(-20px);
}
}
&--success {
background-color: DARKTURQUOISE;
.button__text--success {
opacity: 1;
transform: translateY(0);
}
.button__text--process {
transform: translateY(-20px);
}
}
在这个阶段,你应该已经有一个良好的互动
为了完善我们超酷的发送按钮,我们来添加一个变形图标。我们将使用纯 CSS 的方式,但你也可以使用 SVG。
首先,我们将设计我们的.button__icon-wrapper
和首字母.button__icon
(嵌套在我们的.button
)
&__icon-wrapper {
width: 1.6em;
height: 1.6em;
margin-right: 1em;
display: inline-block;
vertical-align: top;
}
&__icon {
transition: all 300ms ease-in-out;
display: block;
box-sizing: border-box;
}
基础准备好后,我们就开始为每个图标添加样式。首先是一个简单的插入符号,我们将它添加到&--default
类中。我们只需创建一个正方形元素,添加顶部和右侧边框,然后旋转它即可。
.button__icon {
width: 1em;
height: 1em;
margin: 0.3em 0.5em 0.3em 0;
border-right: 3px solid white;
border-top: 3px solid white;
transform: rotate(45deg);
}
对于&--process
,事情会变得稍微棘手一些,因为我们需要创建一个简单的加载图标。我们将利用 来实现。您可以在这里clip-path
阅读更多相关信息。然后,我们将使用关键帧为整个元素添加动画效果,使其旋转并营造出旋转的视觉效果。
.button__icon {
width: 1.2em;
height: 1.2em;
margin: 0.2em 0.5em 0.2em 0;
border-radius: 100px;
border: 3px solid white;
animation: loading 1s infinite ease;
clip-path: polygon(100% 0, 50% 50%, 100% 100%);
}
关键帧:
@keyframes loading {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
最后,让我们创建成功图标,一个简单的勾选标记,类似于我们创建角度图标的方式。不过,我们再旋转一下,360deg
让它更平滑地过渡回默认状态,并应用使用 的显示动画clip-path
,本质上它会先显示底部边框,然后移动到 100% 的高度。
您可以使用clippyclip-path
进行调整。一旦我们应用旋转,它就会沿着勾选标记线显示图标。 如果没有旋转,很难实现从之前的图标平滑过渡。
在里面&--success
我们添加:
.button__icon {
margin: 0 0.3em 0.3em 0.1em;
height: 1.2em;
width: 0.9em;
border-radius: 0;
border-right: 3px solid white;
border-bottom: 3px solid white;
transform: rotate(405deg);
animation: reveal 500ms ease-in;
}
关键帧(我们还将添加轻微的不透明度过渡):
@keyframes reveal {
0% {
opacity: 0;
clip-path: polygon(0 85%, 0 85%, 0 100%, 0 100%);
}
40% {
opacity: 0;
}
50% {
opacity: 1;
clip-path: polygon(0 85%, 100% 85%, 100% 100%, 0 100%);
}
100% {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
}
我们的多状态按钮已经准备好了!
当然,在实际生产环境中使用它时,你应该确保类的切换和处理方式万无一失!你还想看看其他微交互吗?如果有,请告诉我,我的下一篇文章可能就是关于这个的!
文章来源:https://dev.to/saintasia/easy-micro-interactions-in-css-pt2-multi-state-button-1kpi