连接
◆《重构之美》总目录
上一篇:重构之美-走在Web标准化设计的路上[深入结构:div再议以及对span的迷惑。]
下一篇:重构之美-走在Web标准化设计的路上[深入语义:列表Tag(ul/ol)和表格Tag(table)的抉择。]
在《复杂表单》一文中我提出了表单的标准化设计思路,但并没有什么个人总结,因为当时我也在权衡揣摩研究以及斟酌判断决策之中。^_^。
在复杂表单上,标准的优势吸引着我,标准的劣势折磨着我。坚持住,几个月后,劣势开始变小,优势如我所预料开始展现出来了。
还是先回到《一个简单又不简单的标准化表单设计实例。》这篇文章来,把它解决了。有个朋友评论的署名是onestab,你的CSS写得干净简洁,但是仍不够漂亮,最重要的,不管你是否真的来自曾经给于我过帮助的OneStap,您还是没有给出正确办法,因为:我的“大便蛔虫的表单主标题”部分到哪里去了?你怎能无视它的存在?没有它就简单了,难就难在它存在,又不能定义在body中也不能为它而改变结构增加Tag。当然我相信多想一下你肯定能想出来。好吧,我来说说看。
首先我很遗憾,竟然没有一个人指出:您的结构不完整。我前面呕心沥血写的文章都白写了,一到实例上大家眼中仍然没有关注结构。是的,有人想过这个问题吗?(当然可能大家都懒得理我,^_^)我记得以前在标准群中提这个问题的时候,小毅第一句话就是:你的结构不完整。仍我怎么解释他都咬死这句话,拒绝继续,气死我的同时还是感到欣慰。我们抛开设计稿,结构中在body和div之间最少都应该有个标题h1来指明这是“大便蛔虫的表单主标题”。“新增联系人”只是模块标题,还需要一个归属,这个模块到底是用在北京WC研究院还是上海WC研究院。这是一个成熟开发平台中发布了的通用组件,在我到来之前就已经存在很久了,作为通用组件,这个主标题应该具备并且动态生成,但是由于在我去之前,把Web标准带去之前,这个公司三十多个程序员都在用传统方式研发和开发,没人关心过结构,所以这个功能一直没有,而要添加的话,引一发动全身,最初我选择的是直接改动ascx,增加h1写死在页面,但是这样的话就降低了组件的重用性和灵活性,尤其是有很多这样的表单。所以我最后选择放弃h1。结构的不完整带来的就是CSS设计的困难,不能按正常思维去完成,我曾有那么几分钟很想把h1添加上去,但是最终还是从css上找到了办法。可以留意一下我是怎么分析页面的?Css设计唯一的难点是结合结构分析页面,而table不一样,按照设计稿切分表格就是了,当然table也有页面分析,分析的好嵌套少,想省事,那么就使劲嵌套吧,所以传统的table制作手段只有还原没有设计。而我在做Css设计的时候,10分钟会有8分钟用来对着电脑发呆,单个页面的分析,整个站点的分析,整体设计的分析。……打住,跑题了,说远了,回来回来。汗……
没有h1的难点在于主标题图片放在哪里?边框怎么解决?
1、主标题如果放在body中,那么为了避免冲突,必须给每个这样的页面的body增加class,麻烦。
2、如果主标题放在div中,左右边框怎么办?如果把边框做成图片定死,那么怎么适应分辨率?又或者用内部的div来拼凑边框,问题更大。
怎么办,走头无路的时候,反向思维!其实就是乱想。我们还有一个Tag可用,那就是h3。
1、把“大便蛔虫的表单主标题”这张图片定义到h3中去,看似违背常规设计思路,却解决了问题!
2、给div样式margin-top和body拉开距离,然后用相对于div的绝对定位使h3飘起来去填充拉开的距离以定位图片标题。
3、再给h3样式padding-top定位“新增联系人”字体的位置,而“新增联系人”下面的渐变背景则定义在div中repeat-x。
4、最后给div样式padding-top使表单内容在渐变下方。搞定!^_^
其实如果静心分析,可以一下就出来了。要实现自适应边框一定不能用图片实现,只能用div定义边框,因为表单内容会变,所以不能使用第三层的div拼凑边框。主标题在边框外,正常设计下,这就意味着div外需要tag,而目前div外只有不能使用的body,那么要解决这个问题唯一的办法就是从h3身上想,h3能否跑到div外面去?可以!绝对定位。看,分析完了也就做完了。这种手法有一点类似我在《Web标准下,OA系统常见左栏定宽,右栏自适应宽度的“爆(牙齿)力解决法”。》一文中的手法。活用绝对定位,跳出常规设计思维。所以我说我发错地方了,这里大部分人都是程序员,对Css的设计并不擅长也没必要,要解决这个问题不仅必须对Css很熟悉,还要思维灵活,敢于胡思八道。关键是要能对着设计稿使劲发呆,脑袋高速运转,从上到下,各角度去分析页面、站点、整体设计……,而不是急急忙忙的动手。你思想站的高度将决定手中活的容度。
好了,关键样式在下面,完整的我打了个包——Web Standards Form Example.rar
*
{
top
:
0
;
left
:
0
;
margin
:
0
;
padding
:
0
;
font
:
normal 12px "宋体"
;
}
body
{
background
:
#AEB4C5
;
}
input
{}
/*
全局输入框
*/
.buttonarea input
{}
/*
全局按钮
*/
#PopPage
/*
相对定位
*/
{
position
:
relative
;
width
:
98%
;
margin
:
auto
;
margin-top
:
50px
;
padding-top
:
45px
;
text-align
:
center
;
border
:
1px solid #FFF
;
background
:
url(bg_02.png) repeat-x #F2F3F8
;
}
#PopPage h3
/*
绝对定位
*/
{
position
:
absolute
;
top
:
-50px
;
width
:
100%
;
padding-top
:
60px
;
background
:
url(bg_01.png) center 10px no-repeat
;
}
#PopPage div
/*
定宽浮动
*/
{
float
:
left
;
width
:
295px
;
}
#PopPage div label,
#PopPage div input
{
float
:
left
;
}
#PopPage div label
{
width
:
75px
;
text-align
:
right
;
}
#PopPage div.buttonarea
{
clear
:
left
;
width
:
100%
;
background
:
url(bg_04.png) repeat-x
;
}
#PopPage div.buttonarea input
{
float
:
none
;
}
/*
弹出表单按钮浮动清除
*/
自适应自己下载去试试,1024、1280都可以,我给出这个固定宽度的弹出窗口最终设计效果如下:
1024图
1280图
The End?结束了吗?没有,小小的例子可以引出很多东西来,慢慢来说。
我想大家肯定是有很多疑问的,说不定看了设计效果会有不少人骂到:靠,晃点我,明显和设计稿不一样嘛!文字中间的间距呢?输入框长度也不对啊!等等等等……我笑笑,说:凭什么要和设计稿完全一样!
说了这句话,我也静了一下。程序和设计是两条截然不同的路,设计是感性思维,而程序是理性思维。两者全通的人很少很少。所以作为程序员一般而言是没有资格去否定设计的,作为设计师也没有资格去否定程序,问题就出来这里:那么制作谁来做?我从一开始进入互联网就不认为设计和制作是可以分开的,就算在table布局时代,一个优秀的设计师完成设计稿后其实制作已经完成,因为设计时就已经充分考虑的制作(如何切图),精确到像素,脱离设计稿靠记忆都能迅速把表格准确切分出来(当然很多的所谓设计师只是随心所欲的在画画根本不考虑制作,所以被称为美工)。一个优秀设计师的设计稿绝对不仅仅就是一张图,它还涵盖了很多理念在里面(UI,UE,交互等等),到底有多少在于这个设计师对网页这个词的理解深度。你说平面设计师能不去考虑印刷吗?他在做设计的时候虽然不用考虑制作但必须考虑印刷的限制。对于平面设计师,他的设计水平不是设计稿,是印刷后的效果,同样对于网页设计师,设计水平体现在已经成形的网页上,网站设计师范围更大,网站的整体。设计稿算个屁啊!凸!你去问问室内设计的效果图算什么,有多少价值?一个室内设计师如果不知道材料和施工,只会玩3DS MARKS把效果图做得天花乱坠而又实现不了,狗屁。上面的例子,如果设计稿是我做的,我压根就不会把标题放在外面,或者不会选择这种表现形式来进行设计,我会充分考虑如何通过设计来降低制作的难度从而优化制作。还有,文字的间距,此类表单,如果文字无规律可寻,我也不会这么去设计,间距是表现是排版的一种手法(说到这里,既然间距是表现也应当写进Css,所以提醒大家,Web标准下,不要随便使用空格。空格不是办法,有本事用空格把4个字和5个字对齐,^O^!只有Css才能做到)。文案如果不能做到有规律可寻,那么就不该设计间距,否则给予Css设计很大难度,要在xhtml中增加很多无谓的class,还要一个一个定义,不是做不到而是很不值得。请搞清楚一件事,要做的不是Css还原,而是Css设计!哎呀,不说了,严重跑题,以后再详细阐述Web标准下的分工与协同。对了,大家别看了这段话就去和自己的设计师们叫板哈,那我就成罪人了,除非你自信自己对设计的理解比他们深,否则还是请尊重设计稿。
还是回到这篇文章的目的:复杂表单可以标准化吗?应该标准化吗?第一个问题有答案了,可以。那么应该吗?这个分歧点很大,有几个人赞成的请举手……好吧,呵呵,拿我的名字分两方面来论证一下。
求证:理论上来说,复杂表单应该使用table进行设计吗?
-
郑旻:(^_^)
-
如果用table来处理上面的例子,表单部分很明显是4列多行数据。但是它是吗?table是表格是吧,什么是表格?数据库应该是最好的表格了吧,像上面的例子,怎么在数据库中定义字段?当只有一条记录的时候,我们把数据库的行当列,列当行,字段作为值,它是一个2列多行的表,而不是4列。为什么会产生4列?那是因为表现的需要,或许我还会设计成三列的显示,再或许我希望它随分辨率的变动自适应。你的数据库中会设计多个重复的字段吗?所以,复杂表单虽然带个“表”字,但是大部分都是伪表格数据,为什么不是全部,还是有部分表单是真表格表单,类似DataGrid在线编辑模式下的那种。好了,论证完毕。
求证:实践中,效率上,复杂表单应该使用table进行设计吗?
-
郑旻:(哈哈,我又来了)
-
这个我想是大家最关心的事情。怎么说呢?这个是Web标准的特性:对于个人,尤其对于单个页面,用标准设计的速度永远比不上table的可视化设计速度。页面设计如此,表单设计同样如此。我记忆犹新,两年前,我在
《重构之美-迎接Web标准化设计的来临[总结一:网页设计回归?]》中对标准的速度做过如下总结:
3、关于速度和效率的问题。
很多人都在想这个问题,被这个问题所困扰。cloudchen曾经回复过我这么一句话:网页就象快餐,在这种东西上面浪费时间不值。我深以为是,速度是非常重要的。但是我要说的是,如果使用标准,对于网站来说,开发速度会比使用表格快N倍。从单个页面来开,使用标准再熟练再快我承认都快不过表格,说不定差距还会很大。但是对于网站来说就不一样了,随着网站规模的扩大,差距会缩小,到某个临界点时,两者会持平,而后使用WEB标准的网站在开发速度和效率上会将表格远远抛在后面。所以对于小网站,小应用来说,使用标准在速度上是完全没有优势甚至会有明显劣势,但是对于一个大网站,尤其是非一次性开发而是持续性不断开发的网站来说,呵呵,不用我说了吧。我使用表格5年,我的表格设计速度可以说已经练到极为准确和快速了,几乎无法再大幅度提升了,而我使用标准才 2、3个月,我有这样的体会,你做何选择?
今天我把它从坟墓里抓出来同样说到表单设计上,是的,对于团队,对于大量的表单,标准化后的优势不是一丁一点的,是淋漓尽致的凸现。我不止一次的说过和认为:Web标准从一个方面上讲是一项为团队而生的技术和标准!回到上例吧,先给一张图片,这个是我让程序员整理的该项目需要设计的弹出表单列表,先看看,数数,再看看旁边的下拉……。
感受如何?我有两个感受:第一站在传统的角度,我也是从传统过来的,我感到可怕。第二很庆幸标准的出现和我两年来的应用积累成精了,100个表单页面,就算斩一半也有近50,我们所有的程序员都解脱了,所有表现全部压在我头上,我一点都不怕,虽然依旧麻烦,但是相比之下,对于团队已是数量级的效率提升了。而且Web标准的高灵活性、高重用性和对未来的高度适用性等所有优势将驻留在标准化下的表单中,为未来带来极大的便利。
-
最后,当你的系统、网站页面全部标准化了,但是每个表单之处仍然table化,那么它将成为水桶的最短的那块板,不断的卡住你。还有什么疑问吗?那么我下结论罗,^_^。
结论一:理论上来说,复杂表单应该使用table进行设计吗?回答是:NO!
结论二:实践中,效率上,复杂表单应该使用table进行设计吗?回答仍是:NO!
不要说这个表单简单了,复杂了一样的,想想最初的标准只是在很简单的页面上实验,最简单的页面-博客-个人网站-门户网站,一路走来,发现其实复杂页面也没什么大不了(当然现在很多标准化过的网站实际上很烂),我的意思是表单同样如此,不在于它简单还是复杂,关键的关键还是在于结构化和语义化,表单是不是该用table来做?那么table到底该怎么用?
好了,两次的铺垫都为了下一篇,究竟什么是表格?什么是表状数据?[深入语义]loading....
连接
◆《重构之美》总目录
上一篇:重构之美-走在Web标准化设计的路上[深入结构:div再议以及对span的迷惑。]
下一篇:重构之美-走在Web标准化设计的路上[深入语义:列表Tag(ul/ol)和表格Tag(table)的抉择。]
---------------------垃圾部分------------------
..
<
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
>
<
div
>
<
label
>
贷款银行
</
label
>
<
cc1:xmldropdownlist
id
=""
runat
="server"
XmlNodeName
=""
XmlPath
=""
></
cc1:xmldropdownlist
>
</
div
>
<
div
>
<
label
>
本人公积金存储号
</
label
>
<
asp:textbox
id
=""
Runat
="server"
></
asp:textbox
>
</
div
>
</
div
>
<
div
>
<
asp:button
id
=""
Text
="保存"
runat
="server"
CssClass
="button"
></
asp:button
>
<
asp:Button
id
=""
Text
="退回"
runat
="server"
CssClass
="button"
></
asp:Button
>
<
asp:Button
id
=""
Text
="删除"
runat
="server"
CssClass
="button"
></
asp:Button
>
<
button
id
=""
onclick
="javascript:window.close();"
>
关闭
</
button
>
</
div
>
</
div
>