QCon 演讲火热征集中,快来分享你的技术实践与洞见! 了解详情
写点什么

充满 Trick 的 CSS,两难的选择

  • 2007-09-06
  • 本文字数:2837 字

    阅读完需:约 9 分钟

javaeye 的 hax 最近在他的 blog 上进行了一场关于如何写 css 的讨论,其中反思和讨论了一些关于基于标准或 trick 进行设计的选择问题,这个问题也是 David Heinemeier Hansson 对于 XHTML/CSS/Javascript 标准进行 RIA 开发话题的一个延展。我们可以从中思考如何在不完美的技术中选择一条相对完美的技术路线?

讨论的起因是淘宝网的 UED 团队成员段王爷在他的 blog 上发表了一篇关于淘宝网页面设计上的小技巧(Trick)的介绍,这个技巧是为了让一些条目之间的分隔线完全使用 css 生成,不使用多余的 class,段王爷还对比了其它三种常见实现方法。实现方法如下:

从很久很久以前开始,类目间的横线无非都只有三种。
1、背景图
在 a 标签设置一个 padding 用宽 1px 高不等的背景图来 position 到右侧。
缺点:最后一个还是要用 class 来隐藏掉背景。
2、符号
在每个 a 标签之间用“|”符号来填充。
缺点:html 文件变大,文件维护变得很麻烦,而且在 html 中毫无意义。
3、a 标签右侧的 boder。
同背景图一样,只不过使用 border-right 来代替。缺点也同上。 其实现有(淘宝的实现方式)是利用 ul 的 overflow:hidden 再将 li 的 margin-left:-1px 的做法做出来的。这样的做法就可以同时避免以上的缺点了。

上面提到的使用 border 的传统方式需要在第一或者最后一个元素上面添加 class 来隐藏 border,Realazy 也在他的 blog 中给出了一种不错的解决方案,他推荐这样做:

导航项目间的竖线,我们往往通过 border 或者 background 来实现。特殊需求是,第一项左边无竖线或最后一项右边无竖线。按照一般的编程方法,控制第一项要比控制最后一项容易得多。区分第一项的还有一个好处是,CSS 有一个:first-child 的伪元素(pseudo element)可以让我们轻而易举的选择第一个子元素。遗憾的是,当前全球占有率最高的浏览器,IE6,并不支持这个伪元素。我们可以手工给第一个元素加上 class 然后再定义它。等 ie6 淘汰之时,就可以放心用 :first-child 了,相权衡的话,我觉得给第一项加上 class="first"也不失为实用主义做法。

Realazy 提出的方案的思路是使用基于标准的 css 选择器(selector),这种方法的好处是可以实现完美的内容与表现分离。但是现实的问题是并非所有的浏览器都基于标准实现,这也正是基于标准的 RIA 开发面对的最大问题,尤其以 CSS 和 Javascript 问题最大。javaeye 的 hax 在他的 blog 中提出了自己对于这个 Trick 的不同意见:

因为我觉得这个方法一点也不好。很简单的一个理由:这只是一个 trick,只适合这特殊情况,假设你要换用“-”来分割呢?作为插入分割符号来说,真正合理使用 css 的,我给一个例子:
li ~ li:before { content:’-’; margin:0.25em; } 优点:含义非常清晰,维护性极高。你可以换任何的分隔字符,可以设定字体,可以设定颜色、大小等样式,甚至可以换用图片作为分隔。

好了,下面说缺点。唯一的缺点:IE 不支持。

hax 给出的方案在 IE 中无法使用,其实对于大部分网站来说这就相当于绝大多数用户都无法看到这种表现,这就意味着失败。淘宝 UED 的小马提出“实用第一”,从这种观点上说 hax 的方案就是不实用的。但是 hax 提出可以使用 Dean Edwards 的 IE7 Javascript 库

IE7 是一个可以让 IE 像标准浏览器一样工作的 Javascript 库。它修正了很多 CSS 问题,让 PNG 在 IE5 和 IE6 下正常工作。

IE7 这个库动态的实现了很多 IE 原本不支持的伪类(Pseudo Classes),让完全基于标准的 css 选择器(使用伪类)成为可能。随后,hax 在他的另外一篇 blog“面向未来的 CSS 实践”中作了如下设想:

我推崇一种面向未来的 CSS 实践。即大胆采用 CSS2.1 甚至部分 CSS3 的特性。因为绝大多数特性,Firefox、Opera、 Safari 等都已经很好的支持了。MSIE7 也改进了许多,将来 IE 也无疑终究会完全支持 CSS2.1。对于目前的 IE,除了 graceful degradation 的方式(实际上整个内容样式分离的原则和良好的 CSS 设计可以确保这点,比如淘宝以前的“裸体”所体现的),可以考虑通过特定手段来 patch 之。在这点上,我必须说,我原来也是一直坚持只用 ie6 的 selector 的。是什么改变了我?就是 Dean Edwards 的 IE7!它的出现不仅在于实践价值——即提供了一个对于 IE 的补丁,让开发者可以直接写 CSS2 甚至 CSS3。

hax 提出的这种方式是比较激进的,他还在“面向未来的 CSS 实践”中进一步的描述了通过脚本修正的方式解决 IE 不支持标准伪类和多 class 问题的设想,他的核心想法就是让 CSS 的开发可以遵循标准,减少为了优雅退化(graceful degradation)而向最低支持(浏览器)兼容造成的表达方式限制。但是 hax 自己也提出了这种思路面临的尴尬,它举了 table 布局的实用性价值为例:

我认为出现这样讽刺的情况,即遵循标准的人活得比不遵循的人更累,是很有问题的。这种矛盾在我身上存在着,2001 年的时候我在某 bbs 上发了个贴,大数 table 布局之罪,但是过了几天我又跑上去说 table 布局在某种情况下也可以用用。 dlee 同志貌似到现在也跟我当时一样。如果你确实认为,table 布局从实用主义角度无法被完全否定,那 DHH 同志采用实用主义的角度来力挺 html/css/js 就也有点心虚,那个标题也就显得带点任性味道……

“遵循标准的人活得比不遵循的人更累”这句话说出了很多坚持基于标准进行 CSS 设计的开发人员的心声,这其实是实用性和坚持标准之间的一些交换,现实世界中两个方面如何平衡正是广大 XHTML/CSS/Javascript 开发者需要认真思考的,关键的问题,还是目的要明确。盲目的遵循标准,例如很多开发者着迷于使用 div 布局代替 table,但是却没有明确的目标就会迷失,hax 这样评价:

从实用主义角度说,谨慎的 table 布局也许更简单,因为它更好的映射到了 grid 模型上。如果你转用 div/span,标签是清晰了,但是 css 是混乱的!这些属性(css 属性)是分散的,css 代码无法反映整体,无法记录你的 grid 布局意图!这是为什么我们经常说我有一个 css trick 的原因,它是 trick 而已,是你达到最终目的的手段,但是你的目的,你的意图,没有好好加入文档的话,那维护起来恐怕也不见得轻松。 table 布局 其他 css 样式 = 清晰的布局意图和内容的混合体

div 容器 css 样式 = 内容样式分离,但是从 css 代码中很难看出布局意图

关于 div/css 布局还有一些误区,简单的把 table 标签换成 div 是没有意义的(若干层级的 div 可能比 table 更糟糕)。实际上我们希望的是语义标签。

我们应该看到,CSS 的意图是将表现分离。从设计的角度就是实现语义化的 html 结构,让 html/xhtml 尽量只表达纯粹的数据结构。但是此时 css 里面的布局意图是比较难以被记录的(难以被理解就难以维护,难以重构),有其在充斥了大量 Trick 的情况下,这正是广大程序员 / 设计人员需要解决的,我们是否应该通过不断地重构来找到这个矛盾的平衡点呢?欢迎大家讨论。最后附上淘宝 UED 团队的小马总结的淘宝 CSS 编程原则:

  1. 尽量不使用 hack
  2. 尽量不使用 ie6 不支持的选择符

能符合这两个条件的最简洁的写法,就是我们的目标。

2007-09-06 09:341105

评论

发布
暂无评论
发现更多内容

阿里巴巴架构师十年整理出的JavaSpringBoot核心文档,真是太全了

Java 架构 面试 程序人生 编程语言

如何做一场有趣又高效的迭代回顾会议?

万事ONES

Scrum 敏捷 回顾会

行云创新:云原生技术助力企业数字化转型

行云创新

技术 云原生 转型 数字化 平台

如何让文件共享 SDK 支持使用 Uri 上传文件

ZEGO即构

文件存储 分区存储 文件共享

东软熙康、百度、京东方,互联网医院的三个典型样本

海比研究院

快手、知乎等平台严厉打击“病媛”炒作行为:自媒体行业不能被流量裹挟

石头IT视角

拥抱开源,共建生态 - 开源生态与效能提升专场 | CIF 精彩看点

CODING DevOps

DevOps 研发效能 腾讯云 CIF 峰会 开源生态

重磅来袭,虚拟化技术分类

hanaper

华为云带你探秘Xtrabackup备份原理和常见问题分析

华为云数据库小助手

GaussDB 华为云数据库 MySQL 数据库 GaussDB(for MySQL)

掘金热榜第一!阿里P8用近十个月整理出来999页Java岗核心笔记限时开源!

Java 架构 面试 程序人生 编程语言

史上最全Java高频面试合集,命中率高达95%

Java 程序员 架构 面试 后端

搞不懂云原生

二哥不再迷茫

金九银十不要怕!有了腾讯这本2021年最新Java面试手册,offer手到擒来!

Java 程序员 架构 面试 后端

互斥锁、自旋锁、读写锁...理清它们的区别和应用

行云创新

云计算 编程 开发 应用

不得不聊一聊英语爱好者的单词杂货铺了

小匚

随笔杂谈 生活记录 英语 大学英语四六级 单词

图谱相关技术在风控反作弊中的应用和探索

百度Geek说

后端 软件架构

四面字节跳动(高级开发岗):分布式+中间件+TCP+JVM+Hashmap

Java 编程 架构 面试 计算机

从工具、工具箱到数字化软件工厂——DevOps 设计理念与工程实践专场 | CIF 精彩看点

CODING DevOps

DevOps 数字化 研发工具 腾讯云 CIF 峰会

浪潮云洲荣获两项工业自动化及数字化行业年度大奖 inspur浪潮云 昨天

云计算

智能网联汽车行业信息安全现状与威胁

SOA开发者

目睹阿里技术官写的Tomcat架构笔记后,瞬间觉得自己是渣渣

Java 架构 面试 程序人生 编程语言

艾瑞发布《2021年中国企业级 SaaS 行业研究报告》,ONES 入选典型厂商案例

万事ONES

项目管理 SaaS 协同办公

智能大数据专场,百度智能云带来智能大数据产品架构全景图

百度大脑

人工智能 大数据

AlibabaP9力荐!最新出品1297页JDK源码+并发核心原理解析小册

Java 架构 面试 程序人生 编程语言

超十年渗透专家总结出636页渗透测试全笔记,100课时一次讲清

Java 架构 面试 程序人生 编程语言

手把手教你使用Studio Lite + Digtal car!助力智能汽车场景、轻应用开发更轻松!

SOA开发者

使用 grpcurl 通过命令行访问 gRPC 服务

AlwaysBeta

golang gRPC

【新品尝鲜】OCR磅单识别上线邀测,为货运物流提速增效

百度大脑

人工智能 OCR

音视频终端引擎优化实践

百度开发者中心

最佳实践 音视频 实践案例 智能视频 行业深度

用Python绘制专业的K线图【含源代码】

恒生LIGHT云社区

提高工作效率的三种方法

石云升

团队管理 管理 引航计划 内容合集 9月日更

充满Trick的CSS,两难的选择_Java_田乐_InfoQ精选文章