关于css:前端优秀实践不完全指南

8次阅读

共计 14510 个字符,预计需要花费 37 分钟才能阅读完成。

本文其实应该叫,Web 用户体验设计晋升指南。

一个 Web 页面,一个 APP,想让他人用的爽,也就是所谓的良好的用户体验,我感觉他可能包含但不限于:

  • 急速的关上速度
  • 眼前一亮的 UI 设计
  • 酷炫的动画成果
  • 丰盛的个性化设置
  • 便捷的操作
  • 贴心的细节
  • 关注残障人士,良好的可拜访性

所谓的用户体验设计,其实是一个比拟虚的概念,是秉承着 以用户为核心的思维 的一种设计伎俩,以用户需要为指标而进行的设计。设计过程重视以用户为核心,用户体验的概念从开发的最晚期就开始进入整个流程,并贯通始终。

良好的用户体验设计,是产品每一个环节共同努力的后果。

除去一些很难欲速不达的,本文将就 页面展现 交互细节 可拜访性 三个方面动手,列举一些在理论的开发过程中,积攒的一些无益的教训。通过本文,你将能播种到:

  1. 理解到一些小细节是如何影响用户体验的
  2. 理解到如何在尽量小的开发改变下,晋升页面的用户体验
  3. 理解到一些优良的交互设计细节
  4. 理解根本的无障碍性能及页面可拜访性的含意
  5. 理解根本的晋升页面可拜访性的办法

页面展现

就整个页面的展现,页面内容的出现而言,有一些小细节是须要咱们留神的。

整体布局

先来看看一些布局相干的问题。

对于大部分 PC 端的我的项目,咱们首先须要思考的必定是最外层的一层包裹。假如就是 .g-app-wrapper

<div class="g-app-wrapper">
    <!-- 外部内容 -->
</div>

首先,对于 .g-app-wrapper,有几点,是咱们在我的项目开发前必须弄清楚的:

  1. 我的项目是全屏布局还是定宽布局?
  2. 对于全屏布局,须要适配的最小的宽度是多少?

对于定宽布局,就比拟不便了,假如定宽为 1200px,那么:

.g-app-wrapper {
    width: 1200px;
    margin: 0 auto;
}

利用 margin: 0 auto 实现布局的程度居中。在屏幕宽度大于 1200px 时,两侧留白,当然屏幕宽度小于 1200px 时,则呈现滚动条,保障外部内容不乱。

对于古代布局,更多的是全屏布局。其实当初也更提倡这种布局,即应用可随用户设施的尺寸和能力而变动的自适应布局。

通常而言是左右两栏,左侧定宽,右侧自适应残余宽度,当然,会有一个最小的宽度。那么,它的布局应该是这样:

<div class="g-app-wrapper">
    <div class="g-sidebar"></div>
    <div class="g-main"></div>
</div>
.g-app-wrapper {
    display: flex;
    min-width: 1200px;
}
.g-sidebar {
    flex-basis: 250px;
    margin-right: 10px;
}
.g-main {flex-grow: 1;}

利用了 flex 布局下的 flex-grow: 1,让 .main 进行伸缩,占满残余空间,利用 min-width 保障了整个容器的最小宽度。

当然,这是最根本的自适应布局。对于古代布局,咱们应该尽可能的思考更多的场景。做到:

底部 footer

上面一种情景也是十分常见的一个情景。

页面存在一个 footer 页脚局部,如果整个页面的内容高度小于视窗的高度,则 footer 固定在视窗底部,如果整个页面的内容高度大于视窗的高度,则 footer 失常流排布(也就是须要滚动到底部能力看到 footer)。

看看成果:

嗯,这个需要如果可能应用 flex 的话,应用 justify-content: space-between 能够很好的解决,同理应用 margin-top: auto 也非常容易实现:

<div class="g-container">
    <div class="g-real-box">
        ...
    </div>
    <div class="g-footer"></div>
</div>
.g-container {
    height: 100vh;
    display: flex;
    flex-direction: column;
}

.g-footer {
    margin-top: auto;
    flex-shrink: 0;
    height: 30px;
    background: deeppink;
}

Codepen Demo — sticky footer by flex margin auto

当然,实现它的办法有很多,这里仅给出一种举荐的解法。

解决动静内容 – 文本超长

对于所有接管后端接口字段的文本展现类的界面。都须要思考全面(防御性编程:所有的内部数据都是不可信的),失常状况如下,是没有问题的。

然而咱们是否思考到了文本会超长?超长了会折行还是换行?

对于 单行文本,应用单行省略:

{
    width: 200px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

当然,目前对于 多行文本 的超长省略,兼容性也曾经十分好了:

{
    width: 200px;
    overflow : hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

解决动静内容 – 爱护边界

对于一些动静内容,咱们常常应用 min/max-widthmin/max-height 对容器的高宽限度进行正当的管制。

在应用它们的时候,也有一些细节须要思考到。

譬如常常会应用 min-width 管制按钮的最小宽度:

.btn {
    ...
    min-width: 120px;
}

当内容比拟少的时候是没问题的,然而当内容比拟长,就容易呈现问题。应用了 min-width 却没思考到按钮的过长的状况:

这里就须要配合 padding 一起:

.btn {
    ...
    min-width: 88px;
    padding: 0 16px
}

借用 Min and Max Width/Height in CSS 中一张十分好的图,作为释义:

0 内容展现

这个也是一个经常被疏忽的中央。

页面常常会有列表搜寻,列表展现。那么,既然存在有数据的失常状况,当然也会存在搜寻不到后果或者列表无内容可展现的情景。

对于这种状况,肯定要留神 0 后果页面的设计,同时也要晓得,这也是疏导用户的好中央。对于 0 后果页面,分分明:

  • 数据为空:其中又可能包含了用户无权限、搜寻无后果、筛选无后果、页面无数据
  • 异样状态:其中又可能包含了网络异样、服务器异样、加载失败期待

不同的状况可能对应不同的 0 后果页面,附带不同的操作疏导。

譬如网络异样:

或者的确是 0 后果:

对于 0 后果页面设计,能够具体看看这篇文章:如何设计产品的空白页面?

小小总结一下,上述比拟长的篇幅始终都在论述一个情理,开发时,不能仅仅关注失常景象,要多思考各种异常情况,思考全面。做好各种可能状况的解决

图片相干

图片在咱们的业务中应该是十分的常见了。有一些小细节是须要留神的。

给图片同时设置高宽

有的时候和产品、设计会约定,只能应用固定尺寸大小的图片,咱们的布局可能是这样:

对应的布局:

<ul class="g-container">
    <li>
        <img src="http://placehold.it/150x100">
        <p> 图片形容 </p>
    </li>
</ul>
ul li img {width: 150px;}

当然,万一假如后端接口呈现一张非正常大小的图片,上述不加爱护的布局就会出问题:

所以对于图片,咱们总是倡议同时写上高和宽,防止因为图片尺寸谬误带来的布局问题:

ul li img {
    width: 150px;
    height: 100px;
}

同时,给 <img> 标签同时写上高宽,能够在图片未加载之前提前占住地位,防止图片从未加载状态到渲染实现状态高宽变动引起的重排问题。

object-fit

当然,限度高宽也会呈现问题,譬如图片被拉伸了,十分的难看:

这个时候,咱们能够借助 object-fit,它可能指定可替换元素的内容(也就是图片)该如何适应它的父容器的高宽。

ul li img {
    width: 150px;
    height: 100px;
    object-fit: cover;
}

利用 object-fit: cover,使图片内容在放弃其宽高比的同时填充元素的整个内容框。

object-fit 还有一个配套属性 object-position,它能够管制图片在其内容框中的地位。(相似于 background-position),m 默认是 object-position: 50% 50%,如果你不心愿图片居中展现,能够应用它去扭转图片理论展现的 position。

ul li img {
    width: 150px;
    height: 100px;
    object-fit: cover;
    object-position: 50% 100%;
}

像是这样,object-position: 100% 50% 指明从底部开始展现图片。这里有一个很好的 Demo 能够帮忙你了解 object-position

CodePen Demo — Object position

思考屏幕 dpr — 响应式图片

失常状况下,图片的展现应该没有什么问题了。然而对于有图片可展现的状况下,咱们还能够做的更好。

在挪动端或者一些高清的 PC 屏幕(苹果的 MAC Book),屏幕的 dpr 可能大于 1。这种时候,咱们可能还须要思考利用多倍图去适配不同 dpr 的屏幕。

正好,<img> 标签是有提供相应的属性 srcset 让咱们进行操作的。

<img src='photo@1x.png'
   srcset='photo@1x.png 1x,
           photo@2x.png 2x,
           photo@3x.png 3x' 
/>

当然,这是比拟旧的写法,srcset 新增了新的 w 宽度描述符,所以更好的写法是:

<img 
        src = "photo.png" 
        srcset =“photo@1x.png 300w,
                       photo@2x.png 600w,
                       photo@3x.png 1200w,
>

利用 srcset,咱们能够给不同 dpr 的屏幕,提供最适宜的图片。

上述呈现了一些概念,dpr,srcset 属性,不太理解的能够移步 前端基础知识概述

图片失落

好了,当图片链接没问题时,曾经解决好了。接下来还须要思考,当图片链接挂了,应该如何解决。

解决的形式有很多种。最好的解决形式,是我最近在张鑫旭老师的这篇文章中 — 图片加载失败后 CSS 款式解决最佳实际 看到的。这里简略讲下:

  1. 利用图片加载失败,触发 <img> 元素的 onerror 事件,给加载失败的 <img> 元素新增一个款式类
  2. 利用新增的款式类,配合 <img> 元素的伪元素,展现默认兜底图的同时,还能一起展现 <img> 元素的 alt 信息
<img src="test.png" alt="图片形容" onerror="this.classList.add('error');">
img.error {
    position: relative;
    display: inline-block;
}

img.error::before {
    content: "";
    /** 定位代码 **/
    background: url(error-default.png);
}

img.error::after {content: attr(alt);
    /** 定位代码 **/
}

咱们利用伪元素 before,加载默认谬误兜底图,利用伪元素 after,展现图片的 alt 信息:

OK,到此,残缺的对图片的解决就算实现了,残缺的 Demo 你能够戳这里看看:

CodePen Demo — 图片解决

交互设计优化

接下来一个大环节是对于一些交互的细节。对于交互设计,一些比拟通用的准则:

  • Don’t make me think
  • 合乎用户的习惯与预期
  • 操作便当
  • 做适当的揭示
  • 不强制用户

过渡与动画

在咱们的交互过程中,适当的减少过渡与动画,可能很好的让用户感知到页面的变动

譬如咱们页面上随处可见 loading 成果,其实就是这样一种作用,让用户感知页面正在加载,或者正在解决某些事务。

滚动优化

滚动也是操作网页中十分重要的一环。看看有哪些能够优化的点:

滚动平滑:应用 scroll-behavior: smooth 让滚动丝滑

应用 scroll-behavior: smooth,能够让滚动框实现安稳的滚动,而不是突兀的跳动。看看成果,假如如下构造:

<div class="g-container">
  <nav>
    <a href="#1">1</a>
    <a href="#2">2</a>
    <a href="#3">3</a>
  </nav>
  <div class="scrolling-box">
    <section id="1">First section</section>
    <section id="2">Second section</section>
    <section id="3">Third section</section>
  </div>
</div>

不应用 scroll-behavior: smooth,是突兀的跳动切换:

给可滚动容器增加 scroll-behavior: smooth,实现平滑滚动:

{scroll-behavior: smooth;}

应用 scroll-snap-type 优化滚动成果

sroll-snap-type 可能算得上是新的滚动标准外面最外围的一个属性款式。

scroll-snap-type:属性定义在滚动容器中的一个长期点(snap point)如何被严格的执行。

光看定义有点难了解,简略而言,这个属性规定了一个容器是否对外部滚动动作进行捕获,并且规定了如何去解决滚动完结状态。让滚动操作完结后,元素进行在适宜的地位。

看个简略示例:

当然,scroll-snap-type 用法十分多,可管制优化的点很多,限于篇幅无奈一一开展,具体更具体的用法能够看看我的另外一篇文章 — 应用 sroll-snap-type 优化滚动

管制滚动层级,防止页面大量重排

这个优化可能略微有一点难了解。须要理解 CSS 渲染优化的相干常识。

先说论断,管制滚动层级的意思是 尽量让须要进行 CSS 动画(能够是元素的动画,也能够是容器的滚动)的元素的 z-index 放弃在页面最上方,防止浏览器创立不必要的图形层(GraphicsLayer),可能很好的晋升渲染性能

这一点怎么了解呢,一个元素触发创立一个 Graphics Layer 层的其中一个因素是:

  • 元素有一个 z-index 较低且蕴含一个复合层的兄弟元素

根据上述这点,咱们对滚动性能进行优化的时候,须要留神两点:

  1. 通过生成独立的 GraphicsLayer,利用 GPU 减速,晋升滚动的性能
  2. 如果自身滚动没有性能问题,不须要独立的 GraphicsLayer,也要留神滚动容器的层级,防止因为层级过高而被其余创立了 GraphicsLayer 的元素合并,被动的生成一个 Graphics Layer,影响页面整体的渲染性能

如果你对这点还有点懵,能够看看这篇文章 — 你所不晓得的 CSS 动画技巧与细节

点击交互优化

在用户点击交互方面,也有一些有意思的小细节。

优化手势 — 不同场景利用不同 cursor

对于不同的内容,最好给与不同的 cursor 款式,CSS 原生提供十分多种罕用的手势。

在不同的场景应用不同的鼠标手势,合乎用户的习惯与预期,能够很好的晋升用户的交互体验。

首先对于按钮,就至多会有 3 种不同的 cursor,别离是可点击,不可点击,期待中:

{
    cursor: pointer;    // 可点击
    cursor: not-allowed;    // 不可点击
    cursor: wait;    // loading
}

除此之外,还有一些常见的,对于一些可输出的 Input 框,应用 cursor: text,对于提醒 Tips 类应用 cursor: help,放大放大图片 zoom-inzoom-out 等等:

一些罕用的简略列一列:

  • 按钮可点击: cursor: pointer
  • 按钮禁止点击:cursor: not-allowed
  • 期待 Loading 状态:cursor: wait
  • 输入框:cursor: text;
  • 图片查看器可放大可放大:cursor: zoom-in/ zoom-out
  • 提醒:cursor: help;

当然,理论 cursor 还反对十分多种,能够在 MDN 或者上面这个 CodePen Demo 中查看这里看残缺的列表:

CodePen Demo — Cursor Demo

点击区域优化 — 伪元素扩充点击区域

按钮是咱们网页设计中非常重要的一环,而按钮的设计也与用户体验非亲非故。

思考这样一个场景,在摇摆的车厢上或者是单手操作着屏幕,有的时候一个按钮,死活也点不到。

让用户更容易的点击到按钮无疑能很好的减少用户体验及可晋升页面的拜访性,尤其是在挪动端,按钮通常都很小,然而受限于设计稿或者整体 UI 格调,咱们不能间接去扭转按钮元素的高宽。

那么这个时候有什么方法在不扭转按钮本来大小的状况上来减少他的点击热区呢?

这里,伪元素也是能够代表其宿主元素来响应的鼠标交互事件的。借助伪元素能够轻松帮咱们实现,咱们能够这样写:

.btn::befoer{
  content:"";
  position:absolute;
  top:-10px;
  right:-10px;
  bottom:-10px;
  left:-10px;
}

当然,在 PC 端下这样子看起来有点奇怪,然而正当的用在点击区域较小的挪动端则能取到非常好的成果,成果如下:

在按钮的伪元素没有其它用处的时候,这个办法的确是个很好的晋升用户体验的点。

疾速抉择优化 — user-select: all

操作系统或者浏览器通常会提供一些疾速选取文本的性能,看看上面的示意图:

疾速单击两次,能够选中单个单词,疾速单击三次,能够选中一整行内容。然而如果有的时候咱们的核心内容,被分隔符宰割,或者潜藏在一整行中的一部分,这个时候选取起来就比拟麻烦。

利用 user-select: all,能够将须要一次选中的内容进行包裹,用户只须要点击一次,就能够选中该段信息:

.g-select-all {user-select: all}

给须要一次选中的信息,加上这个款式后的成果,这个细节作用在一些须要复制粘贴的场景,十分好用:

CodePen — user-select: all 示例

选中款式优化 — ::selection

当然,如果你想更进一步,CSS 还有提供一个 ::selection 伪类,能够管制选中的文本的款式(只能管制color, background, text-shadow),进一步加深成果。

CodePen — user-select: all && ::selection 管制选中款式

增加禁止抉择 — user-select: none

有疾速抉择,也就会有它的对立面 — 禁止抉择。

对于一些可能频繁操作的按钮,可能呈现如下难堪的场景:

  • 文本按钮的疾速点击,触发了浏览器的双击疾速抉择,导致文本被选中:

  • 翻页按钮的疾速点击,触发了浏览器的双击疾速抉择:

对于这种场景,咱们须要把不可被选中元素设置为不可被选中,利用 CSS 能够疾速的实现这一点:

{
    -webkit-user-select: none; /* Safari */
    -ms-user-select: none; /* IE 10 and IE 11 */
    user-select: none; /* Standard syntax */
}

这样,无论点击的频率多快,都不会呈现难堪的内容选中:

跳转优化

现阶段,单页利用(Single Page Application)的利用十分宽泛,Vue、React 等框架大行其道。然而一些常见的写法,也容易衍生一些小问题。

譬如,点击按钮、文本进行路由跳转。譬如,常常会呈现这种代码:

<template>
    ...
    <button @click="gotoDetail">
        Detail
    </button>
    ...
<template>
...
gotoDetail() {
    this.$router.push({name: 'xxxxx',});
}

大抵逻辑就是给按钮增加一个事件,点击之后,跳转到另外一个路由。当然,自身这个性能是没有任何问题的,然而没有思考到用户理论应用的场景。

理论应用的时候,因为是一个页面跳转,很多时候,用户心愿可能保留以后页面的内容,同时关上一个新的窗口,这个时候,他会尝试下的鼠标右键,抉择 在新标签页中关上页面,遗憾的是,上述的写法是不反对鼠标右键关上新页面的。

起因在于浏览器是通过读取 <a> 标签的 href 属性,来展现相似 在新标签页中关上页面 这种选项,对于上述的写法,浏览器是无奈辨认它是一个能够跳转的链接。简略的示意图如下:

所以,对于所有路由跳转按钮,倡议都应用 <a> 标签,并且内置 href 属性,填写跳转的路由地址。理论渲染进去的 DOM 可能是须要相似这样:

<a href="/xx/detail">Detail</a>

易用性

易用性也是交互设计中须要思考的一个十分重要的环节,能做的有十分多。简略的列举一下:

  • 留神界面元素的一致性,升高用户学习老本
  • 连续用户日常的应用习惯,而不是从新发明
  • 给下拉框减少一些预设值,升高用户填写老本
  • 同类的操作合并在一起,升高用户的认知老本
  • 任何操作之后都要给出反馈,让用户晓得操作曾经失效

先摸索,后表态

这一点十分的有意思,什么叫先摸索后表态呢?就是咱们不要一上来就强制用户去做一些事件,譬如登录。

想一想一些罕用网站的例子:

  • 相似虎牙、Bilibili 等视频网站,能够先蓝光体验,肯定观看工夫后才会要求登录
  • 电商网站,只有到付款的时候,才须要登录

上述 易用性 先摸索,后表态 的内容,局部来源于:Learn From What Leading Companies A/B Test,能够好好读一读。

字体优化

字体的抉择与应用其实是十分有考究的。

如果网站没有强制必须应用某些字体。最新的标准倡议咱们更多的去应用零碎默认字体。也就是 CSS Fonts Module Level 4 — Generic font families 中新增的 font-family: system-ui 关键字。

font-family: system-ui 可能主动抉择本操作系统下的默认零碎字体。

默认应用特定操作系统的零碎字体能够进步性能,因为浏览器或者 webview 不用去下载任何字体文件,而是应用已有的字体文件。font-family: system-ui 字体设置的劣势之处在于它与以后操作系统应用的字体相匹配,对于文本内容而言,它能够失去最失当的展现。

举两个例子,天猫的字体定义与 Github 的字体定义:

  • 天猫:font-family: "PingFang SC",miui,system-ui,-apple-system,BlinkMacSystemFont,Helvetica Neue,Helvetica,sans-serif;
  • Github:font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;

简略而言,它们总体遵循了这样一个根本准则:

1、尽量应用零碎默认字体

应用零碎默认字体的次要起因是性能,并且零碎字体的长处在于它与以后操作系统应用的相匹配,因而它的文本展现必然也是一个让人舒服展现成果。

2、兼顾中西,西文在前,中文在后

中文或者西文(英文)都要思考到。因为大部分中文字体也是带有英文局部的,然而英文局部又不怎么难看,然而英文字体中大多不蕴含中文。通常会先进行英文字体的申明,抉择最优的英文字体,这样不会影响到中文字体的抉择,中文字体申明则紧随其次。

3、兼顾多操作系统

抉择字体的时候要思考多操作系统。例如 MAC OS 下的很多中文字体在 Windows 都没有预装,为了保障 MAC 用户的体验,在定义中文字体的时候,先定义 MAC 用户的中文字体,再定义 Windows 用户的中文字体;

4、兼顾旧操作系统,以字体族系列 serif 和 sans-serif 结尾

当应用一些十分新的字体时,要思考向下兼容,兼顾到一些极旧的操作系统,应用字体族系列 serif 和 sans-serif 结尾总归是不错的抉择。

对于上述的一些字体可能会有些懵,譬如 -apple-system, BlinkMacSystemFont,这是因为不同浏览器厂商对标准的实现有所不同,对于字体定义更多的相干细节,能够再看看这篇文章 — Web 字体 font-family 再探秘

可拜访性(A11Y)

可拜访性,在咱们的网站中,属于十分重要的一环,然而大部分前端(其实应该是设计、前端、产品)同学都会漠视它。

我埋伏在一个叫 无障碍设计小组 的群里,其中蕴含了很多无障碍设计师以及患有肯定水平视觉、听力、口头阻碍的用户,他们在群里常常会表白出一个观点,就是国内的大部分 Web 网站及 APP 根本没有思考过残障人士的应用(或者可拜访性做的十分差),十分的令人揪心。

尤其在咱们一些重交互、重逻辑的网站中,咱们须要思考用户的应用习惯、应用场景,从高可拜访性的角度思考,譬如假如用户没有鼠标,仅仅应用键盘,是否顺畅的应用咱们的网站?

假如用户没有鼠标,这个真不肯定是针对残障人士,很多状况下,用户拿鼠标的手可能在干其余事件,比方在吃货色,又或者在 TO B 类的业务,如超市收银、仓库收货,很可能用户拿鼠标的手操作着其余设施(扫码枪)等等。

本文不会专门论述无障碍设计的方方面面,只是从一些我感觉前端工程师须要关注的,并且仅须要破费大量代价就能做好的一些无障碍设计细节。记住,无障碍设计对所有人都更友善

色调对比度

色彩,也是咱们天天须要打交道的属性。对于大部分视觉失常的用户,可能对页面的色彩敏感度还没那么高。然而对于一小部分色弱、色盲用户,他们对于网站的色彩会更加敏感,不好的设计会给他们拜访网站带来极大的不便。

什么是色调对比度

是否曾关怀过页面内容的展现,应用的色彩是否失当?色弱、色盲用户是否失常看清内容?良好的色调应用,在任何时候都是无益的,而且不仅仅局限于对于色弱、色盲用户。在户外用手机、阳光很强看不清,合乎无障碍规范的高清晰度、高对比度文字就更容易浏览。

这里就有一个概念 — 色彩对比度,简略地说,形容就是两种色彩在亮度(Brightness)上的差异。使用到咱们的页面上,大多数的状况就是背景色(background-color)与内容色彩(color)的比照差别。

最权威的互联网无障碍标准 —— WCAG AA 标准规定,所有重要内容的色调对比度须要达到 4.5:1 或以上(字号大于 18 号时达到 3:1 或以上),才算领有较好的可读性。

借用一张图 — 知乎 — 助你轻松做好无障碍的 15 个 UI 设计工具举荐:

很显著,上述最初一个例子,文字曾经十分的不清晰了,失常用户都曾经很难看得清了。

查看色调对比度的工具

Chrome 浏览器从很早开始,就曾经反对查看元素的色调对比度了。以我以后正在写作的页面为例子,Github Issues 编辑页面的两个按钮:

审查元素,别离能够看到两个按钮的色调对比度:

能够看到,绿底白字按钮的色调对比度是没有达到规范的,也被用黄色的叹号标识了进去。

除此之外,在审查元素的 Style 界面的取色器,扭转色彩,也能直观的看到以后的色调对比度:

焦点响应

相似百度、谷歌的首页,进入页面后会默认让输入框取得焦点:

并非所有的有输入框的页面,都须要进入页面后进行聚焦,然而焦点可能让用户十分明确的晓得,以后本人在哪,须要做些什么。尤其是对于无奈操作鼠标的用户。

页面上能够聚焦的元素,称为 可聚焦元素,取得焦点的元素,则会触发该元素的 focus 事件,对应的,也就会触发该元素的 :focus 伪类。

浏览器通常会应用元素的 :focus 伪类,给元素增加一层边框,通知用户,以后的获焦元素在哪里。

咱们能够通过键盘的 Tab 键,进行焦点的切换,而获焦元素则能够通过元素的 :focus 伪类的款式,通知用户以后焦点地位。

当然,除了 Tab 键之外,对于一些多输入框、抉择框的表单页面,咱们也应该想着如何简化用户的操作,譬如用户按回车键时主动后退到下一字段。一般而言,用户必须执行的触按越少,体验越佳。

上面的截图,齐全由键盘操作实现

通过元素的 :focus 伪类以及键盘 Tab 键切换焦点,用户能够十分顺畅的在脱离鼠标的状况下,对页面的焦点切换及操作。

然而,在许多 reset.css 中,常常能看到这样一句 CSS 款式代码,为了款式的对立,打消了可聚焦元素的 :focus 伪类:

:focus {outline: 0;}

咱们给上述操作的代码。也加上这样一句代码,全程再用键盘操作一下

除了在 input 框有光标提醒,当应用 Tab 进行焦点切换到 select 或者到 button 时,因为没有了 :focus 款式,用户将齐全懵逼,不晓得页面的焦点当初处于何处。

保障非鼠标用户体验,正当使用 :focus-visible

当然,造成上述后果很重要的一个起因在于。:focus 伪类不管用户在应用鼠标还是应用键盘,只有元素获焦,就会触发。

而其自身的默认款式又不太能被产品或者设计承受,导致了很多人会在焦点元素触发 :focus 伪类时,通过扭转 border 的色彩或者其余一些形式代替或者间接禁用。而这样做,从可拜访性的角度来看,对于非鼠标用户,无疑是灾难性的。

基于此,在 W3 CSS selectors-4 标准 中,新增了一个十分有意思的 :focus-visible 伪类。

:focus-visible:这个选择器能够无效地依据用户的输出形式 (鼠标 vs 键盘) 展现不同模式的焦点。

有了这个伪类,就能够做到,当用户应用鼠标操作可聚焦元素时,不展现 :focus 款式或者让其体现较弱,而当用户应用键盘操作焦点时,利用 :focus-visible,让可获焦元素取得一个较强的体现款式。

看个简略的 Demo:

<button>Test 1</button>
button:active {background: #eee;}
button:focus {outline: 2px solid red;}

应用鼠标点击:

能够看到,应用鼠标点击的时候,触发了元素的 :active 伪类,也触发了 :focus伪类,不太好看。然而如果设置了 outline: none 又会使键盘用户的体验十分蹩脚。尝试应用 :focus-visible 伪类革新一下:

button:active {background: #eee;}
button:focus {outline: 2px solid red;}
button:focus:not(:focus-visible) {outline: none;}

看看成果,别离是在鼠标点击 Button 和应用键盘管制焦点点击 Button:

CodePen Demo — :focus-visible example

能够看到,应用鼠标点击,不会触发 :foucs,只有当键盘操作聚焦元素,应用 Tab 切换焦点时,outline: 2px solid red 这段代码才会失效。

这样,咱们就既保证了失常用户的点击体验,也保障了一批无奈应用鼠标的用户的焦点治理体验。

值得注意的是,有同学会纳闷,这里为什么应用了 :not 这么绕的写法而不是间接这样写呢:

button:focus {outline: unset;}
button:focus-visible {outline: 2px solid red;}

为的是兼容不反对 :focus-visible 的浏览器,当 :focus-visible 不兼容时,还是须要有 :focus 伪类的存在。

应用 WAI-ARIA 标准加强语义 — div 等非可获焦元素模仿获焦元素

还有一个十分须要留神的点。

当初很多前端同学在前端开发的过程中,喜爱应用非可获焦元素模仿获焦元素,譬如:

  • 应用 div 模仿 button 元素
  • 应用 ul 模仿下拉列表 select 等等

当下很多组件库都是这样做的,譬如 element-ui 和 ant-design。

在应用非可获焦元素模仿获焦元素的时候,肯定要留神,不仅仅只是外观长得像就完事了,其行为表现也须要合乎本来的 buttonselect 等可聚焦元素的性质,可能体现元素的语义,可能被聚焦,可能通过 Tab 切换等等。

基于大量相似的场景,有了 WAI-ARIA 规范,WAI-ARIA 是一个为残疾人士等提供无障碍拜访动静、可交互 Web 内容的技术规范。

简略来说,它提供了一些属性,加强标签的语义及行为:

  • 能够应用 tabindex 属性管制元素是否能够聚焦,以及它是否 / 在何处参加程序键盘导航
  • 能够应用 role 属性,来标识元素的语义及作用,譬如应用 <div id="saveChanges" tabindex="0" role="button">Save</div> 来模仿一个按钮
  • 还有大量的 aria-* 属性,示意元素的属性或状态,帮忙咱们进一步地辨认以及实现元素的语义化,优化无障碍体验

应用工具查看标签的语义

咱们来看看 Github 页面是如何定义一个按钮的,以 Github Issues 页面的 Edit 按钮为例子:

这一块,清晰的形容了这个按钮在可拜访性相干的一些个性,譬如 Contrast 色调对比度,按钮的形容,也就是 Name,是给屏幕阅读器看到的,Role 标识是这个元素的属性,它是一个按钮,Keyboard focusable 则表明他是否被键盘的 Tab 按钮给捕捉。

剖析应用非可聚焦元素模仿的按钮

这里,我轻易选取了咱们业务中一个应用 span 模仿按钮的场景,是一个面包屑导航,点击可进行跳转,发现惨不忍睹:

HTML 代码:

<span class="ssc-breadcrumb-item-link"> Inbound </span>

基本上可拜访性为 0,作为一个按钮,它不可被聚焦,无奈被键盘用户选中,没有具体的语义,色调对比度太低,可能视障用户无奈看清。并且,作为一个能进行页面跳转的按钮,它没有不是 a 标签,没有 href 属性。

即使对于面包屑导航,咱们能够不将它革新成 <a> 标签,也须要做到 最根本 的一些可拜访性革新:

<span role="button" aria-label="goto inbound page" tabindex="0" class="ssc-breadcrumb-item-link"> Inbound </span>

不要忘了再改一下色彩,达到最低色调对比度以上,再看看:

OK,这样,一个最最最根本的,满足最低可拜访性需求的按钮算是勉强达标,当然,这个按钮能够再更进一步进行革新,波及了更深刻的可拜访性知识,本文不深刻开展。

剖析组件库的 A11Y

最初,在咱们比拟罕用的 Vue – element-ui、React – ant-design 中,咱们来看看 ant-design 在晋升可拜访性相干的一些性能。

以 Select 抉择框组件为例,ant-design 利用了大量的 WAI-ARIA 属性,使得用 div 模仿的下拉框不仅仅在体现上合乎一个下拉框,在语义、行为上都合乎一个下拉框,简略的一个例子:

看看应用 div 模仿下拉框的 DOM 局部:

再看看在交互体验上:

上述操作全是在键盘下实现,看着平平无奇,实际上组件库在失常响应可获焦元素切换的同时,给用 div 模仿的 select 加了很多键盘事件的响应,能够利用回车,高低键等对可选项进行抉择。其实是下了很多功夫。

对于 A11Y 相干的内容,篇幅及内容十分之多,本文无奈一一开展,感兴趣的能够通读下下列文章:

  • WAI-ARIA basics
  • WAI-ARIA 1.1
  • Web 中的焦点治理
  • 无障碍性能
  • 晋升 Web 用户体验的 71 个设计要点
  • 公众号 — 无障碍设计小组

总结一下

本文从 页面展现 交互细节 可拜访性 三个大方面动手,列举一些在理论的开发过程中,积攒的一些无益的教训。尽管不够全面,不过从一开始也就没想着大而全,次要是一些可能有用然而容易被忽视的点,也算是一个不错的查缺补漏小指南。

当然,很多都是我集体的观点想法,可能有一些了解存在一些问题,一些概念没有解读到位,也心愿大家帮忙指出。

最初

本文到此结束,心愿对你有帮忙 :)

想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 — iCSS 前端趣闻 ????

更多精彩 CSS 技术文章汇总在我的 Github — iCSS,继续更新,欢送点个 star 订阅珍藏。

如果还有什么疑难或者倡议,能够多多交换,原创文章,文笔无限,满腹经纶,文中若有不正之处,万望告知。

正文完
 0