连接
◆《重构之美》总目录
上一篇:重构之美-走在Web标准化设计的路上[对HTML/XHTML/XML/XSL的一些认识]
下一篇:重构之美-走在Web标准化设计的路上[深入结构:div再议以及对span的迷惑。]
特意上网搜索了一下,关于div,说法很多。
把div看成是布局元素这种观点我想是最多的,类似有“用div代替table进行布局”、“实战CSS+DIV布局”等等等等,太多了,还有不少人延用Dreamweaver的定义,称div为层,按Photoshop的层的概念来使用……有朋友干脆就直接称div和span为辅助布局元素。
怎么说呢?虽然我很想说对div类似的这种认识是错误的,div不是一个布局元素,没有一个tag是用来布局的,但是我是对的吗?我也不知道。几乎所有人对div的宣传都是布局,不管是‘民间’的还是‘官方’的,但是如果我们找根源,中文中,div是一个结构化标签,是一个块级元素。好吧,我们首先看看div拥有的语义,division(分隔),按语义它的作用是将两个部分分隔开来。然后我们再回到w3去看看怎么定义div和span的:The DIV and SPAN elements, in conjunction with the id and class attributes, offer a generic mechanism for adding structure to documents. These elements define content to be inline (SPAN) or block-level (DIV) but impose no other presentational idioms on the content.
注意到我上面加粗的一句话了吗?W3可没说是 for layout,而是for structure,是结构!因为分隔从而产生(定义)一个代码结构。我想,结构和布局应该是两个概念吧。或许,因为table确实被用于布局了,所以这种根深蒂固的布局思路又自然而然的转嫁到div上,我曾在很长一段时间里也是这么理解的。但是,现在我要说,这绝对是一个错误并且,这是极度严重的错误!!!这纯粹个人观点个人理解,自己取舍好了。
为什么严重?理解的错误直接导致的就是使用的错误。因为如果按照这个思路,把div作为布局元素使用,那么我认为:
你永远无法固定xhtml!永远陷在css的怪圈中!永远不会去思考和理解结构!永远擦不干净table烙下的痕迹!永远无法接近神(貌合神离的神哈,呵呵)……
或许把div称为布局元素还是为了更好的推行标准,但是却将人们从一个错误带向了另一个错误。两年前我刚接触标准时就在《重构之美》首篇中迷惑过关于改版的事情,虽然随着理解的深入好像有了突破,在我写下xhtml后不变动,然后通过css的技巧来完成新版面。比如像著名的csszengarden。但是很快我又有新的迷惑,一个人这样做好像没什么问题,团队呢?比如如果同样的内容,设计成两个版式,然后交给不同的两个人来写xhtml,会一样吗?就像如果把csszengarden的形式颠倒一下,基于同一份数据先做好100个设计稿,让100个人按照这个设计稿写100份xhtml,会一样吗?我想按照div布局模式,对于同样的版式,不同人不同的页面分析都会产生不同的xhtml,更何况不同的版式呢?但是既然表现与结构无关,那么同样的内容不应该有2份以上的xhtml。不要小看这个问题,对于团队中前后台的有效分离与快速协同,这是关键!我在培训中提出一个观点:最理想的境界是前台闭着眼睛都能知道后台输出的是什么样的xhtml结构代码。那么问题出在哪里?div布局!尤其是在理解了h系列标签不合理之后,体会更深刻。
上篇文章我提出的关于结构应当分为两种:语义结构和代码结构。理解了这两个结构之后,那么div的用处就比较明朗了,稍稍动动脑筋就能想到,用于组织代码结构。所以hx标签的问题我认为经典呢,不要说html了,即便对于xhtml,大部分的人关心的仍是如何表现,小部分人关心语义结构,很少人去关心代码结构,似乎xml有了,xhtml就不需要代码结构了。但是从hx系列的问题可以看出并延伸知道W3可一直在关心代码结构,从1.0,1.1直到2.0,一直希望xhtml拥有xml般严谨的代码结构。说到这里再多看xhtml 2.0的另一个变化,br不再被推荐,应该很好理解了,br的语义是产生一个截断(break),但实际作用是产生一个行,语义结构上仍不完美,所以使用line进行替代<line>this is one line</line>。同样br也无代码结构可言,如果我想提取第三行的数据如何操作?所以很有可能类似br、hr这类标签都将被废弃。我琢磨着,xhtml1.x是W3清理表现,将人们往语义结构[Semantic]的方向牵引,而xhtml 2.0则是展示和突出代码结构[structure]。呵呵,您说我琢磨得对吗?瞎猜瞎猜。^_^
回过头来,那么怎么组织?首先对于一个设计稿,一定要不被设计所迷惑和左右,只提取看得见和看不见的数据,然后就扔掉设计稿,先完成数据的语义结构,再添加代码结构(adding structure to documents.),完成xhtml后,最后一步才是重新拾起设计稿打开css,还原。当然实际做的时候不可能不看设计稿,但是怎么看?只提数据!再说一点,数据在文档中的先后顺序由什么定?当然是由文档而定,不是由设计稿所定。举个例子,假如有两个栏目,新闻头条和普通新闻。谁在前谁在后,很显然在文档中应该是头条在前普通在后,这是由UE(用户体验)和栏目轻重的综合考虑决定。但是按照div布局的话,是按照设计稿上前下后左前右后的顺序来决定的,那么如果设计稿中将普通新闻栏目设计在左栏,头条设计在中栏,文档中普通新闻就跑到头条新闻上面去了。所以我打开一个Web标准站点文档浏览,如果文档的先后顺序是按照页面布局上前下后,左前右后的顺序而定的,那么我……特例一点,如果一个单屏设计的网站,标题和导航设计在页面下方,那你的文档岂不是最下面才是标题和导航,这是什么UE?这不是扯蛋嘛。div,div布局的恶果——文档结构仍然在为表现所左右!貌合神离!!
代码结构怎么做?大处按照上篇文章所写,用h系列划分大结构。那么小处呢?这里就要牵涉进div的另外一个概念:块级元素。什么块?模块!用div模块化小处。举例:
<
div
>
<
h3
><
span
>
用户登陆
</
span
></
h3
>
<
div
>
<
label
for
="name"
>
用户名
</
label
>
<
input
id
="name"
/>
</
div
>
<
div
>
<
label
for
="pw"
>
密码
</
label
>
<
input
id
="pw"
/>
</
div
>
<
p
><
button
/></
p
>
</
div
>
这个在[复杂表单]中提到过的例子,我们来详细分析div在小处如何模块化运用。其实很简单,h3/lable/p是语义结构,然后,对于用户名和相应的输入框显然是不可分割的整体,那么好了,div将其标识为一个块,对应的密码部分同理。最后,两者一起与标题和按钮又构成一个不可分割的登陆整体,div之。这样拥有很好的语义结构和代码结构。好的代码结构不仅仅可以便于固定xhtml,便于程序操作节点,还对css提供了很高的自由度。如上例结构,我只需要给最外div一个class,比如"loginarea"。那么:
我可以这么按节点/路径层层定义下去:.loginarea label{} .loginarea input{} .loginarea div label{} .loginarea div input。如果我需要横向登陆,只需要定义一个关键点:.loginarea div{float: left},如果纵向则去掉这个关键点,模块化的登陆就这么简单。这样还可以省写不少class,尤其对于有些看似复杂的结构其实模块化设计好了,模块内部是简单的,一个路径定义过去,根本无需class还不会引起样式冲突和干扰,css的可读性也很好。当然这里会涉及到css的技巧,我认为css的技巧最重要的就是分析页面,页面分析的好,写出来的css简单明了充分利用tag还有多以备扩展,否则class一大堆复杂冗长还会觉得tag不够用又去添加破坏结构。复杂表单那套系统的css我写了48k,还未做最后优化,全部图片总共只有5K,还全是无损PNG格式。整套系统几十个大模块,又有无限级菜单、树、页签、弹出,复杂表单,合同,frame,iframe,报表,控件套控件等等乱七八糟什么都有,css加图片全部表现部分可以做到50K以内。这个项目四个程序员一起开发我一个人顶所有前台,三个月时间,程序员不管任何有关表现部分,我都是玩玩做做就搞定了。中后期,临着交付客户时候我还觉得公司提供的设计不好,又自己花1天重新设计,花不到2天另外写了一个css,整个系统全变了且以前的设计未丢失。功能不变的情况下界面大换,再大的系统也不过一个人几天时间,且程序员不用管。这就是Web标准的威力之一!(因为是内网应用,所以我几乎没考虑和照顾浏览器兼容性,没必要,也是快的一个因素)
所以我认为当前各大网站上以各种方式事先列出什么单行一列,两行一列诸如此类的几行几列的div+css布局代码,不好说他们不对,你完全可以去理解是如何使用css实现几行几列的布局,然后合理运用到自己的结构上。但是如果你按照他提供的代码去套、去添加内容,那么你就错了。不过话说回来,在被一篇一篇标题着斗大的“布局”两个字的潜移默化下,您还有心思去关心结构吗?所以很多都去琢磨css了,所以这些善意的Web标准推广者还是有错的,包括我在内,我2004年撰写的《重构之美》代码示例部分带有更大的误导性(好在当初我一再强调代码毫无借鉴的意义,也算在文字上有所弥补)。现在呢?我也不知道,在路上,在路上……
写很多了,span的合理运用留给Update吧。
2006 3 24-25 Create
连接
◆《重构之美》总目录
上一篇:重构之美-走在Web标准化设计的路上[对HTML/XHTML/XML/XSL的一些认识]
下一篇:重构之美-走在Web标准化设计的路上[深入结构:div再议以及对span的迷惑。]
---------------------垃圾部分------------------
..
<
div
class
="personinfo"
>
<
h2
><
span
>
个人信息
</
span
></
h2
>
<
div
>
<
h3
><
span
>
购房人
</
span
></
h3
>
<
table
>
<
tr
>
<
td
><
span
>
选择
</
span
></
td
>
<
td
>
姓名
</
td
>
<
td
>
性别
</
td
>
<
td
>
年龄
</
td
>
<
td
>
关系
</
td
>
<
td
>
户籍所在地
</
td
>
</
tr
>
<
tr
>
<
td
><
input
type
="checkbox"
/></
td
>
<
td
><
select
/></
td
>
<
td
><
input
/></
td
>
<
td
><
input
/></
td
>
<
td
><
select
/></
td
>
<
td
><
input
/></
td
>
</
tr
>
</
table
>
</
div
>
<
div
>
<
h3
><
span
>
家庭成员
</
span
></
h3
>
<
table
>
<
tr
>
<
td
><
span
>
选择
</
span
></
td
>
<
td
>
姓名
</
td
>
<
td
>
性别
</
td
>
<
td
>
年龄
</
td
>
<
td
>
关系
</
td
>
<
td
>
户籍所在地
</
td
>
<
td
>
工作单位
</
td
>
<
td
>
编辑
</
td
>
<
td
>
删除
</
td
>
</
tr
>
<
tr
>
<
td
><
input
type
="checkbox"
/></
td
>
<
td
><
select
/></
td
>
<
td
><
input
/></
td
>
<
td
><
input
/></
td
>
<
td
><
input
/></
td
>
<
td
><
input
/></
td
>
<
td
><
input
/></
td
>
<
td
><
button
/></
td
>
<
td
><
button
/></
td
>
</
tr
>
</
table
>
<
p
>
<
button
/>
</
p
>
</
div
>
</
div
>
<
h1
>
大便蛔虫的表单标题
</
h1
>
<
div
>
<
h2
>
导航
</
h2
>
<
div
>
<
button
>
新增
</
button
>
<
button
>
刷新
</
button
>
</
div
>
<
div
>
<
h3
>
当前批次采用的标准为
</
h3
>
<
div
>
<
label
>
本人补贴
</
label
>
<
asp:label
id
=""
Runat
="server"
></
asp:label
>
</
div
>
<
div
>
<
label
>
本人工龄补贴
</
label
>
<
asp:label
id
=""
Runat
="server"
></
asp:label
>
</
div
>
<
div
>
<
label
>
配偶补贴
</
label
>
<
asp:label
id
=""
Runat
="server"
></
asp:label
>
</
div
>
<
div
>
<
label
>
配偶工龄补贴
</
label
>
<
asp:label
id
=""
Runat
="server"
></
asp:label
>
</
div
>
<
div
>
<
label
>
特殊补贴
</
label
>
<
asp:label
id
=""
Runat
="server"
></
asp:label
>
</
div
>
</
div
>
<
iewc:treeview
id
=""
ExpandLevel
="1"
runat
="server"
AutoPostBack
="True"
></
iewc:treeview
>
</
div
>
<
div
>
<
h2
>
表单内容
</
h2
>
<
div
>
<
h3
>
申请人信息
</
h3
>
<
div
>
<
label
>
本人姓名
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
身份证号码
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
本人工龄(年)
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
<
asp:regularexpressionvalidator
id
="REVY"
runat
="server"
Display
="Dynamic"
ValidationExpression
="\d{0,2}"
ErrorMessage
="必须输入整数"
ControlToValidate
="txt_WorkAge"
></
asp:regularexpressionvalidator
>
</
div
>
<
div
>
<
label
>
工作单位
</
label
>
<
asp:label
id
=""
Runat
="server"
></
asp:label
>
</
div
>
<
div
>
<
label
>
职务或职称
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
</
div
>
<
div
class
="personinfo"
>
<
h3
>
现住房信息
</
h3
>
<
div
>
<
label
>
现住房地址
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
建筑面积(平方米)
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
其中个人按市场价自购面积(平方米)
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
现住房性质
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
补贴住房面积标准(平方米)
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
申请住房补贴理由
</
label
>
<
asp:dropdownlist
id
=""
Runat
="server"
></
asp:dropdownlist
>
</
div
>
<
div
>
<
label
>
申请住房补贴标准
</
label
>
<
asp:radiobuttonlist
id
=""
runat
="server"
RepeatDirection
="Horizontal"
>
<
asp:ListItem
>
无房户一次性补贴
</
asp:ListItem
>
<
asp:ListItem
>
一次性补面积差
</
asp:ListItem
>
</
asp:radiobuttonlist
>
</
div
>
</
div
>
<
div
>
<
h3
>
配偶信息
</
h3
>
<
div
>
<
label
>
配偶姓名
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
配偶身份证号码
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
配偶工龄
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
年
<
asp:regularexpressionvalidator
id
=""
runat
="server"
Display
="Dynamic"
ValidationExpression
="\d{0,2}"
ErrorMessage
="必须输入整数"
ControlToValidate
=""
></
asp:regularexpressionvalidator
>
</
div
>
<
div
>
<
label
>
配偶工作单位
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
职务或职称:
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
</
div
>
<
div
>
<
h3
>
享受住房分配或货币补贴情况
</
h3
>
<
div
>
<
label
>
(1)已享受房改购房面积(平方米)
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
(2)已享受购房补贴(元)
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
(3)已享受住房补贴(元)
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
asp:button
id
=""
Text
="计算"
Runat
="server"
></
asp:button
>
<
label
>
本次补贴面积(平方米)
</
label
>
<
cc1:acceptnumber
id
=""
runat
="server"
></
cc1:acceptnumber
>
</
div
>
</
div
>
<
div
>
<
h3
>
住房补贴
</
h3
>
<
div
>
<
label
>
本人补贴(元)
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
本人工龄补贴(元)
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
配偶补贴(元)
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
配偶工龄补贴(元)
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
特殊补贴(元)
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
合计(元)
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
实际发放补贴(元)
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
</
div
>
<
div
>
<
h3
>
请申请人根据不同情况填写
</
h3
>
<
div
>
<
label
>
现购房地址
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
售房单位
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
<
div
>
<
label
>
偿还贷款帐号
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div