今天又有个小女孩在写 iconfont 的时候直接使用了属性选择器来选择 class 属性(所有 iconfont 都是 .icon-* 的形式,使用 [class^="icon-"] 来为所有 iconfont 统一指定 font-family)。其实我当年也用过类似的黑魔法,后来差点掉进自己搞出来的坑就再也不这么玩了。
IE8 开始就支持了属性选择器,而且属性选择器不仅仅可以判断相等,还可以判断包含、头包含、尾包含,这些较高级的比较方式。于是,我们这么写也能正常工作:运行<meta charset="utf-8" /> <style> [class^="red"] { color: red; } </style> <div class="red">虽然我是红色的</div> <div class="x red">但我不是红色的</div> 这个代码使用「头包含」来匹配,所以直接「class="red"」可以匹配到,而后面以非「red」开头的就无法匹配到。当然,如果使用「包含」就可以解决眼下的问题,但又会带来新的问题:运行<meta charset="utf-8" /> <style> [class*="green"] { color: green; } </style> <div class="green">直接写绿色当然没问题</div> <div class="yellow green">即使不写在前面也没问题</div> <div class="yellowgreen">但是它还匹配了「黄绿色」中的「绿」</div> 实际上「yellowgreen」表示「黄绿色」,「green」不该匹配这个。如果同时使用包含和头包含确实可以解决大部分问题,但还是比较麻烦,因为有各种特殊情况:运行<meta charset="utf-8" /> <style> [class^="a-"],[class*=" a-"] { color: red; } </style> <div class="a-x">满足头包含</div> <div class="x a-y">满足包含</div> <div class="x a-y">又不满足了 = =。。</div> 虽然最终都可以解决,但是各种奇葩的情况如果考虑下来的话这么做会麻烦死。而且一般人根本不会考虑这么多,只为了解决眼下的问题就可能给未来埋下了一颗地雷,随时都有踩到的危险。不过后来这个小女孩解释说这段代码是某个 iconfont 生成工具生成出来的我才释怀。她们具体使用什么 iconfont 生成工具我不知道。不过对生成得到的代码还是得留个神,这样的问题能避免就尽量吧。 |