月归档:四月 2017

使用 Media Query 检测设备 Reduced Motion 设置

最近在看《Smooth Scrolling and Accessibility1 》这篇文章时,发现在 Safari 10.1 中增加了一个好玩的访问性检测——Reduced Motion2,因此可以通过特性检测区分并对一些配置较差或主动开启「减弱动态效果」的用户进行体验优化。 开启「减弱动态效果」 「减弱动态效果」设置无论在 MacOS 还是 iOS 里都隐藏的比较深: MacOS:进入「系统偏好设置」-「辅助功能」-「显示器」,开启「减弱动态效果」;3 iOS:进入「设置」-「通用」-「辅助功能」-「减弱动态效果」,开启选项。4 开启「减弱动态效果」可以有效地降低 MacOS/iOS 系统糟糕的晕眩效果性能开销,从而达到系统更流畅的功效。 特性检测 Reduced Motion 功能的检测关键词是 prefers-reduced-motion,使用 CSS Media Query 就可以针对开启「减弱动态效果」的用户进行页面性能优化: @keyframes ambient { // Keyframes for an ambient animation that is purely decorative. } .background { animation: ambient 10s infinite alternate; } @media (prefers-reduced-motion) { // Disable the non-essential animations. .background { animation: none; } } 使用 JavaScript 则是使用 matchMedia 检测,还能监听改变事件: var motionQuery = window.matchMedia('(prefers-reduced-motion)'); if (motionQuery.matches) { /* reduce motion */ } motionQuery.addListener( handleReduceMotionChanged ); 用 Safari 查看下面的演示,按照上面的切换方式来观察不同。 See the Pen Reduce Motion Media Query Example by Eric Bailey (@ericwbailey) on CodePen. 使用场景 因为这是 MacOS/iOS 独有的设置,所以目前也只有在 Safari 里可以一用。这个功能非常适合为低配置设备的用户以及追求性能的用户做体验优化,因为很多用户会开启「减弱动态效果」来在旧设备上提升系统流畅度。 比如我的博客背景有一个大的 Canvas,很多人反映说访问时风扇狂啸,那么就可以在检测到开启「减弱动态效果」时主动关闭一些无关紧要的动画从而提升用户的体验。 如果碰巧你用的不是 MacBook,那么你应该去买一个:-P -- EOF -- Smooth Scrolling and Accessibility ↩︎ Reduced Motion Media Query ↩︎ macOS Sierra: Reduce screen motion ↩︎ Reduce screen motion on your iPhone, iPad, or iPod touch ↩︎ Update 2019.04.25:自 Chrome 74 起,也支持该特性检测了。

发表在 前端开发 | 标签为 , , , | 2 条评论

解决 VMware Fusion 中虚拟机启动时报「Could not open /dev/vmmon」的问题

最近在做 RN 开发,安装了 Genymotion 模拟器。之后发现开 VMware Fusion 虚拟机调试旧 IE 时,会在启动时报「Could not open /dev/vmmon」的错误导致无法启动。 Could not open /dev/vmmon Failed to initialize monitor device 如果用 sudo kextutil /System/Library/Extensions/vmmon.kext 启动则会报错: Kext com.vmware.kext.vmx86 failed to load (0xdc008017). Failed to load kext com.vmware.kext.vmx86 (error 0xdc008017). 在网上搜了一下,原因是 VMware Fusion 跟 VirtualBox(Genymotion 和 Docker for Mac 都会依赖的免费虚拟机应用)共存时,如果装了太多虚拟机或虚拟设备,会导致双方共同占用一项共享的系统资源(major device number),导致它被 VirtualBox 占满时 VMware Fusion 中的虚拟机无法启动。解决的方法很暴利,卸载 VirtualBox 就行了。 卸载完可以使用指令 sudo kextutil /System/Library/Extensions/vmmon.kext 启动,然后通过 kextstat | grep vmx 就可以看到已经启动成功。 相关文章 https://communities.vmware.com/thread/469762 https://communities.vmware.com/thread/456399 https://communities.vmware.com/thread/430034

发表在 软件技巧 | 标签为 , , | 留下评论

使用 BEM 的几个注意事项

最近在做新的博客主题,又恰巧在整理 HTML 中为元素命名方面的心得,就借机重温了一下 BEM 文档。或许是太久没看官方文档,我发现 BEM 如今已经延伸到了 Web 开发实践的范畴,而不再是一个单纯的命名规范。好坏不谈,总结一下注意事项。 命名规则 过去的 BEM 语法冗长丑陋,期间也经历了几种方式(现在依然共存): /* 旧:破折号式 */ .block-name {} .block-name__element-name {} .block-name__element-name--modifier-name {} /* 旧:驼峰式 */ .blockName {} .blockName--modifierName {} .blockName__elementName--modifierName {} 而现在的命名规则主要是对修饰符的连接符做了调整——破折号改为单下划线链接: .block-name {} .block-name__element-name_modifier-name {} 如何使用块与元素 如果一个区域可以复用且不依赖其它组件,则可作为一个块(Block)。 如果一个区域不能拿到外部单独使用,那么就应该作为一个元素(Element)。 元素不能单独使用,只能作为块的一部分使用。元素不能包含元素,因为这样做会妨碍块内部元素位置的层级调整。 <!-- 错误范例 --> <form class="search-form"> <div class="search-form__content"> <!-- 应该使用: search-form__input 或 search-form__content-input --> <input class="search-form__content__input"> <!-- 应该使用:search-form__button 或 search-form__content-button --> <button class="search-form__content__button">搜索</button> </div> </form> 如果一个元素可以继续分解,则可使用「元素 + 块」混合的方式另起一个空间,下面会单独介绍。 修饰符的改进 修饰符(Modifier)用来修饰块或元素的外表、状态或行为。修饰符不能单独使用,而且必须绑定在对应的块或元素上,不能混搭。 <button class="button button_active">...</button> 现在除了布尔值修饰符,还可以使用 Key-value 形式。 一般来讲,如果修饰符的值可有可无(disabled、readonly 等,有则是 true,没有则是 false),那么可以省略修饰符的值。 如果修饰符的值可以有多种状态,则使用 Key-value 形式。 另外,因为修饰符的连接符从 -- 变成了 _,所以并不像过去那么丑陋了。 /* 使用布尔值表示状态(禁用、可见、聚焦等) */ .btn_disabled {} .header__search-form_focused {} /* 使用 Key-value 表示选项(尺寸、主题、类型等) */ .btn_size_s {} .search-form_theme_dark {} .menu__item_type_text {} 为什么修饰符一定要包含块名或元素名? 每一个块都会建立独立的命名空间,可以有效的减少命名冲突; 显式说明修饰符所对应的块或元素,防止混淆; 代码搜索更加准确方便; 不包含块名或元素名,使用修饰符就必须使用组合选择器(.btn.disabled),这会增加样式权重使其难以覆盖。 使用混合拆分样式 在 BEM 中,位置和布局样式通过父级块来进行设置。这就需要通过混合(Mix)组合块与元素,组合多个实体(块、元素、修饰符都被称作 BEM 实体)的表现与样式,同时不耦合代码。 <!-- header 块 --> <div class="header"> <!-- `search-form` 块混合 header 块的 `search-form` 元素 --> <div class="search-form header__search-form"></div> </div> 上面的例子通过混合的方式把位置样式从块中剥离,然后就可以在 .header__search-form {} 中设置表单的位置或浮动等样式,从而保持了 search-form 块的样式独立,对其完整样式代码进行了解耦。这并不陌生——在传统命名方式中,我们经常通过嵌套的方式(.header .search-form)对局部样式进行调整。但这样做会改变选择器的权重。在 BEM 的思想中,保持选择器扁平和低权重是一个准则。 因此,在使用 BEM 时需要格外注意遵循它的工作方式: 不在块里设置位置、布局相关的样式,只设置基本样式; 通过混合的方式,在作为父级块的元素时设置布局样式; 适时拆分元素为独立的块,解耦样式并形成新的命名空间。 避免组合使用标签与类选择器 在 CSS 中使用 tag 一直不是一个好的实践,但在有些时候却难以避免。唯一需要注意的是 a.btn 是无法被 .btn_active 覆盖的。因此组合使用标签与类选择器时要格外注意。当然,最好还是避免使用。 适时使用嵌套选择器 很多人说 BEM 是「禁止嵌套」的,这不完全准确。BEM 只是建议尽量保持嵌套层级越低越好。因为 CSS 的权重问题很多人处理不好,最终恶果就是不停的嵌套和为了增加权重而进行的无意义嵌套和 !important,这无疑增加了代码的耦合。 在你需要通过块状态对内部元素进行调整时,使用嵌套是很好的选择: .btn_active .btn__text {} .search-form_foucsed .search-form__input {} .nav_theme_dark .nav__item {} 块不一定是一个视觉上的区块 在批量设置多个样式时,可以使用混合的方式建立一个纯样式抽象的「块」。此时块不对应页面上具体的一块区域,而是代表一组抽象样式。 <article class="article text"></article> <footer class="footer"> <div class="copyright text"></div> </footer> 上面的例子把 .text 作为一个单独的文本样式块,用来声明特定的一种文字设置。 .text { font-family: Arial, sans-serif; font-size: 14px; color: #000; } 同理,页面整体布局、栅格系统等,都可以作为单独的块来设置。 开放/关闭原则 任何 HTML 元素都应遵循向修饰符开放并拒绝改变的原则。换句话说,就是一个 HTML 元素应该便于通过修饰符对齐进行样式覆盖,但是不应该频繁对其本身进行修改,因为每次改动都将影响到所有元素。 切换到 BEM 式 CSS 把 DOM 模型扔到一边,学习创造块。 不要使用 ID 选择器和标签选择器。 最小化选择器嵌套。 使用 class 命名约定来避免命名冲突,确保选择器名称具备自解释性。 用块、元素和修饰符的方式工作。 把可能会改变的 CSS 样式属性从块挪到修饰符里去。 使用混合。 把代码拆分成独立的部分从而更容易的使用单独的块。 重复使用块。 总结 使用 BEM 的好处有很多: 自解释性很强,看到即看懂。 强制 「块--元素_修饰符」结构,命名重复可能性大大降低,有效地防止了样式污染问题。 抽象核心样式,通过修饰符的方式减少代码复制。 提供良好的扩展性。 而且现在 BEM 除了针对 CSS 的方案,在 JavaScript、文件解构上也有了充分设计。按照官方的姿态,BEM 已经不应再作为 SMACSS 或 OOCSS 的类比,而是接近 Web Components 的产品,同时提供了完整的针对项目的构造方案。 我个人还是更喜欢把它当做一个单纯的 CSS 命名方案来看待,因为在组件化开发的方面,现在有很多更好的方案可供选择。另外 BEM 也不是万能灵药,它虽然解决了命名冲突、权重混乱等问题,但在模块组织上并不是特别清晰,借鉴一些 SMACSS 中的思想会让你的项目更加清晰有条理。 光说不练假把式,在接下来的新主题中就会用 BEM + SMACSS 来操练一番。 -- EOF --

发表在 前端开发 | 标签为 , , | 留下评论

GTD 对个人效率的提高和「7个习惯」学后感

刚刚忙完了紧张的工作周期,紧接着就在周末补充了一下养分,学习了「7 个习惯」。原本分享的内容刚写了一半,干脆停下来趁头脑清醒结合之前学习的个人效率提高方法总结一下感受。 我在大概 4 年前开始关注个人效率提升相关的内容,当时我刚离开广州申请了 SOHO 的机会。虽然工作内容没有变化,但在家工作无论是时间还是精力上自己都有更强的把控,因此有一个契机可以践行所谓的「GTD」、「番茄工作法」理论。直到今日我还在使用 GTD 理论替代我的大脑进行任务规划与跟踪处理。 Getting Things Done GTD 的核心理论是清空大脑,把所有个人事物的处理安排都转移到工具中去,从而让头脑专注于解决要事而不存杂念。 因此,使用 GTD 可以最大程度地把大脑从「任务管理助手」的工作中解放出来。在 GTD 理论中有一个经典的两分钟原则:如果一件事能在 2 分钟内完成,就立刻去做。否则就直接交给管理系统来暂存(丢给 GTD 理论中的「收件箱」)。在「7 个习惯」的学习中,我发现自己在第三象限(紧急不重要)耗费的时间明显比其他人少,这应该得益于这套理论。而通过 OmniFocus 的聚焦与透视功能,我可以清晰、准确的知道下一步应该干什么。 GTD 过程 具体落实到生活和工作中,就是遇到任务时、脑子里忽然蹦出想法时,根据两分钟原则去判断立刻完成还是丢到收件箱去,灵光乍现时不做深入分析而是快速捕捉想法。然后在固定时间把收件箱里的想法分配到各个分类、任务中去。同时结合定期的回顾、修正目标,把大任务拆成小任务,并逐一实现。 我经常按电脑的工作模式去分析人脑:一个人如果同时做多件事,精力和头脑往往应付不来,因为「内存」是有限的。即便你不同步处理,在脑海里记录一个顺序,依旧无法发挥最大功效,因为这些要事和琐事就像「计划任务」一样存在于系统中,你始终需要一个钟表去定时检查他们的状态。在学习和使用 GTD 理论的这几年里,头脑可以真正松弛、淡定的完成生活与工作中的事务。当然惰性会影响效果,但已然提升了很多。 GTD 实践 在具体的工作中,我通常在收集完任务后,每天 1 次对所有新任务进行整理和拆分然后切换到公司的透视下开始工作,这个透视下只展示所有工作项目的下一步任务(不是全部可用任务,也不含未来任务),这样待做列表项目并不多,不会造成额外的压迫感。每天下班前再对今天未完成的任务进行简单回顾和补充。 另外,工作期间不设提醒任务,避免不必要的中断。下班时间则可以放松处理打扰任务和统一解决相对紧急的非工作任务。 其它理论 另外值得一提的是「番茄工作法」,它算是一种更具体地执行方式。我不谈结果,但就像达芬奇睡眠一样,长期的坚持或许能带来效率和时间上的优化,可它在实际工作中实在难以落实。我在家 SOHO 的那段时间里曾坚持使用,但随着换了公司也不了了之。 「7 个习惯」 如果说 GTD 是面向任务和个体,专注于完成和克服拖延的方法,那么「7 个习惯」则是个人素质提高的解决方案。它不光在意品性,还注重对待他人技巧。所以更适合职场。 主动积极 习惯一是关于个人责任和态度。主动积极的核心是「我」。万事都以我的意愿为出发点深度思考,不埋怨或直接反射外在的因素(三思而行,避免不过脑子),相信积极的作用,同时主动创造先决条件(使用积极的语言)。 关于这个习惯最让我有新鲜感的是影响圈的内容。不为关注圈消耗情绪,精力集中在影响圈。结合到自身工作,技术与行业发展不是自身可定的,仅保持关注,不掺杂情绪(因为并没有什么卵用)。主动积极的态度是专注自己能影响到的(个人技能提高与项目质量),并不断向外扩散自己的边界圈,影响跳起来就能够得着的果子。 以终为始 想法做事有目标和愿景,比如先挣它一个亿。感谢前面说的 GTD,它让我 check 的每一个勾勾都有意义。并且我知道它们的重要性。以终为始更宏大的意义就是定义长远的人生目标。抱歉,程序猿猝死的太多,这个问题我不敢多想。 要事第一 四象限图表可以很好的分析个人的工作效率,但更多的是分析和比较结果,适合定期检查。再次感谢前面说的 GTD,它带我实战。 双赢思维 情感账户与利弊分析,职场「套路」第一弹。在多人协作中最重要的就是 1+1 能否 >2 的问题,双赢思维是寻找共同利益的技能。实际的工作中,不可能永远双赢,保持主动积极的心态,创造双赢的机会。写博客、做分享,都是双赢思维,因为知识共享带来的是共同提升。 知彼解己 运用同理心理解别人的真实诉求。职场「套路」第二弹。了解他人,获得他人的理解。知彼解己无论在工作还是生活中,都是提高沟通效果的技能。 统合综效 珍视差异,寻求第三方案。双赢思维和知彼解己都是统和综效的先决条件,它们组成完整的团体任务流程。很多时候,集体讨论的方案会远优于个人方案,尤其是差异性集体的力量,更能碰撞出火花。因此,要勇于探索陌生的区域,勤于总结差异的价值。 不断更新 一个关于每日自我更新的习惯。就像 GTD 每日整理任务、每周回顾任务一样,不断更新是辅助自我克服拖延的习惯。坚持的力量需要时间来检查结果。习惯七从身体、心智、情感和心灵四方面持续锻炼,并且以天为单位进行更新,利用成功感去保持积极性。同时,习惯七建议找朋友一起计划,相互督促。跑步、健身、「GitHub 马拉松」等,无一不推荐这样的方式。 总体来讲,「7 个习惯」的核心是通过培养品性使人从依赖到独立,再通过技巧使人从独立到互赖的持续成熟地模式。 GTD 与「7 个习惯」的结合 随着后者的学习,我逐渐发现像 GTD 这样的理论集中在「事」,是一个规划和解决的工具。而「7 个习惯」则是在更宏观的角度,改善人的处事态度,提高生活的满足感。 具体在实践上,在 OmniFocus 中,主要视图是树状排列大脑想到过的所有可做的事,通过透视或下一步任务去筛选执行的顺序。最主要的是帮你把大小任务啃掉。而它最缺乏的就是中、长期的对已完成任务的分析和回溯。在习惯「要事第一」和「不断更新」中,则以天为单位,更好的观察到自身的进步。而 GTD 理论中虽然可以建立常态的重复任务,但是并不分析结果:只要任务完成,GTD 在这件任务上的使命就结束。另外,无论是 OmniFocus 还是 Things,在日历视图(宏观浏览周、月概况)均不方便,更多是为了进行任务预测,对任务耗时、精力分配没有很好的展示,在排期时或许会出现不合理的情况。 因此,「7 个习惯」除了主动积极、双赢思维、知彼解己、统合综效这几个思想习惯,其余的行为习惯都可以和 GTD 融合在一起。比如在日历中只进行二象限事务和情感、情绪事务记录,并且只用来概览和回溯。而各象限事务的具体实施和每日提高的提醒都交由 GTD 工作处理,使其更多的作为一个分配任务和通知的工具,保证计划顺利完成并敦促自己提升。同时指定定期任务,每周末找一个安静的时间对个人中长远目标做总结和思考。相信这样的结合可以最大程度实现习惯培养与工具的有效利用。 关于自我不断更新的四个方面,结合近两年生活和工作的变化,还有一些想总结的,等有空再说吧。写分享去了…… 对了,最最后的,惰性才是阻碍效率提升的最大敌人。下定决心做的事,无论如何都要坚持下去。 -- EOF --

发表在 不想分类 | 标签为 , , | 留下评论

Safari 10.1 中的 Web 新特性

New Web Features in Safari 10.1

发表在 不想分类 | 留下评论

[译] 6 种 JavaScript 展开操作符的绝妙使用

David Walsh 写的一篇关于展开操作符和剩余操作符的文章。 继续阅读

发表在 前端开发 | 标签为 , , | 留下评论