css揭秘 – 用户体验(一)

这是我参与更文挑战的第11天,活动详情查看: 更文挑战

选用合适的鼠标光标

难题

鼠标指针的用途不仅在于显示鼠标在屏幕上的位置,还可以告诉用户当前可以执行什么动作。这在桌面应用程序中是十分普遍的用户体验实践,但在网页应用中却往往被忽视。

解决方案

css3 中定义了鼠标的光标,可以使用 cursor 属性来定义。

1111.png

扩大可点击区域

难题

对于那些较小的、难以瞄准的控件来说,如果不能把它的视觉尺寸直接放大,将其可点击区域(热区)向外扩张往往也可以带来可用性的提升。没有人愿意对一个狭小的按钮尝试点按很多次,但实际上这样的无奈之举仍然每天都在发生。

还有一些时候,我们想让某个元素在鼠标接近窗口某侧时自动滑入,举个例子,一个自动隐藏的页头会在鼠标接近时自动从顶部滑入并完整展现,这也涉及(只在单一方向上)放大热区的问题。

解决方案

扩张热区最简单的方法是为它设置一圈透明边框,因此我们加入:

border: 10px solid transparent;
复制代码

image.png

但是,效果并不好,它把按钮同时加大了,原因在于背景在默认情况下会蔓延到边框的下层。简单好用的 background-clip 属性可以把背景限制在原本的区域之内:

border: 10px solid transparent;
background-clip: padding-box;
复制代码

image.png

如上图,这个方法很管用,然而,当需要给按钮加上真正的边框效果时,发现按钮仅有的那个边框属性已经挪作他用了,此时,可以使用内嵌投影来模拟出一道边框。

border: 10px solid transparent;
box-shadow: 0 0 0 1px rgba(0,0,0,.3) inset;
background-clip: padding-box;
复制代码

image.png
border-box 不同的是 box-shadow 可以指定多层投影,只需要使用逗号分隔即可。但如果把内嵌投影和(常规的)外部投影组合起来,将会得到一个怪异的效果,因为外部投影是绘制在 border box 外部的。

边框会影响布局,因此这种方法也不是很完美,于是放弃边框改用另一个特性来实现:伪元素同样可以代表其宿主元素来响应鼠标交互。

于是,可以在按钮的上层覆盖一层透明的伪元素,并让伪元素在四个方向都比宿主元素大出10px:

button {
    position: relative;
    /* [其余样式] */
}
button::before {
    content: '';
    position: absolute;
    top: -10px; right: -10px;
    bottom: -10px; left: -10px;
}
复制代码

自定义复选框

难题

现在可以设置大多数表单控件的样式,但是单选框和复选框不在此列,极大多数浏览器中仍然是几乎或者完全无法设置样式的。

解决方案

核心:当 <label> 元素与复选框关联之后,也可以起到触发开关的作用。

初始代码:

<input type="checkbox" id="awesome" />
<label for="awesome">Awesome!</label>
复制代码

接下来,需要生成一个伪元素,作为美化版的复选框,先给这个伪元素添加一些基本的样式:

input[type="checkbox"]+label::before {
  content: '\a0'; /* 不换行空格 */
  display: inline-block;
  vertical-align: .2em;
  width: .8em;
  height: .8em;
  margin-right: .2em;
  border-radius: .2em;
  background: silver;
  text-indent: .15em;
  line-height: .65;
}
复制代码

image.png
左边是原生的复选框,右边是初步定义的复选框

现在需要给复选框的勾选状态加上不同的样式。样式可以很简单,比如换种颜色,再加上勾选标记:

input[type="checkbox"]:checked + label::before {
  content: '\2713';
  background: yellowgreen;
}
复制代码

image.png

现在看来,这个伪元素俨然是一个经过简单美化的复选框了,因此需要将原生的那个复选框隐藏掉即可,但是不能使用 display:none,因为那样会把它从键盘 tab 键切换焦点的队列中完全删除。使用另一种方法来达到目的:

input[type="checkbox"] {
  position: absolute;
  clip: rect(0,0,0,0);
}
复制代码

image.png
美化后将原生的复选框隐藏掉的状态

还可以进一步优化,比如在它聚焦或禁用时改变它的样式:

input[type="checkbox"]:focus + label::before {
  box-shadow: 0 0 .1em .1em #58a;
}

input[type="checkbox"]:disabled + label::before {
  background: gray;
  box-shadow: none;
  color: #555;
  cursor: not-allowed;
}
复制代码

开关式按钮

开关式按钮与复选框的行为十分相似,可以用来切换某个选项的开关状态:启用时,它是被按下的状态;停用时,它就是浮起的状态。

在语义上,开关式按钮和复选框并没有本质上的差别,因此可以放心地使用这个技巧,不用担心语义上有问题。如果想用这个技巧来生成开关式按钮,其实只需要把 label 设置为按钮的样式即可,并不需要用到伪元素。

input[type="checkbox"] {
  position: absolute;
  clip: rect(0, 0, 0, 0);
}

input[type="checkbox"]+label {
  display: inline-block;
  padding: .3em .5em;
  background: #ccc;
  background-image: linear-gradient(#ddd, #bbb);
  border: 1px solid rgba(0, 0, 0, .2);
  border-radius: .3em;
  box-shadow: 0 1px white inset;
  text-align: center;
  text-shadow: 0 1px 1px white;
}

input[type="checkbox"]:checked+label,
input[type="checkbox"]:active+label {
  box-shadow: .05em .1em .2em rgba(0, 0, 0, .6) inset;
  border-color: rgba(0, 0, 0, .3);
  background: #bbb;
}
复制代码

image.png

开关式按钮很容易与普通按钮混淆,让人误以为按下它会触发某个动作,要慎用。

最后说一句

如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下,您的支持是我坚持写作最大的动力,多谢支持。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享