阅读更多

4顶
0踩

互联网

11月的一个深夜,我飞临我的故乡亚利桑那 Tucson 的上空,我为这个城市网格式的布局所打动,Tucson 是美国通过规划而建造的城市之一,从上空看,这个城市的所有东西都被设计者精心布局(图1),我刚从伦敦回来,伦敦正好相反,伦敦的城市布局(图2)曲里拐弯,看上去更像是出之天然。

Tucson

图 1:亚利桑那的 Tucson

London

图 2:伦敦

我构想这篇文章已久,这两个城市的俯瞰图让我联想到 Web 设计,当今的技术可以让我们自由实现网格式设计,或者完全跳出网格之外,这种选择对 Web 设计师的推动是毫无疑问的,然而真正的挑战是,我们该如何放弃那些闭塞的思想而跳出网格之外思考。

城市的感觉

将城市规划推之 Web 设计,二者之间的相似之处很有趣。网格布局非常适合创建可预见的,易于导航的网站,网格可以很好地帮助设计师进行规划,让用户易于访问(图3)。

Grids and Grid Design(s)

图 3: Ryan Brill

从正面意义上看,Tucson 这个城市当然很容易访问,一点方向感或一张街道图就足够了,居民向别人指示自己的方位,只需说,我在 Campbell Avenue 和 Prince Road 交叉路口的西南拐角处就可以了。公共交通都是正南正北或正东正西,辨路是很容易的。

而从另一方面说,Tucson 的设计者最初的规划只考虑到有限的扩张,当城市发展到规划之外的地方,问题就出现了。Tucson 网格化的局限阻止了不同风格社区或邻里的出现,很多 Tucson 的居民觉得这个城市缺乏一个充满活力的市中心或众多有个性的社区,结果,即使这样的区域出现了,也容易前往,他们也懒得去找。

伦敦却不同,它简直是个迷。我知道伦敦人自己也要靠城市指南才可出行。这个城市的交通系统充满挑战,那些出租车司机需要通过专门的考试才能上岗。这个城市的自然成长并没有让它成为一个容易出行的地方。

然而在伦敦,精彩纷呈的城区与口味独特的邻里到处都是,文化聚集区以及奇趣社区也不一而足。虽然更难出行,因为口味纷呈,人们反而更乐意置身其中。

这个隐喻也适合那些趋向自然的 Web 设计,人们如何才能轻松地在那些曲里拐弯的胡同中穿梭?从另一个方面说,漂亮的设计可以通过打破我们所一直遵从的条条框框而得以实现。图4中你可以看到,突破网格设计的规矩如何让设计既保持易用性,又看上去与众不同。

网格代码的迷思

作为一个更多注重代码而不是设计的人,我很迷惑地发现我们的设计是如何拘泥于代码,我相信是长期的表格布局让我们画地为牢(图5),联想到最新的 CSS 布局,很容易知道这是为什么。

Table Grid

图 5: k10k

表格布局很适合网格设计。表格的代码本身就是重现一个网格,我们只是在单元格中填入图片,文字,界面元素来完成我们的设计(图6)。如果我们想实现复杂的非结构化设计,就需要在文档中运用大量图片,导致整个文档的臃肿。

Boxes creating a grid
Grid boxes creating a grid

图 6: Weightshift

表格布局有一些优势,然而跟城市规划一样,优势有时候也可以变成劣势。基于表格的网格保证它里面的所有单元格规规矩矩,要想让所有的列拥有同样的宽度?太简单了,表格的天性如此。让单元格之间保持一致的间隙?也是小菜一碟。然而,如果你不想要这种整齐划一的结构怎么办?很不幸,你做不到。

CSS 改变了这一切,这是我认为我们还未学会为 Web 而设计的理论依据。我们,尤其是那些从长期的表格布局转到 CSS 的人,刚刚开始明白 CSS 的视觉模型对打破网格设计的陈规多么有帮助。CSS 布局完美吗?并不,在 CSS 带来的好处之外我们还失去了一些东西。整列扩展对 CSS 设计来说是很大的问题,单元格的间隙问题也是。

CSS 无非是边线与盒子,网格中也有,然而二者的本质区别是,CSS 允许我们将一个盒子从其周围的环境中独立出来任意处置(图7)。

The Box Model

图 7

我们可以使用 position 或 float 属性定位,我们可以用轻量级图片充当背景,因此使用 Box 的时候我们既可实现网格布局,也可以更有效的实现非网格布局,你可以在 Dave Shea 的 Blood Lust 中看到这个例子,这是他在 CSS Zen Garden 中使用的众多设计之一(图8)。

图9展示了 Blood Lust 中运用的基于 BOX 的非结构化设计,也展示了如何使用 CSS 和 BOX 实现相互独立的非结构化网格。

Grid boxes used for a deconstructed grid

图 9

一旦我们明白了 BOX 的能力,我们就可以很容易突破网格的束缚。图10中展示了一种高度非结构化,甚至是自由的设计。

这些 BOX 使用 CSS 定位:

Grid boxes for spontaneous, non-grid design

图 11

不仅代码变得更干净,对熟悉 CSS 布局的设计者而言也更直观简单。而这种设计也同样直观易用且不落俗套。

展望

现代布局技术之美是我们有更多选项可选。使用 CSS 我们可以创建易于管理,轻量,视觉丰富的设计,如果乐意,也可以是网格设计,同时,我们也可以很容易地打破或解除这个网格。

这为当代 Web 设计带来更多机会,我们不应因为对网格设计更熟悉而重蹈覆辙。

对于我们这些长期耽于表格布局的人来说,面临的困难尤其大。对多年的 Web 设计者,这意味着同一直使用的东西决裂,有些人也许并不觉得难,然而绝大多数人会心存畏惧。我们需要学习 CSS 模型的工作原理,还要勇于同陈规告别。

有一些新人,他们从未从事过表格布局设计,对他们来说,我们过去的方法既奇怪又死板,正是从这些人中,我们有希望看到更多对设计陈规的突破。

Web 正在走向成熟,我们设计方式也在改变,我们的面前有更多的创新与创意。我们不会拘泥于被规划的城市,我们可以实现独特的设计,我们这些老设计师,联合当今的新人会让 Web 日新月异。

相关阅读

作者感谢 Mark Boulton 的 grid-system 系列文章,并感谢 Timothy Samara 2002 年出版的 Making and Breaking the Grid。

本文作者

Molly E. Holzschlag

Molly E. Holzschlag 是一个知名的 Web 标准倡导者与传授者。她的30多本著作中最畅销的是她同 Dave Shea 合写的 The Zen of CSS Design (禅意的 Web 设计)。Molly 是 W3C 工作组受邀专家,也是 Web 标准项目组(WaSP)的前主管。Molly 同设计者,开发者,执行者与决策者们一起,为实用的,漂亮的,有意义的 Web 提供推动力。

译后记

这是一篇发表于 A LIST APART 的 2005 年的文章,2005年,CSS 布局还不像现在这样普遍,而表格布局已经让很多人不堪其重,作为 Web 领域资深的专家,作者 Molly E. Holzschlag 也是表格布局的长期使用者,当 CSS 接近成熟,基于 CSS 的布局让人耳目一新的时候,她对基于表格的网格设计的心情是复杂的,从文章中可以看出。

然而时间到了2009年,当 CSS 已经无孔不入,CSS 布局也变得烂熟的时候,我们很有必要再次对网格设计进行思考,网格死了吗,或者说表格是邪恶的吗?答案并不那么简单,当今的 Web,无论怎样变化,它的宗旨是永恒的,除了 Web 应用,Web 永远不变的使命是表达和传递信息,如果你是一个文人,你会爱上伦敦,然而如果你是个邮递员,你会选择 Tucson。因此不管是网格设计还是自然设计,并没有绝对的优劣,网格设计更清晰整洁,自然设计更优雅精炼。

而表格,也并不象很多人说的那么邪恶,须知,现在的表格已不是昔日的表格,BOX 可以结合 CSS,表格也可以,完全使用 CSS 进行修饰的表格就像一组有机组合并互动的 BOX,当你并不需要其中的单元格精确定位的时候,表格是一种比 BOX 更完美的容器,因为它对所有浏览器的兼容是最好的,它不会坍塌,不会长短不一,它的行为更容易符合预期,最重要的是,它是人们对事物进行组织的一种最直接的方式。


中文翻译来源:COMSHARP CMS 官方网站,译者35公里。

来自: comsharp
4
0
评论 共 2 条 请登录后发表评论
2 楼 hflhhb 2009-07-09 11:52
很好,很有启发
1 楼 ageless 2009-03-31 12:54
不错的文章

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • C++STL迭代器(iterator)

    尽管不同容器对应不同类型的迭代器,但这些迭代器有着较为统一的定义方式,具体分为4种。迭代器的4种定义方式迭代器定义方式具体格式正向迭代器容器类名 :: iterator 迭代器名;常量正向迭代器容器类名 :: const_iterator 迭代器名;反向迭代器容器类名 :: reverse_iterator 迭代器名;常量反向迭代器容器类名 :: const_reverse_iterator 迭代器名;通过定义以上几种迭代器,就可以读取它指向的元素,*(迭代器名)

  • 保卫C++:安全STL编程中的受检迭代子

      保卫C++:安全STL编程中的受检迭代子            C++语言、STL、标准C++库,相比之C语言及C运行时库(CRT)而言,更加现代、也更加健壮。正因为软件的安全性与健壮性息息相关,所以在安全性方面,标准C++比C及CRT面临的问题更少,那也就不足为奇了。然而,在标准C++中,仍存在一些漏洞,而且,Visual C++ 2005中的一项新增功能,使这个所谓的“

  • 【C++】:STL迭代器使用详解,很好很详细

    写在前面,迭代器这种东西,就是为了使访问简单!! 容器::iterator iter; for(iter= 容器.begin();iter!=容易.end();iter++){ coutfirst等等之类的                                    //迭代器就是这么个套路 } 然后就是set,set就是一个集合,仅此而已,而其他的,像是map比较有意

  • c++ STL容器在循环中删除迭代器的处理细节

    c++中STL容器vector/list/map/set/deque/string等删除元素的问题,迭代器容易出现以下错误,示例代码如下:std::vector<int> arrayList; ... std::vector<int>::iterator it = arrayList.begin(); for ( ; it != arrayList.end(); it++)...

  • STL里面的五种迭代器

    根据STL中的分类,iterator包括: 输入迭代器(Input Iterator):通过对输入迭代器解除引用,它将引用对象,而对象可能位于集合中。最严格的输入迭代只能以只读方式访问对象。例如:istream。  输出迭代器(Output Iterator):该类迭代器和Input Iterator极其相似,也只能单步向前迭代元素,不同的是该类迭代器对元素只有写的权力。例如:ostr

  • c++编码规范(一)

    1 通用原则 7 原则1.1:对外部输入进行校验 7 原则1.2:禁止在日志中保存口令、密钥 8 原则1.3:及时清除存储在可复用资源中的敏感信息 8 原则1.4:正确使用经过验证的安全的标准加密算法 8 原则1.5:遵循最小权限原则 9 原则1.6:删除或修改没有效果的代码 9 原则1.7:删除或修改没有使用到的变量或值 9 2 字符串操作安全 10 规则2.1:确保有足够的空

  • STL迭代器简介

    STL迭代器简介 STL将容器(Containers)和算法(Algorithms)分隔开,两者之间的纽带就在于迭代器(Iterators)。 迭代器也是一种智能指针,重载了例如常见的operator*以及operator->。 迭代器有常见的五种相应型别: iterator_category value_type difference_type pointer reference ...

  • C++迭代器(STL迭代器)iterator详解

    转自http://c.biancheng.net/view/338.html。侵删。 要访问顺序容器和关联容器中的元素,需要通过“迭代器(iterator)”进行。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。 迭代器按照定义方式分成以下四种。 1) 正向迭代器,定义方法如下: 容器类名...

  • C++编码规范

    1 通用原则 7 原则1.1:对外部输入进行校验 7 原则1.2:禁止在日志中保存口令、密钥 8 原则1.3:及时清除存储在可复用资源中的敏感信息 8 原则1.4:正确使用经过验证的安全的标准加密算法 8 原则1.5:遵循最小权限原则 9 原则1.6:删除或修改没有效果的代码 9 原则1.7:删除或修改没有使用到的变量或值 9 2 字符串操作安全 10 规则2.1:确保有足够的空间存储字符串的字符数据和’\0’结束符 10 规则2.2:字符串操作过程中确保字符串有’\0’结束符 11 规则2.3:把数据复制

  • STL迭代器

    迭代器是一个"可遍历STL容器内部分或全部元素"的对象 迭代器指出容器中的一个特定位置 迭代器就如同一个指针 迭代器提供对一个容器中的对象的访问方法,并且可以定义容器中对象的范围 迭代器就像一个指针......

  • c++编码规范(四)

    7 文件输入/输出安全 规则7.1:必须使用int类型来接收字符输入/输出函数的返回值 说明:字符输入/输出函数fgetc()、getc()和getchar()都从一个流读取一个字符,并把它以int值的形式返回。如果这个流到达了文件尾或者发生读取错误,函数返回EOF。fputc()、putc()、putchar()和ungetc()也返回一个字符或EOF。 如果这些I/O函数的返回值需要与

  • C++中STL各个迭代器详解

    1、自C++11起可以用range-based for循环来所有元素,但有时并不需要处理所有元素,此时可以使用迭代器。 std::vector<int> vec {1,2,3,4,5,6,7,8,9,10}; for (auto n : vec){ std::cout << n << endl; } 2、迭代器中用来表现容器中的某个位置 oper...

  • C++中STL为什么要使用迭代器?

    原因: 1、通过迭代器访问容器,可以避免许多错误,同时还能隐藏容器的具体实现。 2、迭代器可以保证对所有容器的基本遍历方式,都是一样的,实现算法时若需要遍历,则使用迭代器,则可以不用关注容器的具体类型,实现数据结构和算法的分离。 3、迭代器本身有很多优点,可以弥补C++语言的不足,比如它的iterator_category,可以得到迭代器所指向的类别,这样可以根据不同的类别的特性,提供不同的...

  • STL容器的遍历插入或删除(迭代器失效问题的统一解决)

    STL容器根据迭代器的失效问题,其实可以分为两类容器: (1)数组型容器的插入删除操作:vector、string、deque(均为顺序存储)         由于这类容器的插入或删除都会使所有迭代器失效,因此每次插入删除后都需要重新定位 (2)结点型数据容器的插入删除操作:list(使用链表存储)、map(使用红黑树存储)、set(使用红黑树存储)         由于这类容器删除时只会

  • 【STL】——迭代器

    1、迭代器之按照定义划分 2、迭代器之按常性划分 3、迭代器之按功能划分 3.1反转型(反向型)迭代器 3.1插入型迭代器 3.2流式迭代器

  • C++中STL用法总结

    1.1 什么是STL? STL(Standard Template Library),即标准模板库,是一个具有工业强度的,高效的C++程序库。它被容纳于C++标准程序库(C++ Standard Library)中,是ANSI/ISO C++标准中最新的也是极具革命性的一部分。该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法。为广大C++程序员们提供了一个可扩展的应用框架,高度体现

  • STL 模板库中迭代器 iterator 失效问题

    在做线上测试是涉及到vector 的相关迭代器操作,引出迭代器失效问题,这里mark一下。 如下程序是运行不起来的: #include using namespace std; #include int main(int argc,char *argv[]) { vector vs_int; vs_int.push_back(0); vector:: iterator iter = vs

  • STL程序设计实践五:巢状式的型别宣告

      STL程序设计实践五:巢状式的型别宣告Email – ccplusplus@21cn.com前言       STL是泛型程式设计的一个研究成果。在泛型程式设计中巢状式的型别宣告是其的惯用手法,它利用了typedef关健字。”STL程序设计实践四”中我们对该关健字的用途做了些简单介绍。这里说一下利用typedef关健字在泛型程式设计中进行巢状式的型别宣告。也算是对”STL程

Global site tag (gtag.js) - Google Analytics