重构之美-走在Web标准化设计的路上[深入结构:div再议以及对span的迷惑。]

连接
◆《重构之美》总目录
上一篇:重构之美-走在Web标准化设计的路上[深入结构:合理运用div。]
下一篇:重构之美-走在Web标准化设计的路上[复杂表单:Reloaded]


修整一个月,我又回来了,好吧,咱继续聊。

上篇文章中主要否定了使用div进行布局这种说法,提出div应当用于组织代码结构,现在我们再深入一点,div拥有语义吗?这个问题前段时间在研究群里曾激烈争论过,当时米随随发问:“什么是语义化WEB,div是什么?”小毅答曰:“DIV表示无意义容器。”我说:“否定。”然后旁边有人嘀咕:“...又要打起来了。”我大笑着进入战斗状态,结果迅速被围攻了。呵呵,总是和主流格格不入的我又一次站在主流的对立面。我还是不赞成将div视为无意义容器。容器这个概念是模糊的,是与设计挂钩的,理解成容器以后又远离结构了。再说每一个不是自我关闭的标签都可以视为容器,有什么区别?难道div可以包含一切(别断章取义哈),于是就可以随意使用了吗?那又如何固定xhtml?所以还是要回到div的语义上来,div是有语义的,只不过它的语义是面向代码结构的,是面向程序的。

division(分割),对了,前段时间浏览w3schools时,看到它是这样定义div的:The div tag defines a division/section in a document. 我想我对div的理解是没错的。在文档中定义一个分割或者节点。我说div用于模块化页面内容,实际上从代码结构角度是展现xml化的节点结构。除了定义一个节点以外,div目前还用于定义一个分割,产生具有结构的行。还是以登陆为例:

< div >
    
< h3 > 用户登陆 </ h3 >
    
< div >
       
< label  for ="name" > 用户名 </ label >
       
< input  id ="name"   />
    
</ div >
    
< div >
        
< label  for ="pw" > 密码 </ label >
        
< input  id ="pw"   />
    
</ div >
    
< p >< button  /></ p >
</ div >

最外层的div是作为产生节点使用,而用户名和密码部分实际上是为了产生具有结构的行,这里若使用br同样能够产生行,但是缺乏结构,所以div代替了br。猜到我要说什么了吗?呵呵,又是xhtml 2.0,2.0中的section和line标签,是的,在1.X中,div同时扮演了section和line的角色,因为分割产生节点,因为分割产生行。但是很明显section和line具有比div更为明确的语义,那么我们可不可以认为div的语义和br一样是模糊的,既然是模糊的,br已经被毙了,我们现在大量使用的div会不会落到同样的下场呢?不知道,至少目前的xhtml 2.0中,div仍然存在。看看上面的结构代码在xhtml 2.0中应该如何展示(没考虑XForm):

< section >
    
< h > 用户登陆 </ h >
    
< line >
       
< label  for ="name" > 用户名 </ label >
       
< input  id ="name"   />
    
</ line >
    
< line >
        
< label  for ="pw" > 密码 </ label >
        
< input  id ="pw"   />
    
</ line >
    
< div >< button  /></ div >
</ section >

所以有些人单纯的认为好像是div在不断嵌套,其实不是的,是没有办法而产生出来的假象。这里再请大家注意一个情况,需要和css结合起来看待,按钮那个部分,在xhtml1.X中我使用了p,严格说从结构上是错误的,很明显按钮不是一个段落,我仅仅是希望它换行呈现,但是如果使用div,那么就必须给予这个div一个class="button"以区分开来,并且在设定css的时候必须先清除公有的样式属性,这样会带来不少麻烦。另外作为节点的div和作为行的div同样会出现这种问题。示例:如果我定义节点div{width: 300px; padding: 10px;},那么我就必须在定义行div时要么覆盖要么清除以避免冲突,div div{width: 200px /*覆盖*/; margin: 10px; padding: 0 /*清除*/; color: #333;},然后在定义div div.button{margin: 0 /*清除*/; color: #F60 /*覆盖*/; background: #999;}的时候再做对行div的样式冲突避免,为了避免这种情况,采用对节点div增加class="loginarea"和p,这样就可以避开两次样式清除和覆盖操作。这样的情况在结构复杂的页面中更为明显,不要告诉我加class就行了,class越多,文档通用性越差,xhtml越难固定。这就是在xhtml1.X 中因为div的语义模糊带来的麻烦,回头在xhtml 2.0的结构中就很好办了,section{},section line{},section div{},无需class也互不干扰,诶诶诶,这里的div貌似很适合它分隔的语义哈,不是行也不是节点,仅仅就是一个分隔,呵呵。

在我认为标签中最难理解的2个之一的div现在应该算是很清楚了。剩下的一个就是span,至今我仍未能理解到span如何产生结构,只好说说自己的迷惑了。

先还是说说div和span的区别,从大的方面来说,div被归类到Structural Module(结构模块),而span被归类到Text Module(文本模块)。小的方面,div是block-elements(块级元素),span是inline-elements(行内元素)。在所有Structural Module中,div是唯一一个语义模糊的,在所有Text Module中,span也是唯一一个语义模糊的,呵呵,两个Tag唯一的共性:语义模糊。

回到span的语义:跨度、范围。这个这个……比division(分割)更为抽象,难以理解。在一阵疯狂google后还是没找到我想要的那种解释,接近的都没有,也许根本就没有,所有的结果都指向表现,无论中英文都是指为字体添加样式,可是可是W3中明文写着The span element, in conjunction with the id, class and role attributes, offers a generic mechanism for adding structure to documents. 这里的for adding structure to documents做何解释?百思不得其解,后来气不过,甚至打开W3的源码查看他是如何使用span的,虽说获得了一些提示,但依旧不足以领悟到structure的真谛,我想应该是我的XML功力还不够。唉,既然语义上,结构上行不通,那么只好换个角度,从实际应用中试着去理解。span是行内元素,主要应用于文本,这点没什么异议,关键在于如何运用?为什么我始终不认为span是个样式容器,对,又是容器,google的时候发现清一色的容器解释,div是大容器,span是小容器,我郁闷。如果span因为文本的样式而存在,它凭什么存在?一段文本为什么要添加样式?如果你想强调应该使用em,如果想特别强调应该使用strong,Text Module里还有很多语义明确的标签可以使用。所以span应该不是作为样式容器而存在,就像div不是作为布局容器而存在一样。但是我领悟不到span的真谛,哭啊!不过我可以抛砖引玉,在有一个地方,我一定会使用span的。那就是表单中。还是以登陆为例,如果登陆的数据需要展现出来,比如很多edit页面和view页面,结构应该完全相同,不同的是在edit页面中是输入框,而view页面中则用span展现数据。类似如下:

< div >
    
< h3 > 用户登陆 </ h3 >
    
< div >
       
< label  for ="name" > 用户名 </ label >
       
< span > MyName </ span >
     </ div >
    
< div >
        
< label  for ="pw" > 密码 </ label >
        
< span > MyPassword </ span >
     </ div >
    
< p >< button  /></ p >
</ div >

这样的好处有两点:1、和label区分开来,便于应用样式,如下定义:div div span{}。2、可以通过节点提取所有录入的数据。这是我目前唯一非常明确的使用span的地方,这里除了span好像没有更合适的了,也有点符合它的语义:范围和结构化。这是我抛出的一块砖头,谁能引出玉来,或者知道玉,求之。其他span的运用仍在摸索中,包括从W3源代码中获得的提示。

差不多要说完了,这时我对关于容器的说法又耿耿于怀了,于是再次以容器为关键词疯狂google,凭什么上上下下都说是容器,我要找出根源来,终于在最后,皇天不负有心人,在我执迷不悟的,怀着容器是错误理解的信念下,挖出来了根源。W3在这里对div和span进行了这样的解释:generic language/style container。两者都一样。哦,原来如此,怪说不得所有的中文翻译都是容器,我想很少人去看英文追根到底吧。确实style container应当翻译为样式容器。这一点都没错,错的是请注意,这是html中的div和span!!!而不是xhtml中的div和span,随即我再查到W3在对xhtml中的div和span的解释,已经不一样了:对于div是Define the characteristics of a block,而对于span是Define characteristics of text。对!这才是我的理解,也是我想要的正确解释!!因为这个是xhtml 2.0中的解释,由于2.0中section的存在,所以在对div的解释中,节点的含义被取消了,xhtml1.x的解释我懒得去找了。现在回头看我刚才试着写下的xhtml 2.0登陆结构中的div和最后一句话。嗯,div即便不做节点也不做行,可能还是有用的。

说到这里,问一句,html和xhtml最大的不同在哪里?是语法吗?是名称吗?是严格了,xml化了吗?不不不,本质区别是:html是面向表现的语言,而xhtml是面向结构的语言!所以我们应当从结构的角度去审视和理解与运用xhtml中的每一个Tag。比如容器的理解,在面向表现的html中,是正确的,但是在面向结构的xhtml中则错了,应该理解为节点。理解直接影响运用,以表现的理解显然无法写出结构化的代码。否则什么合什么离,哈哈哈,忍不住又敲出来了。

好了,span现在总结不出来,只好先对div做个总结收尾:在当前xhtml1.x环境下,我们需要产生节点(section)和行(line)的时候选用div。

阿弥陀佛,最烦人的两个东西总算告一段落,虽然未完,但是遗憾也是美嘛,以后再说了。结构也算告一段落,下篇可以换个口味了,正式进入语义!

2006 4 27-29 Create


连接
◆《重构之美》总目录
上一篇:重构之美-走在Web标准化设计的路上[深入结构:合理运用div。]
下一篇:重构之美-走在Web标准化设计的路上[复杂表单:Reloaded]

---------------------垃圾部分------------------

..
            
< 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 >
posted on 2006-04-29 01:07 爆牙齿 阅读( ...) 评论( ...) 编辑 收藏

你可能感兴趣的:(span)