转载请注明本文出自http://www.dudo.org/
前面的文章,主要讲到如何使用无序列表ul元素来实现复杂柱状图,但是在Web标准中,除了注重表现外,更加注重语意,所谓的语意就是样式和内容的相关程序。在前面举到例子中,要实现销售记录一览,使用ul或者dd dt dl虽然可以实现想要的效果,但是如果不过表现,只看HTML代码的话,很明显,这堆代码基本上语意比较差,或者说单看HTML代码看不出你想要表达什么样的效果。在Web标准中,列举数据元素时,最好使用table元素来实现,这才是table的用武之地。在这一节里,我们就尝试使用table来实现复杂的柱状图效果。不过已经有人早就尝试过这个试验了(CSS Vertical Bar Graphs),为了和本节形成比照,前面的例子也是按照这个效果制作的。
首先来看一下运行的效果图:
在技术上来说,如果我们去除各个标签的本来含义,只把它们看作是XHTML中的普通元素的话,我们会发现其实无论使用什么标签,在实际操作上都差不多。我们之所以选择不同的标签是因为在表达上的需要,但从技术上说,它们只是普通元素。转载请注明本文出自http://www.dudo.org/
本文还是以前面文章设计的案例来讲,在阅读本文前,请先查看前面的这篇文章,以免造成理解困难。接下来我们就看看如何一步一步实现这样一个效果。
一、首先打地基——构建HTML代码
这个很简单,就是做一个XHTML中table标签就可以了:
<table id="q-graph" cellpadding="0" cellspacing="0"> <caption>某公司2007年1~4季度南北区域销售情况对照表(单位:万件)</caption> <thead> <tr> <th></th> <th class="north">北方</th> <th class="south">南方</th> </tr> </thead> <tbody> <tr id="q1"> <th scope="row">Q1</th> <td class="north bar" style="height:111px">18</td> <td class="south bar" style="height:99px">16</td> </tr> <tr id="q2"> <th scope="row">Q2</th> <td class="north bar" style="height:198px">32</td> <td class="south bar" style="height:210px">34</td> </tr> <tr id="q3"> <th scope="row">Q3</th> <td class="north bar" style="height:260px">43</td> <td class="south bar" style="height:198px">32</td> </tr> <tr id="q4"> <th scope="row">Q4</th> <td class="north bar" style="height:111px">18</td> <td class="south bar" style="height:198px">32</td> </tr> </tbody> </table>
在这段代码没有什么特别之处,只不过注意一下scope=”row”,一般情况下,表头应该使用<th>来指明,不过当<th>既是表头又是表格数据的时候,就要使用scope加以说明 。scope属性通常可以连接表格数据单元格和表头,它有四个属性值row、col、rowgroup、colgroup分别代表定义行表头、列表头、行组的表头和列组的表头。转载请注明本文出自http://www.dudo.org/
二、定义总体样式
首先还是设定等宽字体、字号、默认空白等
* {margin:0; padding:0;} body {padding:0;margin:40px;font-size:9pt;font-family:Helvetica,Geneva,sans-serif;}
这段代码的意思很简单,不用过多解释。
和前面几节一样,我们应用的重点还是相对定位和绝对定位的知识。首先我们设定整体table的样式:
table#q-graph { width:600px; height:300px; caption-side:top; border:2px solid #0063be; background:#adfe12 url(fade-light.png) repeat-x scroll 0 0; position:relative; border-collapse:collapse; display:block; /*for Firefox*/ }
这段代码很简单,没有特殊要说明的地方,只不过在Firefox对Table进行相对定位后需要设置display:block,Internet Explore下不存在这样的问题。同时border-collapse:collapse;设置相邻单元格共用一个边框。
此外,对于table的默认样式,Firefox和Internet Explorer的解释是不同的,包括他们的位置和宽度都,因此要统一设置:
table#q-graph caption { width:100%; position:absolute; top:-20px; }
注意:在Internet Explore中,这实际上无法改变caption的位置(只接受正的top值),我们只是让Firefox中的caption和IE中效果相同。转载请注明本文出自http://www.dudo.org/
点击此处查看运行效果
三、接下来,我们要按照季度分类
根据XHTML中的设计,我们使用<tr>来代表季度,<td>代表南北区域,<th>代表<td>中内容属于哪个<tr>。同时我们还注意到,我们不能直接为<tr>设定边框样式,因为它没有边框(只有<table>、<td>、<th>等有)。不过我们可以为<th>设置一个边框:
table#q-graph tbody tr,table#q-graph tbody th { position:absolute; width:150px; height:296px; vertical-align: top; bottom:0; border-right:1px dotted #41a3e2; }
这段代码没有什么特别要说明的地方,如果你对选择符(逗号“,”空格等)的应该还不是很了解,请查看相关文章。
现在四个<tr>元素都重合在了一起,我们使用绝对定位把它们在同一行上分布:
tr#q1 {left:0;} tr#q2 {left:149px;} tr#q3 {left:298px;} tr#q4 {left:447px;border-right:none;}
四、进一步设定<td>样式
前行让所有的单元格底部对齐:
td.bar{ position:absolute; text-align:center; width:34px; bottom:0; z-index:2; }
然后设置背景和位置:
td.north { left:36px; background:#ddd url(bars_v.gif) no-repeat 0 0; } td.south { left:80px; background:#ddd url(bars_v.gif) no-repeat -34px 0; }
五、对于<thead>的处理
<thead>是用来看作图例的,我们只需要把它放在表格一侧即可。为了让它们也有相应的背景,我们可以在上面这段css代码的td.north和td.south前面分别加上 th.north和th.south,有半角逗号(,)隔开即可。下面使用CSS来改变<thead>的位置:转载请注明本文出自http://www.dudo.org/
table#q-graph thead tr { bottom:auto; left:100%; margin:-2.5em 0pt 0pt 5em; top:50%; position:absolute; } table#q-graph thead th { width:34px; position:absolute; left:0; height:auto; color:#fff; } table#q-graph thead th.north {top:30px;}
- 把<thead>移到一侧,我们使用也是绝对定位,设置left:100%,如果不想使它紧挨表格,可以再通过margin来设置。当然也可以直接使用left:105%等来设置;
- bottom:auto;是取消从父元素继承来的bottom:0的属性。
- top:50%是用来设置垂直居中的。一般来说,绝对定位中使用top:50%是使上边缘正好处于垂直居中的位置,我们还要使用负的margin值来上移一半的高度使整个元素垂直居中。这也是我们在页面布局经常用到的一种元素居中方法;
至此我们柱状图效果基本完成了。但是在Internet Explrore中,我们发现柱状图的底部并没有和表格实际对齐,这是因为在IE中默认表格样式中边框和内容之间留有一定的空白,我们可以通过设定<table>的CSS属性border-spacing:0来实现,不过可惜的是Internet Explorer中并不起作用,所以我们还要直接为<table>元素增加一个cellspacing的属性,即<table id=”q-graph” cellspacing=”0″>…</table>
点击此处查看运行效果
六、接下来,我们还可以再加点点缀
在前面的例子中,我们使用实现了比例尺的效果。这里我们两样可以实现这样的效果。在<table>元素的后面添加一个无序列表:
<ul id="ticks"> <li><p>50</p></li> <li><p>40</p></li> <li><p>30</p></li> <li><p>20</p></li> <li><p>10</p></li></ul>
当然你也可以使用<div>实现这样的结构,不过语意不够好。
下面我们设置一下它的位置和样式:
ul#ticks { list-style-type:none; width:600px; position:relative; top:-300px; } ul#ticks li { border-top:1px dotted #41a3e2; height:59px; } ul#ticks li:first-child { border:none; } ul#ticks li p { position:absolute; left:100%; }
注意:这里我们对<ul>使用了相对定位,相对定位和绝对定位的区别就是它们定位的参照物不同,相对定位使用的是与其相邻的元素,绝对定位使用的是父元素。转载请注明本文出自http://www.dudo.org/
我们两次使用到了伪类:first-child,如果你还不了解相关伪类的使用,你可以查看这篇文章。
点击此处查看运行效果
七、最后处理
由于IE6不能使用PNG透明效果,因此我们还针对它做一个!important的CSS hack:
table#q-graph { background:#adfe12 url(fade-light.png) repeat-x scroll 0 0 !important; background:#adfe12 repeat-x scroll 0 0; }
针对Internet Explore错位问题:
td.bar { bottom:0; .bottom:2px; }
不过还有一个问题,就是在Internet Explorer中无法很好解决图层的顺序问题,在Firefox下效果比较理想。
点击下载并查看最终效果
那个IE下标尺怎么置于柱状图下面呢?
[回复]
打印预览时看不见东西 [reply=dudo,2009-04-25 09:30 PM]的确,这样的设计是在Web中表现,如果要打印的话要加上 media="print" 这个属性,否则打印机看到不到所有的CSS设置[/reply]
[回复]