小小的按钮,设计起来不简单——设计师不知道的那些「坑」
按钮看似简单的元素,设计时的坑儿真不少。
产品设计中,按钮起着功能承上启下的作用,是交互量最大的元素之一,也是最基本的页面元素,但是在设计工作中,有些点常常被我们忽略,以下是前端开发实践中常常遇到的一些问题。
一、长得都一样,行为大不同
不管你设计成什么样子的按钮,落实到web前端代码,常常使用<button>标签和<a>标签来表示,不管用那个标签,都可以呈现出一摸一样的按钮样式:

如上图,两个一样的按钮,第一个用<button>标签实现,第二个用<a>标签实现。虽然看起来完全一样,但是点击后的作用却可以完全不同。

<button> 标签顾名思义,定义一个按钮。它常用于表单提交、确认或取消、搜索、点赞、保存等浏览器不需要 页面跳转 或 刷新 的功能上。

z站的保存按钮用的button属性的input标签
<a> 标签用于定义超链接,用于从一个网页链接跳转到另一个页面,表现为浏览器打开新的窗口或者当前页面刷新加载成另一个页面。常用于导航、登录注册、查看更多等。

a标签按钮点击后跳转新页面
由于它们有一个重要的共同点,交互方式都是点击,所以不少的同学在设计的时候并没有在UI层面加以区分,这不仅导致前端同学开发的时候有所混乱,也更容易让产品的体验不符合用户的心智模型:同一样式的按钮,这里点击可能是浏览器跳转新页面,哪里点击可能是弹出一个弹框来。

那么我们应该如何从设计上进行区分呢?
这里抛砖引玉提供一个小方法:
首先从功能性上进行思考,即点击后的结果是什么?是跳转新页面还是提交数据等?
然后只需要在样式上做一点点的差异化设计,让用户从视觉层面感知点击后行为的不同,就会让用户建立有箭头的就会跳转或打开新页面的认知,同时也会让前端开发的同学更清楚什么时候用<button>,什么时候用<a>标签。
![]()

这里分享一个小技巧,当打开一个浏览器页面,鼠标移到一个按钮时,如果浏览器左下角出现如图所示的一段连接地址,说明使用的<a>标签,是连接,点击后浏览器通常会跳转或页面刷新。

二、缺少padding概念的按钮设计
为什么我设计的按钮宽度都是统一的,但是前端实现后就不统一了?
如图:

设计同学常常为了视觉的统一而将按钮设计如上图左所示,而前端同学开发后却变成了右图。
造成这种情况的原因是,sketch等软件在对按钮进行组件化的时候,并没有内间距padding的概念,而这个padding是前端写按钮的一个重要的样式属性。
什么是padding呢?
如下图所示,对于按钮这个组件可以理解为,文字和案例框边界的间距。

如上图,前端同学在开发的时候则可以设置按钮的左右padding = 80px,这里文字是16px大小,文字之间字距为0,4个字所占宽度为16*4=64px,边框为1px内边框不占空间,所以按钮的长度应该是:80*2+16*4=224px
对前端开发来说,一组组件化的按钮字体大小、左右padding通常都是统一固定的,他们的长度是根据按钮字数内容多少来决定的,而无法像设计稿上那样拖一拖就能搞定的。
如果非要像设计稿那样,强制让按钮宽度一样也是没问题的,无非就是前端同学多花几分钟时间多写几句代码,但遇到问题都这样处理,项目将变得越来越不可维护,拖低整个开发效率,让bug频出,从而影响整个项目的生命周期。
除非极特殊的情况,为了便于项目的可维护性,相同高度的按钮不要有多个padding值。

而sketch等软件里面,按钮的长度通常都是设计师靠感觉拖拽出来的,padding值并不标准,同时前端同学开发的时候,常常也是从“看起来差不多”,给按钮一个大概的padding值。

所以创建按钮组件的时候,一定要明确标注按钮的padding值,让前端同学有据可依进行开发。
最小宽度min-width
那么要实现设计图那样,四个字和两个字的按钮,让他们长度都一样应该怎么办呢?
你只需要为前端同学标注出最小长度min-width即可。如图:

如图所示,蓝色部分为4个文字所占宽度,假如我们字体是14px,左右padding是16px,按钮没有外边框。
如果不设置最小宽度,那么2个字的按钮宽度为:14*2+16*2=60px,既两个字+左右两padding的长度。
现在我要让4个字的按钮和2个字的按钮长度一样,我们只需将4个字的按钮长度做为最小长度值即可:14*4+16*2=88px,前端这样定义后,只要按钮文字小于等于4,按钮的长度都是88px,如果超出了4个字,比如5字,那么按钮的长度为88 +14=102,如果超出n个字,按钮会自动延长为88+14*n。

行内按钮和块级按钮
如果将上文中按照自身内容多少而撑开宽度的按钮称之为「行内按钮」,那么还有另一种按照外围空间自动撑大的按钮,叫「块级按钮」。
块级按钮,他们通常会自动撑满一行空间,随着屏幕或者所在区域的宽度自适应变化,常用于外围空间较窄的区域,比如移动端,如下图所示:

或者这样:

这种按钮通常只需注明最小padding即可,既当屏幕足够大时,按钮内容和左右边框间距会自动伸长占满空间,当屏幕缩小,左右间距会自动压缩,直到等于设定的padding值为止,这样可以有效的保证按钮的可点击范围和视觉效果。
行内元素是向内收缩的,一排可以多个。

块级元素是向外膨胀的,一个就占一排。

按钮的边框
前面有提到按钮的边框为内边框所以不占空间,既然有不占空间的内边框,当然有占空间的外边框,如果你设计的按钮是有边框的,那么一定要明确是内边框还是外边框。

如图,边框厚度5px,颜色rgb(0,0,0),透明度16%。能明显看出外边框比内边框所占空间更多。
如果你是用sketch进行设计,会发现图层边框属性有三个:内部、居中、外部,而新建图层时,默认是选中居中的,那么请注意,前端开发中,默认都是内部边框,可以设置成外边框,但是没有居中边框这个属性!

如果使用外边框,则按钮的长度 = padding*2+内容长度+边框厚度*2
设计实践中,良好的交互反馈会让用户建立一种一直点一直爽的控制感,我们通常会为按钮设计三种状态样式:自然态(normal)、鼠标移入(hover)、点击态(active),但其实还有一个重要的状态被我们忽略了。
交互状态:
normal:自然态,既没有产生交互时的常规状态。
hover:鼠标指针或手指移入按钮时的样式状态。
active:鼠标指针或手指点击按钮时的样式状态。
focus:屏幕获取焦点的状态。
linked:连接点击后样式状态。

focus(聚焦)是常常被忽略的交互反馈状态。
focus(聚焦)主要用于习惯使用键盘访问的用户或者部分残障人士,用tab键代替鼠标对网页进行访问,当对网页点击 tab键时,正常的反应应该是,可点击或者可输入的部分会出现蓝色的边框,然后可以通过回车键代替点击(可以打开bai度试试),而聚焦时蓝色的模糊边框样式是浏览器默认给予的样式,是可以改变的!
如图 阅读全文按钮,浏览器默认的focus样式:

谷歌material自定义的focus状态样式:

focus(聚焦)在用户体验可行性设计上,是一个非常重要的交互反馈,然而由于设计师或者前端同学的忽视,许多网站直接将focus聚焦的交互样式去除了,导致使用tab键无法获取聚焦反馈。大家可以打开一些常用的网站试一试。
通常系统默认的聚焦样式都是蓝色阴影边框,这个样式是可以自定义的,建议在递交设计稿给前端同学进行开发时,要对应注明一下focus样式,否则很可能会被前端同学直接将样式去掉。
linked用于链接点击后样式
在新闻博客或者搜索引擎等站点,有许多可点击的标题列表,点击新页面打开,如果设计时定义了这些链接的linked属性,那么被点击过的标题或者链接按钮可以用样式进行区分,以告知用户那些链接是「已阅」的。
结合上文,linked样式属性只能针对「链接」类型,即<a>标签。

最后总结一发:
1.按钮要从功能行为上区分是否为链接,从设计上进行一定区分更易符合用户心智模型。
2.行内按钮是向内收缩的宽度是由内容、padding、外边框共同决定的。
3.行内按钮可以设置最小宽度min-width,让字数不同的部分按钮宽度一致。
4.块级按钮宽度会自动撑满所在的区域,长度与所在区域有关。
5.边框要明确是内边框还是外边框,不要用居中边框,因为前端无法实现。
6.按钮常见的交互行为样式除了hover、active外,还有常常忽视的focus聚焦样式。
7.为了区分链接是否已经点击过,可以为链接设计linked状态样式。














































































