CSS Tips:用于按钮上的小技巧

URL:ui-buttons.web.app/

可以说,在 Web 应用或网站上,按钮无处不在。它们是 Web 页面和应用界面中最常见的元素之一,用于触发各种操作和交互。然而,在 CSS 中,我们可以通过各种技巧来改变按钮的外观和行为,使其更加灵活和易用。或许你会说,使用 CSS 给按钮设置样式,从而美化按钮的视觉效果,这是一件非常简单的事情。

真的是这样?如果你的答案不是百分百的肯定,那就对了。你也可以接着往下阅读。我将在接下来的内容中会和大家分享一些关于按钮的技巧(一些不太常见的 CSS),帮助你更好地掌握 CSS,并在设计中展现出更多的创意和可能性。

先从 HTML 开始

如果语义化的角度来说,为 Web 提供按钮,就应该使用 HTML 的 <button> 元素。然而,很多 Web 开发者并不太关注 HTML 语义化这个事情。因此,在 Web 应用或页面上,你可以看到千奇百怪的 HTML 元素用于制作按钮,比如:

HTML 复制代码
<button>我是一个真按钮</button>

<input type="button" value="我也是一个按钮" />

<a href="">我是一个链接,我也被当作按钮使用</a>

<span>其实就只是一个HTML标签,我与按钮没半毛钱关系</span>

当然,上面的示例,仅仅是冰山一角,还有很多其他的 HTML 标签用于制作按钮,比如 divsection 等等。

如果你在开发的过程中,也习惯性的使用非 <button> 元素来构建按钮的话,那么请你考虑 A11Y 相关的细节。例如,给元素添加 roletabindex 以及相关的 ARIA 等属性:

HTML 复制代码
<div id="save" tabindex="0" role="button" aria-pressed="false">save</div>

这样,你可以为更多的人提供平等的服务。

众所周知,按钮是一种小部件,用于执行操作,例如提交表单、打开对话框、取消操作或执行命令,如插入新记录或显示信息。添加添加 role="button" 告诉辅助技术(例如屏幕阅读器)该元素(div)是按钮,但不提供按钮功能(通常会使用 JavaScript 来模拟按钮的功能)。这意味着,如果你希望按钮是真的按钮,请使用原生的按钮标签,即 <button>typebutton<input>

HTML 复制代码
<button>我是一个真按钮</button>
<input type="button" value="我也是一个按钮" />

注意,如果使用 role="button" 而不是语义化的 <button><input type="button"> ,你需要让这个元素可聚焦并定义 clickkeydown 事件的事件处理器。简而言之,你要额外做的事情会很多,个人不建议使用非 <button> 标签元素来构建按钮。

在 Web 上,还有另一个争议,那就是就 Web 上的很多链接,它的 UI 外观看上去很像一个按钮,因此有了个"是按钮,还是链接?"的讨论,要是你想更深入的了解这方面的话题,请移步阅读 @Chris Coyier 的《A Complete Guide to Links and Buttons》一文,这里就不再做相关的阐述!

基于可访问性的原因,我们使用 button 来制作按钮:

HTML 复制代码
<button type="submit" class="button">Submit</button>

重置按钮默认样式

如果使用按钮控件来制作按钮,例如 <button><input type="button"> ,用户代理都会为它们设置一个初始化的样式。以 Chrome 浏览器为例:

CSS 复制代码
/* User Agent Stylesheet */
button {
    appearance: auto;
    font-style: ;
    font-variant-ligatures: ;
    font-variant-caps: ;
    font-variant-numeric: ;
    font-variant-east-asian: ;
    font-variant-alternates: ;
    font-variant-position: ;
    font-weight: ;
    font-stretch: ;
    font-size: ;
    font-family: ;
    font-optical-sizing: ;
    font-size-adjust: ;
    font-kerning: ;
    font-feature-settings: ;
    font-variation-settings: ;
    text-rendering: auto;
    color: buttontext;
    letter-spacing: normal;
    word-spacing: normal;
    line-height: normal;
    text-transform: none;
    text-indent: 0px;
    text-shadow: none;
    display: inline-block;
    text-align: center;
    align-items: flex-start;()
    cursor: default;
    box-sizing: border-box;
    background-color: buttonface;
    margin: 0em;
    padding-block: 1px;
    padding-inline: 6px;
    border-width: 2px;
    border-style: outset;
    border-color: buttonborder;
    border-image: initial;
}

/* User Agent Stylesheet */

input {
    font-style: ;
    font-variant-ligatures: ;
    font-variant-caps: ;
    font-variant-numeric: ;
    font-variant-east-asian: ;
    font-variant-alternates: ;
    font-variant-position: ;
    font-weight: ;
    font-stretch: ;
    font-size: ;
    font-family: ;
    font-optical-sizing: ;
    font-size-adjust: ;
    font-kerning: ;
    font-feature-settings: ;
    font-variation-settings: ;
    text-rendering: auto;
    color: fieldtext;
    letter-spacing: normal;
    word-spacing: normal;
    line-height: normal;
    text-transform: none;
    text-indent: 0px;
    text-shadow: none;
    display: inline-block;
    text-align: start;
    appearance: auto;
    -webkit-rtl-ordering: logical;
    cursor: text;
    background-color: field;
    margin: 0em;
    padding: 1px 0px;
    border-width: 2px;
    border-style: inset;
    border-color: -internal-light-dark(rgb(118, 118, 118), rgb(133, 133, 133));
    border-image: initial;
    padding-block: 1px;
    padding-inline: 2px;
}

input[type="button" i] {
    appearance: auto;
    user-select: none;
    align-items: flex-start;()
    text-align: center;
    cursor: default;
    box-sizing: border-box;
    background-color: buttonface;
    color: buttontext;
    white-space: pre;
    padding-block: 1px;
    padding-inline: 6px;
    border-width: 2px;
    border-style: outset;
    border-color: buttonborder;
    border-image: initial;
}

对应的按钮样式风格如下:

为了便于自定义按钮的 UI 样式,通常会给按钮设置 appearance 属性的值为 none

CSS 复制代码
.button {
    appearance: none;
}

这样做的最大好处是,它可以基于用户操作系统为按钮提供初始化 UI 样式,这个时候,你在不同的操作系统,不同的平台,看到的按钮风格是有所差异的:

上图是基于 OS 系统在不同浏览器下,按钮设置了 apperance:none 的 UI 效果!

如果你希望彻底从头开始给按钮定义样式,又担心自己遗漏覆盖默认样式,那么可以采用一种简单且粗暴的方式,将按钮的 all 属性设置为 unset

CSS 复制代码
.button {
    all: unset;
}

如此一来,按钮将不会带有任何 UI 效果:

CSS 的 unsetinheritinitialrevert 统称为 CSS 显式默认值,它可以很容易让你获得重置和继续属性默认值的方式:

如果你对这方面的知识感兴趣的话,个人建议你移步阅读《现代 CSS》中的《CSS 显式默认值:inhert 、initial 、unset 和 revert 》一文!

触摸操作

你是否曾经反复点击按钮,结果页面意外地放大了?如果你希望避免这种现象出现,可以通过 touch-action 来移除:

CSS 复制代码
.button {
    touch-action: manipulation;
}

manipulation 值禁用了诸如"双击放大"的手势。其他手势,如"平移"和"捏合放大",不受影响。额外的好处是浏览器不再需要等待第二次点击来延迟点击事件。

有人建议将 metaviewport 中的 user-scalable 设置为 none

HTML 复制代码
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">

需要注意的是,使用 user-scalable=no 可能会给视力受损(如低视力)的用户带来无法访问的问题。WCAG 要求至少 2 倍的缩放;然而,最佳实践是启用 5 倍缩放。因此应该谨慎使用。

悬停和可视焦点

给按钮提供悬停和焦点样式,对于按钮来说是非常重要的。这里特意要提出来的是,同时给按钮添加悬停和焦点样式时,它们的顺序非常重要。

当悬停样式在焦点样式之前添加时,每种样式都能正常工作。然而,问题出现在当焦点样式在悬停样式之前放置时。当使用鼠标点击元素时,焦点样式将不会出现,只有悬停样式会显示。

以下是正确的顺序:

CSS 复制代码
.button {
    /* Default Style */
    
    &:hover {
        /* Hover Style*/
    }
    
    &:focus {
        /* Focus Style */
    }
}

按钮焦点样式还有一个细节。与按钮交互时,获得焦点环不只是通过鼠标与其交互可获得,还可以通过键盘与其交互也可以获得。因此,请不要遗漏给键盘交互获得的焦点环设置样式。

在 CSS 中,可以通过下面这种方式给 :focus (鼠标交互)和 :focus-visible (键盘交互)设置不一样的样式:

CSS 复制代码
button:focus:not(:focus-visible) { 
    outline: 2px dotted #416dea; 
    outline-offset: 2px; 
    box-shadow: 0px 1px 1px #416dea; 
} 

button:focus-visible { 
    outline: 2px solid #f35; 
    outline-offset: 2px; 
    box-shadow: 0px 1px 1px #416dea; 
} 

CSS 中除了 :focus:focus-visible 之外,还有一个 :focus-within ,它们都可以用于设置焦点环样式,但它们之间有着明显的差异。有关于这方面更详细的介绍,可以称步阅读《CSS 焦点样式: :focus 和 :focus-visible》一文!

按钮的最小宽度

为了确保按钮具有适当的宽度,重要的是提前考虑到按钮内容的长短,并为其设置最小宽度。通过使用 min-width 属性,可以帮助你确定按钮的最小宽度。

考虑下面的示例,其中有一些按钮具有不同长度的内容,包括英文和阿拉伯文。如果文本较短,没有设置最小宽度,按钮的宽度可能会变得太小。通过使用 min-width,可以避免这种情况。

CSS 复制代码
.button {
    min-width: 104px;
}

有关于这方面更多的介绍,可以移步阅读:

按钮的字体

默认情况下,表单元素不会继承 <html><body> 元素的 font-family 。如果你希望按钮的字体继承它们的 font-family ,最简单的解决方案是重置按钮的 font-family 属性的值为 inherit

CSS 复制代码
.button {
    font-family: inherit;
}

按钮禁用状态

为了指示按钮被禁用,我们可以给它添加 disabled 属性,然后用 CSS 样式进行样式化。

HTML 复制代码
<button disabled></button>
CSS 复制代码
button[disabled] {
    color: #d2d5db;
    background: #6c7589;
    cursor: not-allowed;
}

当按钮被禁用时,无法通过键盘聚焦到它,并且它会从可访问性树中移除。

意外选择

很多 Web 应用或网站上会将链接 <a> 的外观设置的看上去像一个按钮。通常会使用一个共享的类,例如 .button.btn

HTML 复制代码
<a class="button" href="/sign-in">Sign in</a>

此时,反复点击它,可能会被选中或高亮显示,为了避免这种现象,可以将 user-select 设置为 none

CSS 复制代码
.button {
    user-select: none;
}

小结

按钮样式的设计对于 Web 的外观和用户体验至关重要。通过一些小技巧,可以使按钮看起来更加吸引人、易于理解和操作。以下是对按钮样式小技巧的简要总结:

首先,悬停和焦点样式是为了增强按钮的交互性。通过使用 :hover:focus:focus-visible 伪类,我们可以为按钮添加悬停和焦点时的样式效果,从而提高用户对按钮的注意力,并且在键盘导航时也能保持可见性。

其次,按钮的最小宽度是确保按钮在不同文本长度下保持一致的外观。通过使用 min-width 属性,我们可以为按钮设定一个最小宽度,这样即使按钮文本内容较短,按钮也不会显得过于拥挤或不规整。

第三,字体系列的设置可以让按钮文本与网页的整体风格保持一致。通过将 font-family 属性设置为inherit,按钮文本将继承网页中定义的字体样式,从而确保按钮在外观上与网页内容一致。

最后,禁用状态样式可以为用户提供视觉提示,告知他们按钮当前处于禁用状态。通过为 [disabled] 属性选择器定义样式,我们可以改变禁用状态按钮的颜色、背景和鼠标指针样式,使用户能够清楚地识别禁用按钮并且避免误操作。

综上所述,通过应用这些按钮样式小技巧,我们可以创建出更具吸引力、易用性和可访问性的按钮,从而提升用户体验并增强网页的整体品质。


如果你觉得该教程对你有所帮助,请给我点个赞。要是你喜欢 CSS ,或者想进一步了解和掌握 CSS 相关的知识,请关注我的专栏,或者移步阅读下面这些系列教程:

相关推荐
我要洋人死24 分钟前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人36 分钟前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人36 分钟前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR42 分钟前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香44 分钟前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai1 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
逐·風6 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#