当前位置: 首页 > 图文教程 > 网页制作 > CSS样式表 > 关于网页表单实现和网页布局如何运用表单
HTML表单一文中介绍了关于表单的创建和样式化的基础内容。本文提供了关于表单元素和样式的更多详细内容,以及在真实的web应用程序设计中表单是如何运用的。
这一部分提供了关于表单实现和界面布局的新信息。
大量使用class和id标记是违反KISS(保持简洁)准则的(在CSS盒模型与基础布局一文中已经解释过了)。然而,难度大的布局却经常会在级联上遇到很多冲突——这些冲突最简单的解决方法就是在元素中添加标记,以及编写包含若干选择符的样式表规则。
难度最大的布局中到处都是边缘情况,对这些边缘情况最好的处理办法就是给元素赋一个id,来定义一个狭义而唯一的环境。
通常一个实际的表单所需要的不仅仅是按钮和文本输入区域,因为我们常常会需要按照选项来构建用户响应。HTML为有这种要求的设计人员提供了若干选项。
对于网站来说,表单常常是用户交互和数据搜集的焦点所在。因此,表单对于一个网站的成功与否是非常关键的,这就要求我们对表单的设计给予高度的关注。
最容易吸引网站用户的注意力的是浏览器画布(以及穿过布局的线条)上的四个特定点。本文将向你介绍这种现象,并提供一些建议,告诉你如何通过CSS来最大程度地利用这种现象。
前面的文章中我们介绍了如何确保排版的一致性以及最大化地利用空白。本文中我们会更进一步地阐述如何利用em单位来实现一定程度的布局一致性,这种一致性只有通过CSS才能实现。
商业项目中常见的一种要求是,一个被认可的网站设计应当在一种或多种浏览器上渲染效果一致。本文将会对这种要求的原因,效果,以及用于满足这种要求的处理方法进行简要的探讨。
通过联系表单,网站访客可以直接将e-mail发送到站内信箱中,联系表单的使用是非常普遍的,这是因为:只要用户具有激活的e-mail地址,他就可以使用联系表单,而且联系表单可以很方便地结合到专门的邮件文件夹中。
在前面的表单一文中,所涉及到的标记就是用来创建这样的表单的,我们还对这个表单进行了一些修饰:
<form id="contactForm" method="post" action="/cgi-bin/service_email_script.php"> <ul> <li id="nameField" class="required"><label for="realname">Name:</label><input type="text" name="name" value="" class="medium" id="realname" /><span class="note">required</span></li> <li id="addressField" class="required"><label for="address">Email:</label><input type="text" name="email" value="" class="medium" id="address" /><span class="note">required</span></li> <li id="subjectField"><label for="natureOfInquiry">General subject:</label> <select name="subject" class="medium" id="natureOfInquiry"> <option value="support">Support</option> <option value="billing">Accounts & billing</option> <option value="press">Press</option> <option value="other_q">Other questions</option> </select> </li> <li id="acctTypeField"><label for="acctNone">Account type:</label> <fieldset> <label for="acctGold">Gold</label><input type="radio" name="acct_type" id="goldAcct" class="rInput" /> <label for="acctSilver">Silver</label><input type="radio" name="acct_type" id="acctSilver" class="rInput" /> <label for="acctBronze">Bronze</label><input type="radio" name="acct_type" id="acctBronze" class="rInput" /> <label for="acctNone">None</label><input type="radio" name="acct_type" id="acctNone" class="rInput" checked="checked" /> </fieldset> <span class="note">required</span> </li> <li id="availabilityField"> <label for="availability">My account is unavailable:</label><input type="checkbox" name="is_down" id="availability" class="rInput" /></li> <li id="messageField"><label for="messageBody">Comments:</label><textarea name="comments" cols="32" rows="8" class="long" id="messageBody"></textarea></li> <li class="submitField"><input type="submit" value="Send" class="submitButton" /></li> </ul> </form>
除了包含了几个新元素之外,这段标记之中还添加了许多class和ID,这些class和ID可以在样式表中加以引用。这样就可以对每个表单,表单域/值组,以及表单域分别加以引用,而不用管上下文。
此外,通过新的标志符,设计师就可以将必须填写的表单域和不是必填的表单域区分开来。
最后,这段代码中还有一些新的类,用来提示自身所在的表单元素应该显示的信息的数量和类型。通过这些类,就可以将布局细节同时应用到多个任意元素上。
由于该示例表单只具备最基本的内容,我们用标题替换掉了之前文章的表单中的legend元素。
标签是最适合用在fieldset中的,而不是label(label更多地是与单个控件相关)。在本例中我们完全忽略掉了legend元素,因为它很难样式化。
另外还需要注意的是,在源顺序中,表单域的“required”标签最好是放在表单域自身之前,以满足屏幕阅读器用户的需要。然而,为了对这些项目进行合理安排,position属性(不属于本文的讨论范围)是必需的。因此,“required”标签在源顺序中是放在其相关控件之后的(即使是在同一个上下文中)。
文本框和提交控件在前面的文章中已经介绍过了。就如上面所说的,我们会遇到很多实际用例,在这些情况中要让用户能够选择两个或两个以上的选项。下面我们将简要地谈一下涉及这些操作的元素。
… <label for="availability">My account is unavailable:</label><input type="checkbox" name="is_down" id="availability" class="rInput" />
选择加入或选择退出这类问题通常都是通过这些控件之一来实现的。此外,这类控件还可以用在需要从几若干选项中任选几种的时候,比如说,一张个人爱好清单。
… <label for="acctNone">Account type:</label> <fieldset> <label for="acctGold">Gold</label><input type="radio" name="acct_type" id="goldAcct" class="rInput" /> <label for="acctSilver">Silver</label><input type="radio" name="acct_type" id="acctSilver" class="rInput" /> <label for="acctBronze">Bronze</label><input type="radio" name="acct_type" id="acctBronze" class="rInput" /> <label for="acctNone">None</label><input type="radio" name="acct_type" id="acctNone" class="rInput" checked="checked" /> </fieldset>
通过一组单选框,你可以把若干选项排列在一起,在这些选项中只能选择一个。比如,在1-5或1-10的等级范围内指定一个数值,这个例子直观地阐述了radio控件的使用。
跟其它表单控件不同的是,radio控件不仅是允许,更是要求各个相互关联的控件的name相同。
这些元素的得名是来自于常见的机械式调音的汽车收音机界面。跟那些常见于数字调音收音机的由程序控制的预设不同,机械“预设”按钮只要一按下,就会从一系列波段中将收音机聚焦在要收听的那个波段上。
checkbox和radio控件都有checked属性,只要设置了该属性,就会在初次渲染的时候默认激活该控件。
关于是用radio控件,还是checkbox控件的问题,最好是在考虑完各种不同因素后再作决定。如果你想让用户对一项主观性的选择(比如,加入邮件列表)进行确认,那么checkbox控件可能是最好的选择。如果你想让用户在两个客观性的选项(比如说性别)中做出选择的话,就应该用radio控件。
… <label for="natureOfInquiry">General subject:</label> <select name="subject" class="medium" id="natureOfInquiry"> <option value="support">Support</option> <option value="billing">Accounts & billing</option> <option value="press">Press</option> <option value="other_q">Other questions</option> </select>
select和option元素跟一系列radio控件的效果差不多,但占的空间却要少得多。是否用select元素来代替一堆radio控件,这通常是关系到如何使用用户界面空间的问题;对于电子商务网站里的一长串地理区域的列表或部门列表这样的内容,一般都是用select元素比较好,而简短的选项(比如,是/否,真/伪,年龄段,收入范围)则应该用radio控件来排列。
慎密的自测表明,操作select列表所需的运动控制水平是很高的,但随着其包含的option数量的增加,所需的控制水平的增长是很微小的。实际结果就是,简短的互斥选项列表最好是采用带有适当label的radio控件的形式。
fieldset元素最重要的目的就是为一组紧密相关的控件划分一个单独的语境(比如将一组text控件归为电话号码,将select元素归为日期,等等。)。
既然本文所涉及到的新概念已经概述完了,现在我们就该来看一看实际的应用——下面的十二个示例全面包含了Web表单开发过程中遇到的各种设计概念和样式化问题。
强烈推荐读者将示例材料保存到自己的硬盘上,并对其中的样式表规则进行尝试。
这些示例按照源代码顺序逐渐深入,而不是按照样式表的制作顺序。之所以这样做的原因和含义将在本文后面部分进行讨论。
我们从html { margin: 0; padding: 0; }规则开始,第一步是对包含该表单的页面的body进行配置。
body { margin: 0; padding: 1.714em; background-image: url(images/bg_grid.gif); font-size: 14px; font-family: Helvetica,Arial,sans-serif; line-height: 1.714em;
}
现在页面容器已经做好了,接下来的几个步骤就是改变或删除用户代理样式。
h3 { margin: 0 0 1.2em 0; border-bottom: .05em solid rgb(0,96,192); font-size: 1.429em; line-height: 1.15em;
}
form { width: 35.929em; margin: 0;
}
ul { margin: 0; padding: 0; list-style-type: none;
}
对h3进行样式化的目标是创建24像素高的内容框,下面要紧跟24像素的空隙,也就是:
(((14 × 1.429) × 1.15) + (20 × .05)) ≈ 24 14 * 1.429 ≈ 20; 20 * 1.15 == 23; 20 * .05 == 1;
(20 × 1.2) = 24
……现在来为表单元素创建容器。
li { clear: both; height: 1.714em; margin: 0;
}
fieldset { height: 1.429em; margin: 0 0 -.143em 0; border: 0;
}
良好的平面设计(随之而来的就是良好的界面设计)最大的优点之一就是元素是按照可预测的间距来铺设的。这些间距又称作栅格。
上面已经说过,本示例中的最小栅格单元是24像素的正方形,但比起确保设计元素按照细小而可预测的间距来放置,保证布局的协调性所要考虑的事情更多。真正有效的栅格应当具备如下特性:
明显具有这些特征的布局将会更富吸引力,而且更容易理解,因此也将有利于提高网站的可用性。
大多数专业人员用来创建站点布局构图的工具是Adobe Photoshop,它的优点之一就是能轻松使用网格线。为了在Photoshop中显示最小栅格,你可以选择View → Show → Grid,这样就能按照在Guides & Grid Preferences中设置的间距来显示网格了。
通过选择View → Rulers,切换到移动工具,将标尺上的指针往标尺外拖动,就可以对诸如列之类的东西添加定位标记了。
正如所指出的那样——示例样式表中的一些规则强化了这个概念——在一个布局中实施最小栅格最好的方法是依靠em单位。然而,仅靠em是不够的;设计师在处理替换字号,空隙,以及边框时还必须保证分数到小数的转换正确。
在示例样式表中还展示了另一种实现栅格的技巧:使用与文档中各种元素和列的大小有关的class标记。如果保持这些标记的一致的话,大部分实施栅格的工作都可以通过它们来完成。
使元素对齐到栅格就是为标签和表单控件设置布局属性。
label { display: block; float: left; clear: left; width: 10.286em; overflow: auto; padding-right: 1.714em; text-align: right;
}
input { height: 1.143em; border: .071em solid rgb(96,96,96); padding: .071em; line-height: 1;
}

图1:俄勒冈州 Portland的早春景色。我们对这幅照片添加了线条,来阐释三分法则;注意看右下方的交叉点和形成该交叉点的线条是如何约束视觉活动的。照片作者版权所有,©2000。
在考虑如何实现优秀的布局的时候,有一个普遍存在的规律:如果你将布局或图片分成三部分,浏览者的注意力就会集中在分隔这些部分的线条(尤其是线条的交点)上。如果没有在设计中运用这个奇异的规律的话,你的布局就会显得不均衡。
对这种现象最简单的解释就是,这四条线与符合黄金比例的栅格非常接近,该比例的值接近六分之一。在各种数学领域和自然世界中经常可以遇到黄金比例的例子。

图2:msnbc.msn.com的屏幕截图,上面加上了七个金色的矩形。挨在一起的第四和第五个矩形整体说明了页面布局栅格的本质。
该示例表单的布局中,表单控件都对齐到一个左边缘,这个左边缘位于从左边到假想的表单右边缘的整个距离的三分之一处,这是经过慎重考虑后出的选择。而表单的垂直布局就更是如此了——将标题考虑在内,文本区域正符合前面所说的那两条规律。就算不将标题考虑在内,必填的表单域也符合最重要的那条规律。
对于设计师来说最重要的一点就是,如果在样式表设计一开始的时候就将三分法则和栅格纳入考虑范围的话,样式表的规范化工作就会大大简化。
为了在水平和垂直方向上维持我们想要的栅格,还需要做一些细节调整。这些调整几乎完全是装饰性的。
textarea { height: 4.714em; margin-bottom: .286em; border: .071em solid rgb(96,96,96); padding: 0;
}
select { display: block; float: left; height: 1.571em; font-family: Futura,'Century Gothic',sans-serif;
}
option { font-size: 100%; }
前一个示例对字体渲染进行了一些调整;现在我们接着来完成这个工作。
input, textarea { display: block; float: left; overflow: hidden; font-family: Futura,'Century Gothic',sans-serif; font-size: 1em;
}
input, textarea, select { margin-top: 0; font-size: 100%;
}
我们需要将各个文本控件的宽度改变一下,不让它们跟默认值相等。
.medium { width: 11.714em; }
select.medium { width: 12em; }
.long { width: 20.429em; }
.rInput { border: 0; }
我们这个表单的提交按钮等候处理已经等了很久了……
.submitButton { display: block; clear: both; width: 7.2em; height: 2em; margin: 0 0 0 16.8em; border: 1px solid rgb(128,128,128); padding: 0; font-size: 10px; text-align: center;
}
把“required”标签放到它该去的地方。
li.required span.note { display: block; width: auto; float: right; color: rgb(128,128,128); font-size: .714em; line-height: 2.4em; font-style: italic;
}
终于该来解决radio控件的冲突问题了,也就是说这些控件跟源顺序中位于它们之下的表单域之间的冲突问题。
fieldset label { margin-right: .25em; padding-right: 0; line-height: 1;
}
fieldset .rInput { margin-right: .75em; }
fieldset label, fieldset .rInput { width: auto; display: inline; float: none; font-size: .857em;
}
li.required fieldset { width: 18.857em; float: left;
}
我们来做最后一步,将剩下的一点小小的参差对齐,让整个表单井井有条…
#acctTypeField fieldset { padding: .286em 0 0 0; line-height: normal;
}
#acctTypeField .rInput { margin-top: .167em; }
#availabilityField label { height: 3.143em; padding-top: .286em; line-height: normal;
}
#availabilityField .rInput { margin-top: .286em; }
#availabilityField, #messageField { height: 1%; overflow: auto;
}
前面所有的样式规则都是针对Opera或Safari的(随你挑,这两种浏览器都表现得相当好)。下面的这些样式规则是专门针对IE的,我们通过CSS文件中的link条件注释代码块来指定它只针对IE。
h3 { margin-bottom: 1.2em; }
li { margin: 0 0 -.214em 0; }
select { height: 1.429em; }
textarea { height: 4.571em; }
fieldset { height: 1.583em; padding-top: .417em;
}
.medium { width: 13.429em; }
select.medium { width: 13.714em; }
.long { width: 20.286em; }
fieldset .rInput { border: 0 !important; }
#subjectField { margin-bottom: -.214em; }
#availabilityField .rInput { margin-top: .286em; }
#messageField { padding-bottom: .286em; }
input.submitButton { margin-top: .15em; }
* html input, * html textarea { float: left; }
* html select { font-size: .643em; }
* html select.medium { width: 21.364em; }
* html textarea { height: 4.643em; }
* html #subjectField { margin-top: .071em; margin-bottom: 0;
}
* html #availabilityField label { padding-top: 0; }
* html input.submitButton { margin: .1em 0 0 7em; }
本文示例的最后一部分展示了单独为IE6和IE7编写的样式表,而尽职的网站设计团队如何针对各种不同的浏览器进行处理,还需要更多的讨论。
Web的现实情况是,用户们在形形色色的环境下使用着五花八门的浏览器。有的浏览器是老式的,而有的却是最前沿的。有的浏览器是在配置齐全的计算机上运行的,而有的却是在电话之类的移动设备上运行。所有浏览器都是在特定的操作系统上开发的,然后再移植到其它的标准支持程度不同的操作系统上去。除了Opera,所有的浏览器发行商所发布的浏览器都被设计成要跟一系列产品中的其它类型的产品搭配使用——这种设计要求增加了这些浏览器的复杂度,而这种复杂度对于浏览网页这样的简单任务来说是不必要的。
多种多样的浏览器优缺点已经够设计员们琢磨的了,然而现实中却还存在着漏洞的问题——安全漏洞,组件漏洞,尤其是还有渲染漏洞。Safari 3.x的用户们发现,这些演示文档揭示出他们自己的浏览器在某些地方存在着令人郁闷的渲染漏洞。
解决这些问题最好的办法就是定义支持等级。这种做法,又叫做“分等级浏览器支持”,最先是由Yahoo!的界面开发团队宣传开来的。
大体上说来,支持等级分成四个大类:
至于形成该支持等级定义的要求收集过程以及将浏览器归类至各个等级之下的详情,实在是又长又乏味,由于本文已经够长了,这些内容就略去不谈了。
在上述的背景说明中,我们将示例的出场顺序按照样式表源顺序来安排,而不是按照样式表中实际的规则添加顺序来安排。之所以这么做,原因包括:
Opera 9.6 的 OS X版是开发用的用户代理;除了这个附加说明和在上面提到过的其它说明之外,下面是对该样式表进行修改和增添的一般顺序:
上述的过程以最宽泛的规则开始,逐渐变得越来越具特异性,直到个别浏览器的特定缺陷被囊括其中……与样式表自身的源顺序非常相似。然而,它们的结果并不完全相关。这是因为,浏览器渲染引擎的多样性以及像float语境之类的东西的特性,在混合进多种样式的时候导致了不可意料的结果,因此实际的处理比起折返,调整,以及再考虑要更复杂。
本文提供了一个关于表单样式化和布局的构思慎密的基础,但在此基础之上还可以进行更加深入的研究。如果设计师需要创建一个向标准靠拢的web表单,由操作系统(创建Web表单控件时借用了其组件)造成的麻烦,以及浏览器渲染引擎之间的差异会使得摆在他面前的任务更具有挑战性。本文对那些有关于这种任务的浏览器缺陷进行了初步的实验,并说明了如何达到对web开发中较难的一个方面的熟练掌握。
在下面的表格中,括号内加了星号的数字表示它们是无限循环小数;比如0.2(6*)就等于0.266666666666666…(6是无限循环的)。
因为表格是从左到右阅读的,表格的左边是最接近于零的数值,并且越往右越大。
| x | 1/x | 2/x | 3/x | 4/x | 5/x | 6/x | 7/x | 8/x | 9/x | 10/x | 11/x | 12/x | 13/x | 14/x | 15/x |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2 | .5 | - | - | - | - | - | - | - | - | - | - | - | - | - | - |
| 3 | .(3*) | .(6*) | - | - | - | - | - | - | - | - | - | - | - | - | - |
| 4 | .25 | .5 | .75 | - | - | - | - | - | - | - | - | - | - | - | - |
| 5 | .2 | .4 | .6 | .8 | - | - | - | - | - | - | - | - | - | - | - |
| 6 | .1(6*) | .(3*) | .5 | .(6*) | .8(3*) | - | - | - | - | - | - | - | - | - | - |
| 7 | .(142857*) | .(285714*) | .(428571*) | .(571428*) | .(714285*) | .(857142*) | - | - | - | - | - | - | - | - | - |
| 8 | .125 | .25 | .375 | .5 | .625 | .75 | .875 | - | - | - | - | - | - | - | - |
| 9 | .(1*) | .(2*) | .(3*) | .(4*) | .(5*) | .(6*) | .(7*) | .(8*) | - | - | - | - | - | - | - |
| 10 | .1 | .2 | .3 | .4 | .5 | .6 | .7 | .8 | .9 | - | - | - | - | - | - |
| 11 | .(09*) | .(18*) | .(27*) | .(36*) | .(45*) | .(54*) | .(63*) | .(72*) | .(81*) | .(90*) | - | - | - | - | - |
| 12 | .08(3*) | .1(6*) | .25 | .(3*) | .41(6*) | .5 | .58(3*) | .(6*) | .75 | .8(3*) | .91(6*) | - | - | - | - |
| 13 | .(076923*) | .(153846*) | .(230769*) | .(307692*) | .(384615*) | .(461538*) | .(538461*) | .(615383*) | .(692307*) | .(769230*) | .(846153*) | .(923076*) | - | - | - |
| 14 | .0(714285*) | .(142857*) | .2(142857*) | .(285714*) | .3(571428*) | .(428571*) | .5 | .5(714285*) | .6(428571*) | .(714285*) | .7(857142*) | .(857142*) | .9(285714*) | - | - |
| 15 | .0(6*) | .1(3*) | .2 | .2(6*) | .(3*) | .4 | .4(6*) | .5(3*) | .6 | .(6*) | .7(3*) | 8 | .8(6*) | .9(3*) | - |
| 16 | .0625 | .125 | .1875 | .25 | .3125 | .375 | .4375 | .5 | .5625 | .625 | .6875 | .75 | .8125 | .875 | .9375 |
评论 (0) All