2018年12月09日

人在寻找更好的设计,也在寻找更好的自己。人将设计推倒重来,也将自己推倒重来。

我们清楚顾此失彼的道理,却依旧固执于完美。

当无数个你能,又或不能决定的事实带你走到现在这个分支。

有人说“当你握紧拳头,手中什么也没有,松开双手,你拥有的是一切。”

你追问起自己是什么时候觉得一切是美好的,又何为完美?

并没有。

就如同你对人说“我从始至终都是我,改变的是你们对我的看法。”

想想,不过也是这样。

人在不停的寻找那个自己渴望成为的自己。

因为看起来是那么的相像,像一个不可计算却必定的随机。

我或许会在某一刻坚信,但最终问起,却还是没有答案。


从钢管厂,到17岁末奶粉店折腾一次,21岁摆地摊折腾一次,22岁瞬间解散一个队伍,23岁网上折腾一次,KTV搬砖一年多,而后辗转到网友的项目。今年就这样26岁了。

接近十年到末尾,工资一块钱没变多,也一块钱没变少。没存下钱也没有负债。然后,也还是单身

关于创业。要说总结,便是将想法落实,是极其困难的,特别是你还什么都没有。所以不要再侃侃而谈那些东西了,也不要在什么都没有的时候跟一堆什么都没有的人去计划什么。在自身和他人都不满足各方面稳定性的前提下。

把时间用在培养自己的能力和累积那么一丢丢财富上先,在大家都不稳定的年龄,十有九点九是很难如愿的。等时间沉淀了自己,筛选完了队友,才会得到改观。

这是我试到这年龄才终于相信和明白,为什么俗话说要“三十”才立。

然后,再说吧……

【完美】iOS Safari 滚动穿透问题解决方案

iOS Safari 上有一个滚动穿透问题,即当我们制造了一个遮罩,却依旧可以在遮罩上滚动 body,如果遮罩上存在滚动元素,在该元素滚动至两端后会继续朝着这个方向滚动 body。这个问题和 350ms 延迟(已被 Apple 修正)一样从整体上破坏了移动端的 Web 体验(其他的有滚动条问题与 Google 带头的下拉刷新问题之类)。

这在 Android 上现在已经可以使用 overscroll-behavior 这个 CSS 属性来实现局部滚动和阻止下拉刷新(Chrome),而 iOS 目前尚未加入这个属性。

在网上搜索了一箩筐解决方案,与尝试修改 HTML 结构(例如将正文与浮动分开,即滚动的不再是 body,但这样一来为此修改结构,同时例如在 iOS 中点击系统顶部 bar 是有返回顶部功能的,为此就会失去这个功能)等尝试但都不如意。

直接阻止触摸的方法。只能用于遮罩上不存在滚动元素的情况。

记录位置后取消滚动条并浮动 body 再在解除时恢复的方法。触发时 body 将回至顶部,且这个过程无法添加动画,此外还会因为浮动而带来图像(图片与视频)异常。

给两端增加 1px 的方法。回弹时会有 1px 抖动,且需要特殊 HTML 结构支持。

于是,开始。

.scroll 选择器为需要局部滚动的元素。

在找到所有 .scroll 之后,阻止其 touchmove(移动手指)动作。

触发 touchstart(移入手指)时记录手指位于屏幕 Y 轴的坐标,再解除对 touchmove(移动手指)的阻止,而后再次阻止 touchmove(移动手指)。如果没有解除与再次阻止这个过程,则第一次触摸会无法滚动,我没有想明白或忘了这是什么原理,也许你可以告诉我。

我们已经记录了触发点位于屏幕 Y 轴的坐标,它用作于之后 touchmove(移动手指)时判断方向。

触发 touchmove(移动手指)时对比,如果此时滚动位置小于等于 0 并且手指位于屏幕 Y 轴的位置大于此前记录的触发点(即滚动已经位于顶部并且手指是在继续往下方滑动)便阻止,否则解除(底部则相反,只是多了计算获得底部是在多少像素)。

触发 touchend(移出手指)时恢复阻止 touchmove(移动手指)状态。

建议。在浮动遮罩局部滚动区域的外围元素要做好阻止 touchmove(移动手指)行为的工作,同时因为 Android 已经不存在这个问题,CSS 中需要包含同样作用的 CSS 代码(上文有提到的局部滚动),而该段 JavaScript 代码应判断只在 iOS 执行。

最后。这是出于解决浮动遮罩类元素存在滚动时,穿透引发 body 滚动问题而出的方案。对于这个问题它是完美方案,但是它无法用于多层的叠加的场景,例如在浮动遮罩的滚动中再有滚动。

接着,有一个分叉问题。需要滚动的元素不存在滚动条(例如移动设备纵横向切换改变了元素的高度而致使滚动条的出现与消失)时是不必要做这么多工作的(只需要执行最初找到它时给它绑定的阻止就够了)。但是这样一来,需要操作的时候就多了一步判断工作。实际上我并不知道判断还是不判断更好,如果从大部分情况为存在滚动条,那么一定是前者更好。或者有更好的写法来解决这个问题。

加上判断。

我在这篇文章的页面上制作了一个浮动演示,你可以用手机打开试试(如果你看到它在左侧漂浮着,是一个黑边白底的正方形,如果它还在。需要注意的是,你可能在 body 滚动尚未停止的时候去触摸它,此时可能手指依旧只能触摸滚动 body,这并不是一个问题,因为正常情况下浮动是在 body 静止时被呼出的,不存在演示中的这种情况)。

2018年6月3日 追加

对选择器增加了 :not(.scrollX) 以解决横向滚动时被触发导致无法触摸横向滚动问题。也就是你需要给横向滚动的同时追加一个 .scrollX 类。当然,也许你并不会在所有滚动区都使用 .scroll,可能不会有这个问题(这跟 CSS 文件内容的规划有关)。

Web UI 设计中交互与外观样式的取舍

  标题所指的“交互”与“外观样式”并非取舍关系,而是在这里将阐述两者各自的问题。这篇文章并不阐述技术细节,而是探讨应当如。

  并且本文没图片也没太多例子,有些文字描述的比较模糊和不仔细,嘛,就大概的交代下一些东西,能看到多少是多少。好的开始。

  如果你已经写过一段时间的 HTML 和 CSS 了,那么你应该接触过不少的特效和外部库了吧?

  我们先探讨“外观样式”方面的。

  样式的设计应当遵从一种事先整理好的概念模型,我们发现很多开源的样式库,或者一些大型企业(指国外)都遵宗这一道理(交互方面也是如此)。

  如果你确定了网页的整体颜色,接着你会确定一个或几个与其搭配的颜色,例如按钮,接着我们遇到的问题是,按钮需要几种色彩,多少种设计?例如:灰色、黑色、蓝色、红色、黄色、绿色,接着定义了两种外观:填充背景色的 和 缕空背景色(有线条轮廓)。

  接着我们遇到了一些类似按钮或就是按钮的东西,如果你没有系统的规划,你可能为它再单独的写一个样式。

  对此,我的建议是,如果 黑色 的按钮没有存在的必要(使用不到那么多颜色)那么可以取消它,而如果你只打算控制少数色彩,既按钮只需要留下 灰色、蓝色、绿色 这样三个即可,它们通常可以应付大多数情况。而外观,如果可以省掉 缕空背景色 的按钮设计,那么就取消它(缕空型的用于 tab 性质的按钮,通常两个连一起)。

  设计中的页面元素数量和我们经常看到的“你能控制3种颜色就足够了”是相同的道理,过多的色彩如果无法控制,页面会显得凌乱,而设计元素也是相同,当你设计了五彩缤纷,而或是有各种造型的按钮,它们同色彩一样,是一种很难控制的事情,又或者说,能少既少。除非,你能确信它的存在是非常必要的,这个按钮必须不同于之前的。

  对于其它模块也是如此。甚至对于一个按钮的细节。

  如果你还未系统的整理过 CSS 的规划方式,我的建议是去看看不同的样式库,它们往往都有规划(它们必须规划),它们会告诉你一个网站通常有哪些元素模块,接着你得学习如何将这些模块最有效的写出来,复用性,可以用在各种情况,并很好的将它们以代码的形式规划部署在你的代码文件里。

  接着我们再将“交互”中的取舍。

  我经常看到一些网站特效非常的多,的确 CSS3 和 JavaScript 为我们提供了非常多的动画和过滤效果。

  但你要比样式更注重一个问题:阅读成本。以及其中的 视觉中断 问题。

  任何一个交互过程,都会导致用户大脑的暂停,让他来响应你的交互效果。甚至你可以理解成,当鼠标经过一个超链接,如果只是改变背景色,那么用户的大脑接收到了这一改变,它只有一个信息:鼠标经过时该链接变成了某颜色。而如果你加了 0.2s 的缓冲,并且做了 :before 或直接的下划线。那么用户大脑所要处理的事情就不只是颜色了。虽然这个消耗成本或许并不大。但是你的确多给了用户很多信息,不是么?

  当一个交互涉及的内容比较大,那么会带来的结果是,用户的注意力被分散,暂停,又或者说被这个效果所吸引导致暂停。例如我们在一个 table 列中,让用户鼠标经过某行时,这行的背景色发生变化,当你做这件事时,并不应该把它当成一种效果,而是一种目的,目的在于让用户把这个变化作为视觉焦点,让用户更容易,或有意的让它锁定在这行。

  你会经常看见有一些导航菜单的设计,那么我来描述一个非常复杂的:页面载入时,导航以一种特效形式出现,接着当鼠标经过菜单中的某个时,该项会有一个比改变背景色更复杂的过滤效果,接着以一个特效列出了它的二级菜单,接着鼠标指针在不同的二级菜单列种游荡,每次经过菜单都会有一个 CSS 过滤效果,并且给它加了动画和装饰,而且每个项都有字体图标,再用户点击它的时候再来一个变化……

  非常高端,但是,有什么用呢?实际上如果你以用户的视角去体验,这些特效反而会使你觉得这设计真差!

  我们需要的是一个方便我们寻找和切换类目的菜单,这才是它的目的,如果没有缓冲的改变背景色太过直接,那么我们可以加上 0.x 秒的缓冲使过程显得柔和。安卓当前的设计即是如此,一切都非常简单,会有简单的过滤效果,最后在用户点击的时候背景色产生一个动画的原形扩散,它们本身都保持了样式外观上的简洁性。

  不必要的东西都可以不存在,每一项设计都存在着一个目的,以及用户的阅读成本,它都会带来一个利好,但都有其对应的消耗与相反的弊端。

  交互中的特效应当作为一种点缀,整个网站都不需要存在过多这种设计。

  网站的根本目的是在于用最好的方式展示出用户希望获得内容信息,以及我们有时希望用户聚焦的信息。

  如同我们用纯图标代替一个文字按钮,它除了美观,也是为了让用户可以更快速的了解这个按钮是做什么的。

  对于过程性的交互,简化它,很多时候,我们向用户表明的内容无非只有:账户菜单,内容分类,和正文。

  最后,一个鼠标经过缓冲效果应当最好是在 0.1 ~ 0.3 秒 最多 0.5 秒,交互中的展示和收纳也是如此 不要超过 0.5 秒,并且你应该将所有动画的缓冲时间规定在固定的几种,例如我的动画大部分都是两种:0.3 和有时候如果 0.1 太短 0.3 太长 会偶尔的有一个 0.15 0.2 0.25 之类的……

Web 设计中关于 DPI 的一些事情

  我经非常提及设计的一些细节问题,今天要讨论的是关于 DPI 这个细节,也许你已经注意到了一些问题。

  iOS 设备,从 iPhone 到 iPod,的分辨率放大方式,从初代的 1:1 到后来的 2:1 接着 iPhone6P 的 3:1,我们观察到它都是成倍数的放大,一个整数。

  而市场上很多的安卓设备却并非如此,它们的放大方式早期存在很多的 1.5:1,直至今日,我想你能找到 2.5:1 的设备。

  这件事的结果在于,当我们在代码中绘制 1px 抵达 2:1 设备实际绘制的是 2px 实际分辨率,而在 1.5:1 的屏幕上则绘制的是 1.5px,这也就造成了内容渲染结果的模糊。

  如果你使用过这些安卓设备,尤其是在 Web 上这个问题尤为突出,因为任何像素单位设计之初都是以整数绝对像素来定义的,即便是 rem 换算成像素点也是如此,而系统或浏览器无法处理好这种结果。

  它在 App 的设计也有表现,安卓 QQ 的一些版本有一些缕空的按钮(背景色透明有边框线条),这时线条所描绘的就是一个 1.5 像素,你会感觉到它显示的有些模糊,或者说有些问题。

  而系统 UI 自身则很少有这种问题,安卓自身在设计的时候考虑到这个情况就可以将原本的 1px 在 1.5:1 的设备上处理成 1px 或者 2px 而不取 1.5px。这体现在某些应用程序上也同样适用,或者拿字体和图标举例,如果字体并非对 1.5 放大倍率做过调整,或者图片形式的图标没有对这个中间值进行过特别优化,那么它的显示结果就不如倍数放大的设备。

  对于厂商来说需要注意这个问题,当然,对于一些设备而言可能硬件上有难题无法处理,如果取 1:1 内容显示的太小,而 2:1 则太大(显示范围非常小),但无论如何,这样做都是不好的。

  iOS 设备的精湛之处或许并不在于屏幕的色彩和 DPI 有多高,它一开始就知道放大倍率带来的结果,这个结果的影响力大于你的屏幕参数具体有多高,即便再出彩的屏幕,如果存在着非倍数放大的 DPI 设定,那将是毁灭性的,任何形式的 UI 与 文本 都会受此影响,结果是相当糟糕的。

在设计中会带来的一些 BUG:

  第一个是上面提到的像素模糊问题;

  第二个是因为 1.5 这种值的存在,相邻色彩块中间可能出现 0.5px 的断裂,当两个纯色模块靠在一起,本身是没有间距的,然而在这种设备下中间会有 0.5px 错位出来的显示结果,如同早期 IE 中经常遇到的 1px 莫名其妙的溢出。解决方法是将块元素 margin 减去 1px 加上其它代码调整成一个在两种 DPI 下都能正常显示的结果。选一些重点的调整即可。

  第三个问题是模糊,这可能跟浏览器有关,但目前普遍使用的 WebKit 一直存在这个问题,如果某个元素存在着透明度或不固定形式,那么在某种情况下会导致该块区域显示结果模糊。解决方法是针对它取消透明度,或者更多的调试也许可以获得一个既保持透明度又没问题的结果(例如文本区透明度,那么我们不让它透明,而改变文字本身的颜色灰度好了)。

  强调一下,除了 Web 在 App 设计中这个问题也存在,而在 Web 中问题更突出,并有第二和第三个或更多问题。

  如果你更改了安卓的 DPI 让它以 2:1 整数倍数放大,你会发现你的设备显示结果清晰无比……

STHeitiSC-Light.woff 黑体-简 细体 苹果 iCloud 备忘录 字体

2015-12-16_122331

2015-12-16_120513

:joy: 继续 Windows 糟糕的中文字体表现,特别是在非高清屏。

在 iCloud 偶然的又发现这个字体,它的大小是 17M,下载地址在末尾,这个字符集不同于 pinghei 的 woff,它应该是完整的,你可以尽情的使用它!

好的上代码:

你可以在 head 标记当中添加以上这段 JavaScript 代码,它的作用是判断 userAgent 中是否包含 windows nt(桌面平台 Windows)字样,如果是则执行打印加载字体的 CSS(style)写入到 head 中。

如果你不想把代码添加在模板结构里,而放进 .js 链接文件里,它们效果是一样的(除非你有两个 head):

这样一来,其它平台和 Windows Phone 就不会载入这个 17M 大的字体。只有桌面平台的浏览器会载入。(当然如果用户切换了 UA 我们只能当那是他自己的事了。。。)

接着,你在 CSS 中应当这样调用这个字体:

为什么我们需要将 “Helvetica Neue”,PingHei,”PingFang SC”, 写一份在它前面?因为 OS X 和 iOS 可能自身就带有这个字体,又或者没有带这个字体,这个时候如果你只写 STHeitiSC-Light 开头,会导致 OS X 和 iOS 默认显示为 黑体-简 细体 这个字体,你要知道 iOS 的默认字体并不是它!因此需要在前面写一份 iOS 的默认字体来解决这个问题。当然你也可以再写个判断,两种都可以。

iCloud 中的 黑体-简 细体:STHeitiSC-Light.woff
iCloud 中配合使用的英文字体:SFNSText(以相同格式增加到代码中,截图中并未使用该字体),它的对应 CSS 为:

如果大小不对可能是 300&500 的宽设定(如果你没有定义会把 400 的显示成 500),如果你通常定义的正常体是 400 粗体是 700 那么可以把上面的 300&500 修改成习惯的大小(虽然这样的话数值是不正确的)。

—-

– – 代价也是巨大的,每个 IP 要下载 17M 加上刷新重新载入,17MB*100IP=1.7G 看着办吧,放到免费 CDN 里去。

最后,对于 UI 设计相较复杂的网页,好像换上这个字体也没有什么卵用,虽然微软雅黑的表现很糟糕,但它毕竟也是仔细设计过的,相较之下这个字体它就无法配合复杂的 UI,只是在单纯展示文字方面可圈可点。直观的可以看到它的笔画末端有类似宋体的喇叭口而不是微软雅黑的直勾勾,灰度小一些显得有点灰加上抗锯齿之后就情深深雨蒙蒙了……

在移动端用 Touch 事件以拖拽手指实现伪 hover

2015-11-02

然后有一个非常简单的方式实现

在需要的元素或者整个 body & html 根上绑定 touchstart 事件。放弃以下的蹩脚方法!

—-

前言:

  我们知道触屏设备,移动端浏览器它没有 hover 的动作效果,其次我们知道 iOS 的 Safari 与 Chrome 是不会对 hover 做出反馈的(它会在手指点击的时候瞬间执行一次 hover 效果,但随即便进入 a 标签的超链接,而假设不为 a 标签则就完全不会显示 CSS 中设定的 hover 效果),而 Android 系统下则会将触摸判断为 hover 并显示,但是它有一个严重的问题,即是 hover 状态会一直停留不取消,当我们不停的挪动手指触摸到不同位置将会看到一个非常糟糕的体验。(iOS 下的 Opera 和 搜狗 等浏览器的默认设定与 Safari 和 Chrome 不同,它的默认设定和 Android 相同)。

  以上便是这篇文章所要解决的问题,我们需要一个 hover 效果,与此同时不同的移动端浏览器或不同系统下的,使它们达到相同的交互显示效果。

正文:

  我们要实现一个怎样的 hover 效果?

  在这里的显示效果是这样的,这里的陈述将根据 iOS Safari 为基础:当我们的手指触摸到某个需要 hover 的元素,它将展示 hover 的效果(通常情况下如果触摸为点击而非拖拽挪动手指,则会直接触发 a 标签的超链接,而当我们点触的同时并挪动手指,则 a 标记的超链接则不会触发),那么我们要利用的便是这种状况,利用挪动,或者非 a 标签直接实现 hover。接着当手指松开的时候 hover 效果取消。


【触摸模块时 hover】

IMG_0636
【松开手指时 取消 hover】

  注意上面这个结果,无论在 iOS 或是 Android 它们的效果是相同的,同时“稍后观看”按是 :hover 而非我们制造的 .hover 所以 它会停留住,即便你松开了手指(因为在这里我们需要这个按钮在 hover 之后可点击),图中第1个和第3个模块是没有任何操作情况下的常态。这样就达到了一个复杂的效果。

  我们知道 js 无法直接操作 css 中的 :hover 写法,那么显然,没错,我们要自动的为触摸到的元素添加 class 使用 .hover 来塑造一个 :hover 效果。而以下我们将介绍两种情况下做这件事的方案。

  首先第一种情况,是一个完整的全新的设计时可以用的:

  此时发生的事情和 CSS 需要相应做的事是:body 中的任意标签 在 hover 与 拖拽时均会给该元素添加一个 .hover class,所以我们的 CSS 当中,将用 .hover 完全的取代 :hover(:active :focus 等保持原本写法),如此一来无论桌面系统的鼠标 hover 还是触摸时 hover 的表现结果是相同的这点不用担心。上面的代码我们分别定义了 touch 事件的 触摸 拖拽 为 添加 class,而结束时 删掉这个 class。

  第二种情况是你的项目已经开发到了比较完善的程度,此时无法完全的使用 .hover 取代 :hover(其实改改应该也不难),又或者你只希望这种动作只发生在某些特别的位置:

  以上的代码将 body * 选择器写成了 class(这是你需要指定的位置),当然的你可以指定多个 class,不同之处在于,因为你的 CSS 本身已经设定了 :hover 代码,这个时候当你将 :hover 需要效果的部分同时增加上 .hover 会造成两种同时存在的结果。所以我们需要每一个动作都有一个反向的 .no_hover,同时你需要对 .no_hover 添加上反向的 CSS 代码(即未触发 hover 时的样式 还原回效果)。

  我推荐第一种方法,但它的开销可能大一些,每次 hover 都会对 dom 进行操作,因为第二种方法需要写的 CSS 内容会多很多,但如果只是很局部的使用则第二种比较好。推荐第一种的原因在于,如果浏览器的默认设定得到了改善,到时候你只需要批量的将 CSS 中的 .hover 字样替换成 :hover 一切就会恢复成通常的方式了。

  这是非常值得尝试的一种效果,它让 Web 在触屏设备上拥有了如同 APP 一样的交互效果,不要小看它,虽然代码并不复杂,要知道越是基础的东西,越是看似简单的东西,越为重要,比起复杂炫酷的特效,我们在屏幕上操作最多的这种基本动作反而更影响体验,着显细节。

末尾:

  你恐怕要着一段代码阻止移动设备长按浏览器而弹出的菜单,这是必须的,iOS 下的代码很简单,只有一段 CSS 就可以做到,而 Android 要麻烦一些(我暂时没有找到方法 过往的 js 似乎对 Android 5.x 的 Chrome 就不起效)。如果你有对安卓的方法,请多指教。

-webkit-overflow-scrolling: touch; 隐藏滚动条

如果你不知道 -webkit-overflow-scrolling: touch; 是什么意思,它是用在移动端 webkit 内核浏览器的一个滚动条效果,通常我们的页面滚动(body 会默认采用这种方案无需代码声明)当手指触摸滑动时,它是不会以一种惯性,带回弹效果的滚动,而这段代码即是让它拥有这种像 App 一样的效果(很显然它是非常有必要的,完全可以全局的变成默认行为),历史就不写了。

在我使用这段代码的时候它随即带来了一个问题,-webkit-overflow-scrolling: touch; 所带来的滚动条在未滚动的时候是隐藏状态,而当手指尝试去滑动滚动条就会显示出来,然而这个控件的样式并非像桌面浏览器可以自定义,也就是说无法隐藏。我尝试在互联网上搜索中英文解决方案,但是都没有结果。最后通过 Google 的手机版找到了这个方案。

首先我们假设这样一个结构:

或者你可能用的是 div 而不是 nav,这里并没有关系。首先 li 层也没有关系。

那么你设计的滚动部分可能在 ul,假设你的 ul 设定高度为 40px,并且隐藏了纵向(Y)滚动条,且允许横向(X)滚动;至此 nav 可能并没有做什么设定,又或者你也对它设定了一些参数。

隐藏这个 ul 所产生的横向滚动条的方法是:将 ul 的高度提升为 51px(增加 11px 左右),而后锁定 nav 的高度为 40px,并且对 nav 也做 x y 轴的滚动条隐藏(让超出的 11px 不会产生纵向滚动,而滚动条则位于 overflow-y: hidden; 所遮挡的部分,这样就达到看不见的目的了)。

对于自动变化高度的横向滚动条暂时好像这个方案并不能解决,不过一般都是固定高度吧?

我发布这篇文章的时候 谷歌的搜索主页(搜索结果菜单)是以这种方式解决这个问题的,你可以更改浏览器 UA 尝试看下它的源码。

其实这是一个很初级的 CSS 使用思维,但是我零零散散花了很长时间去解决这个问题,起初的思路是寻找有没有哪句代码可以直接隐藏掉它,随后我打算用 js 去做这件事代替 -webkit-overflow-scrolling: touch; 但是想想这挺蠢的。末尾无意间闪过 Google 的工具条……

另外一个小地方,如果你把 -webkit-overflow-scrolling: touch; 定义在了 body 可能出现标签页白屏的问题,所以你应该这样做:

不要定义在 body(body 和 html 会自动带有这种效果),而定义在,你的滚动条多半只可能出现在的几种类型,例如 nav div 和 ul。

目前为止 iOS 8.4 中的 Safari 不会白屏,但其它浏览器如果定义在 body 均会白掉。