Emotionally Complicated Class Names https://css-tricks.com/emotionally-complicated-class-names/amp/
分类: 前端
以html+css为主的网页技术
-

Compass + cleancss 导致的灵异小问题
问题不大,不过很诡异。代码如下:
SASS:
.some-class display: none .other-class:blank display: noneHTML:
<div class="some-class">...</div>理论上说,这样这个div应该不显示。在本项目中,它的确没显示;但是在另外一个将本项目作为依赖的项目中,它却显示出来了。
经检查,本地开发和部署时,直接使用 compass compile 生成CSS,compass 配置中,设置输出模式(output_style)为
compressed,结果是这样的:.some-class{display:none}.other-class:blank{display:none}而在作为依赖时,用到的则是 grunt-contrib-cssmin 处理过的CSS,刚才那句就被压缩成
.some-class,.other-class:blank{display:none}:blank伪类尚未被Chrome中支持,于是整条规则都被忽略,导致div显示出来。 -

啊,前端的轮子啊
时势造英雄。
IT科技几十年来诞生过不少概念,但直接拿来就能作为宣传材料的不多,HTML5算一个。借助智能手机、微信微博快速普及带来的平台优势,HTML5快速成长,接连攻陷投资界、创业界、广告界,现在说起H5,在我的圈子里几乎无人不知无人不晓。
资金充裕,整个行业自然地位上升,财务上升;继而自然从业者增加;继而就会出产大量的产品。而作为前端从业人员,最大的感觉就是:轮子真TM多啊……这不,我前几天计划学习一下近来出现的各种新技术,今天正好看到Bable最新入门The Complete Guide to ES6 with Babel 6,正好我写xgame-api的时候饱受node不能完全支持ES6之苦,马上坐正准备好好看。
然后就看到:
Keeping up to date
Here’s a little story: while writing these guides, I learned that the require hook in babel-core used by Gulp and Mocha is already set to be deprecated.
跟上变化
讲个段子:就在我写这套入门的时候,babel-core里的
require钩子,就是Gulp和Mocha使用的那个,被标记为“弃用”Babel6是24天之前发布的,这套文章是上周写的,核心API已经发生变化了。这让我不禁去想,紧跟业界潮流的成本会不会太高了?ES6的确提供了不少语法糖,以及终于像样的模块管理。如果现在就开始使用ES6,不仅可以提前享受到这一切,到标准真正到来的时候,可以省去升级的时间。
不过这里面之考虑了标准变化,没有考虑需求变化和产品变化。如果是抽象性很强的代码,比如某种算法库,或者某个功能组件,那么从开发之日起,遇到的变化可能不会太多太大。但如果是业务代码,就不得不遭遇各种各样的修改和变化,于是功能稳定便于维护就更加重要。紧跟潮流,意味着必须付出多余的精力去应对各种不稳定导致的节外生枝,一不小心,业务逻辑就要延期交付鸟。
又有个切身例子。Tiger Prawn(后面简称TP)立项的时候,模块管理无论是AMD还是CMD还是sea.js都难以让人满意,所以我就用了最简单的直接引用和命名空间。前几日用Browserify感觉不错,赶上TP遇到个问题,就寻思着重构下。结果努力一天之后,架构变化还是太复杂,遂放弃。次日修正实际问题只花了半天。生产中,还是优秀的架构设计更重要,毕竟开发和维护效率至上;追新追潮流几乎都可以算是作死的行为。
那么什么时候学习新技术呢?程序员都应该做业余项目,不是私活,而是根据一些平日里瞎想出来的需求,用一些新技术去实现,即使实现不了,也能够实地演练各种新技术。这样,有朝一日新技术成熟了,就可以很快应用到新产品中。
-
纯CSS实现toggle按钮
将来要用到,提前准备一个。
-
新项目:诺兹多姆,时间的守护者
其实也不算新项目。加入点乐之后,我的主要任务之一就是做后台。我是个自视甚高的人,所以要做就做最好用的后台,经过不懈努力,现在的点乐后台V3.3版,无论从开发的角度还是使用者的角度来看,(应该说)都已经非常好用了。
不过问题仍然有很多,主要分为两方面:性能和弹性。
性能
先说性能,最初的版本是完全PHP的,用户操作都基于表单。我将其改成加载局部HTML片段,用户操作主要用ajax实现。显然,后台不可能停工,所以我边改边上线,架构上基本继承前人的设计,比如,大多数页面没有分页功能(很多同事用习惯了,也要求不要加分页)。
于是,大多数页面都要读取符合条件的全部数据,然后由Javascript实现排序、筛选、搜索等功能。当初我这么做的时候,公司业务量小,没什么问题;如今公司发展起来了,业务量越来越大,每次都加载全部数据,页面性能越来越差。尤其是手机端,很多页面一开就死。无奈之下,我只好先用Javascript分页顶着。
弹性
曾经懵懂少年的我动手时还不太会用Backbone,没有理解其精髓,只是觉得Backbone.View的事件代理比较好,写起来蛮舒服;更没想到借助Robotlegs的优秀设计开发Nervenet,所以前端架构上也有问题。比较严重的是数据同步(所谓数据双向绑定),即操作人员修改了某数据,保存到服务器后再回来,页面应该更新被修改的数据。那时候Knockout刚出来,Angular和Ember都还不堪大用,数据双向绑定对我来说只是个梦想。还好我码功扎实,也能解决的七七八八,比如主功能区共用一个Model作为中介(Mediator Pattern,中介者模式),数据交互都从它那儿走,其它组件监听change事件来更新视图。
不过这样终究不是办法,因为随着功能的增加,代码里各种写死的属性和方法越来越多,代码日益臃肿,弹性也是个大问题。
诺兹多姆诞生
恰在此时,新项目来了。新项目也需要后台,我当然不会直接把点乐后台拿来重用,而是花了一些时间剥离其中的前端框架,准备将其独立出来,成为一个新项目:诺兹多姆。
诺兹多姆,青铜龙之王,时间守护者。在炉石传说里,诺兹多姆将强制把每回合的事件降到15秒,这也是我的目的,无论用户要干什么,都能在很短的时间内——不妨假定是15秒——完成。
这是个专门针对后台的前端框架,能够覆盖各种后台的需求,也能提供漂亮的界面和良好的交互。等各种希望这个项目完成后,能够达到这些目的:
- 大大提高后台类应用的开发效率
- 前后端分离,独立开发,分开部署
- 丰富的组件,覆盖后台常用功能
- 灵活的插件机制,扩展能力强大
- 漂亮的界面,可以自由更换主题
- 全平台覆盖,甚至支持打包成移动应用
开源
此项目是在公司做的,当然要以公司的名义开源。当然,开源的结果基本上还是只有我们公司在用……
现在还在开发中,离最终目标还很远。
[github repo=”Dianjoy/nozdormu”]
致谢
此项目中用到了大量开源代码,感谢他们的创作者,是他们让世界变得更加美好。
感谢公司给我这个机会。感谢同事们让公司不断成长,给我留下尝试的机会。
-
boostrap3的不良部分
Bootstrap 3的脑残部分略多啊……比如
.hidden-xs,明显应该是在超小设备上隐藏,结果里面赫然写着:display: block !important,important个毛啊…… -
![[教程]纯CSS实现多选组件](https://blog.meathill.com/wp-content/uploads/2013/10/IMG_0678-1200x896.jpg)
[教程]纯CSS实现多选组件
产品篇
在我们的后台中,需要设置广告精准投放的区域,也就是要在全国31个省、自治区、直辖市中选择。那么,出现下面这幅景象也就理所应当了:

这样做有几个问题:
- 选项很多,没有规律,找起来很累
- 如果是一个已经选择了部分选项的广告,修改时仍然需要用肉眼寻找,无法一眼看出来投放到哪些省份
- 选完一个,再选下一个,还要从头找,甚至会被已经选过的影响
于是我想,首先应该把所有选项分为“已选中”和“未选中”两批,解决第2个问题,减轻第3个问题;其次复选框本身的价值不大,可以被替换为其它样式;唯一可能引入的问题,就是点选时,用户的预期是看到复选框里出现一个小对勾,表示选中,如果我把它移开放到“已选中”组里,用户可能会迷惑,需要一些时间学习。
于是我跟某产品经理朋友聊了聊这个想法,他表示确实可能造成用户迷惑,不过如果能加入动画效果,那么基本没问题。嗯,开始动手。
技术实现篇
近日flexbox规范定案,浏览器相继支持
display:flex;,同时传来一条好消息,新实现比老实现display:box;快很多。这次我打算用flexbox来解决问题,因为里面有一个很重要的属性:order(之前叫box-ordinal-group),它可以改变布局中元素的排列顺序,配合CSS3新增的选择器,应该可以满足需要。第一步 分拆选中/未选中
(关于flexbox的知识,可以通过Google了解,虽然搜到的多是上一个版本,不过和最终版差别不大,只是叫法不同。本文不再过多讲解,我就当大家都会了)
<input type="checkbox">本身的样式不能修改,所以我们必须借助<label>的帮助;实现选中/未选中区分,那自然就要用到伪类:checked;选择器一定是从外到内、从前到后的,没法选择父级元素,所以不能用<label>去包<input>,那么最终布局就只能是:<div> <input type="checkbox" name="q[]" id="q1" /> <label for="q1">小宝3225</label> <input type="checkbox" name="q[]" id="q2" /> <label for="q2">王老白白白</label> <input type="checkbox" name="q[]" id="q3" /> <label for="q3">空夫31</label> <input type="checkbox" name="q[]" id="q4" /> <label for="q4">谷大白话</label> <input type="checkbox" name="q[]" id="q5" /> <label for="q5">Meathill</label> <input type="checkbox" name="q[]" id="q6" /> <label for="q6">一毛不拔大师</label> </div>很简单哈,不解释了。CSS3新增了“下一节点”选择器
+,用来选择某节点的下一个节点,结合:checked伪类就可以将选中的<input>和它临近的<label>通过改变order属性移到前面去:#container { display:flex; flex-direction:row; flex-wrap:wrap; } #container input, #container label { order: 2; //所有选项、label顺序为2 } input[type=checkbox]:checked, input[type=checkbox]:checked + label { order: 0; // 越小越靠前 }不过这样只是把选中的内容提前,视觉上没有真正的分割。所以我决定再加入一根分割线,上面是选中的,下面是未选的。这个时候我们需要用到
~这个选择器,选择某节点后面的节点:hr { display:none; // 默认情况下,没选任何选项,分割线隐藏 order: 1; // 分割线顺序为1 width:100%; // 保证独霸一行 } input[type=checkbox]:checked ~ hr { display:block; // 有选项被选中后才会显示分割线 }Demo如下:
这样基础功能实现了。不过视觉上,排版仍然不整齐,选中的选项和未选中的选项区分不算太明显,所以下一步我准备美化下checkbox。
第二步,美化checkbox
做法与前面类似,也要用到CSS3新增的选择器。前面为了实现
<label>提前,没有用它包裹<input>,所以在选项很多很长导致换行的时候,可能出现复选框和标签脱离的尴尬状况。好在复选框的价值可以用别的样式取代,所以先把小方框隐藏起来,转而将<label>作为操作目标,再来点边框底色圆角(参考自Bootstrap 3),就可以了:input[type=checkbox] { display: none; } label { min-width: 120px; border: 1px solid #CCC; padding: 2px 8px; text-align: center; margin: 0 5px 5px 0; background: #FFF; color: #333; border-radius: 3px; box-sizing: border-box; } label:hover { border-color: #ADADAD; background: #EBEBEB; cursor: pointer; } input[type=checkbox]:checked + label { order: 0; background-color: #5cb85c; border-color: #4cae4c; color: #FFF; } input[type=checkbox]:checked + label:hover { background-color: #47a447; border-color: #398439; }这样看起来还有上升空间,如果加上几个图标响应用户操作,那么学习成本会更低,对操作后的预期也会更准确。于是引用CDN上的font-awesome,使用
:before伪类加上小图标,就得到了最终效果:我无意中发现,这样批量添加删除时,鼠标可以常点不动,应该也是个意外的收获吧。
第三步,加入动画教育用户(失败)
至此功能基本做好了,不过由于修改了行为,可能导致用户迷惑,所以准备加个动画帮助用户理解这个交互。
可惜作为一个新功能,浏览器的支持尚不完善,虽然规范中规定“animatable: yes”,但是实测在Chrome v.30也无法工作:http://jsfiddle.net/meathill/Ka66W/1/
看来只有等新版浏览器发布后再去完善了。
兼容性
使用纯CSS做组件,几乎不用担心兼容性问题,因为浏览器本身就做了很好的向下兼容,代码最多不生效,一般不会错。
具体到这个组件,因为只针对视觉效果,没有增删改任何浏览器行为,所以兼容性也没有任何问题。不过最终效果呢,只有支持flexbox和CSS3选择符的浏览器才能正常渲染。
我的环境是Window 8 + Chrome v.30,以及小米2 + Chrome v.30,测试通过。
后记
如今CSS很强,纯CSS可以实现很多功能,希望今后能做出更多有价值的东西。分享这个组件的实现,希望对大家有用。
-
前端框架点评
前两天被人@,提问前端框架的问题。这还是第一次在微博上被陌生人提问,感觉有点小激动。今天写篇小文章,简单点评一下我用过的前端框架,希望对大家有所帮助。
本文涉及的范围
本文要点评的前端框架,都是我用过的,以JavaScript框架为主,也可能包括一些工具类库。由于前端的特殊性,弱语言HTML和CSS是必不可少的工具,运行机制导致很多成熟的工程学方法没法用,必须用工具库补充。烦请大家不要抠字眼,我一向很马虎,呵呵。
Bootstrap
一定要先推荐Bootstrap。它由Twitter的两位工程师首创,当前版本2.3.1,涵盖了文本、布局、表单、工具,除了暂时没有日期选择器之外,几乎包含了网页所需的一切。我们知道,网页出现是为了传递信息,而成熟的印刷业对其影响很大,表现出来就是,HTML中很多标签,比如
H1~H6、p等,都是有具体语义的。但很多前端框架并未给予他们足够的重视,所以往往需要我们重置或者自己动手写。Bootstrap则不是这样。它不仅包含大量组件,还帮助我们给每种可能用到的语义标签都定义了样式,又设计出很多helper;而其网格系统也能帮我们出色完成排版工作。总而言之,使用它几乎足以满足任何网页开发需求。值得一提的是,Bootstrap的组件和Widget都基于HTML标签构建,非常好用;而响应用户操作则基于对
document的侦听,所以几乎不会对我们其它代码逻辑造成影响,我们可以放心大胆的在项目当中使用。当然,Bootstrap依赖jQuery,后者近期遭遇到一些纷争。不过我还是要强烈推荐这个框架。jQuery UI
比较遗憾的是,虽然号称UI,但jQuery UI只能算作一个组件库。因为缺少基础排版支持,所以既想使用jQuery UI,又想和自己的样式保持一致会有些困难,需要花费不少时间做修改。
抛开这一点,jQuery UI也是个很好的工具,几个widget都很实用,文档丰富详实,如果项目本身对交互要求不高,只是个别地方需要一些功能补充,jQuery UI确实是不错的选择。尤其当我们需要
draggable、sortable、resizable这几个功能时,选择的余地真的不大。HTML5 Boilerplate
这个工具力图给开发者提供一个舒适的起点。他们为项目建立了标准化的目录结构,并且把常用的资源都整理在合适的位置,这样我们只需要替换它们就能保证项目对所有浏览器都有完美表现。同时,他们重置了CSS,引入了GA统计,在页面中标记了合适的输入点,这样我们能尽快投入到项目逻辑的开发中。
但这个工具的问题也很明显,它努力达成的目标,是消弭浏览期差异。假如我们只需要统一的环境就能开展工作,那H5B就足够了;而实际上,我们通常需要更多,比如排版、比如组件。所以,这个工具对我来说,学习的意义大于使用的意义。
HTML KickStart
我见过的前端框架里只有这个跟Bootstrap的覆盖面接近。它的设计更好,更鲜艳更有活力,不过最近的开发好像慢了下来。我并没有真正使用它,因为它的组件太少了。
Backbone
非常好的MV*框架,真的像根脊柱一样,把被jQuery拆的七零八散的js统一在合理的框架内,让整个项目都变得协调了。引入
Collection真的很天才,结合其出色的View设计——其实Backbone的View并不是传统意义上的View,更像mediator——可以看出,Backbone的设计者对Web开发有着深刻理解。哦,差点忘了,Router还能帮我们很好的整理单页应用的逻辑。不过js毕竟是一门很烂的语言——或者让我换种表述方式,缺陷很多,所以它尚无法做到像AS3的Robotlegs那样好。不过,如果我们希望把代码组织的更好,Backbone类的框架是不可或缺的。
Rachet
Rachet的目的和架构,很像Bootstrap,不过它瞄准在移动端。Rachet现在仍处于比较低级的阶段,组件太少,开发起来不太方便,最多相当于Kickstart把。可惜的是,移动端移动框架普遍较弱,在我看来,基于它的Junior仍然是不二之选。
Zepto
说到移动端开发就不能不提Zepto。它力图实现一个十分类似jQuery的库,不过只考虑支持移动端,所以体积会小很多,速度也会快不少。Zepto的升级频率最近也不高,不过还是到了1.0。新版Zepto放弃了ruby,使用coffee作为编译工具,支持使用者自由组合功能模块,相当贴心。
不过具体使用时,还是会有一些函数的用法和jQuery不同,需要注意。举个例子,
css函数,jQuery里支持数字,比如$('div').css('height', 100),会把页面中所有div的高度设置为100px;而Zepto不行,必须$('div').css('height', '100px')才会正常工作。jQuery Mobile
强大的jQuery团队最失败的作品。贪恋于风光的过去,迷信“全覆盖”,使得jQuery Mobile步履蹒跚,在移动平台上无法取得足够好的性能表现(早期版本甚至不支持固定底部)。而这直接带来了对HTML在移动端的质疑。有很多本不擅长前端开发的人,看到Phonegap,就直接上jQuery Mobile,结果发现性能不行,体验很差,便在各种渠道大放厥词,说HTML不行。这种行为直接伤害了HTML和Hybrid应用。
jQuery Mobile失败不仅在于此。jQuery本身方便快捷,使用它很容易养成不重视代码组织的习惯;而在移动端,单页应用占据主流,这意味着,使用jQuery Mobile很可能无法良好的组织代码,直接带来项目维护成本的提高。另外,早期版本的设计也不可避免的带有大量Web痕迹,导致实用性不足。所以直到今天,jQuery Mobile都还是个悲剧。
不过,jQuery 2.0已经beta2了,我们知道,jQuery 2.0里放弃了对IE678的支持,性能会得到不小的提升;jQuery Mobile 1.3已经引入了对hash的支持,组织代码好多了;同时,随着3次小版本更新,越来越多适用于移动应用的组件加入进来,大大扩充了军备库。我认为,未来的jQuery Mobile,值得一试。
Sencha Touch
大家可能还记得,Facebook闹过一阵,说HTML5不够好,还把他们的手机客户端用原生重做了一遍。之后Sencha的两位工程师表示不服,以HTML5为基础开发了功能几乎完全一样的客户端,他们用到的框架就是Sencha Touch。据说,它的性能比jQuery Mobile好不少。
但是,真正用了就知道,sencha touch实在太不“前端”了。它里面几乎没有给HTML和CSS留下太多位置,明明十分强力的布局样式工具,被封装成了单薄的接口;但是没少往JS框架里加内容。结果就是用起来非常复杂,随时需要看文档;自定义困难,它里面甚至有一个属性叫“html”,用来填入大段文本类型的html;数级嵌套起来的对象也很让人头疼,而且感觉维护也不会太容易。所以我做了一半就还是放弃了。劝大家也别去尝试了。
如果有哪位高人愿意以实际经验教育我的,我洗耳恭听。
-
诡异BUG之:IE下表单必须提交两次
做前端遇鬼是常事儿,比如今天,就遇到个:
- IE6~10
- jQuery 1.8.3
- Backbone 0.9.2
- HTML5头
- 一个
Backbone.View,内部有一个form,View托管form的submit事件,根据class和action进行不同的操作,或者验证数据提交表单 - 第一次提交,验证通过,
return true,没反应 - 第二次提交,验证通过,
return true,表单提交 - 其它浏览器表现正常
提炼这些Bug描述就花了不少时间,反复Google也没有什么结果。比如,StackOverflow上类似问题的解答是:
submit原本不会冒泡,所以应该直接侦听form;但实际上jQuery1.4之后已经支持submit事件的托管了,我的实验也支持这个结果。至于导致问题的原因,我还没想明白也没测出来,留着以后再做吧。最后用Hack的方式暂时解决:
if ($.browser.msie && isIEFirstSubmit) { isIEFirstSubmit = false; setTimeout(function () { form.submit(); }, 50); }有了解这个的高人还请不吝赐教。有感兴趣的同学可以去试试:http://www.dianjoy.com/dev/#/user/updateuser
