当前位置: 代码迷 >> HTML/CSS >> 网页排字,表格已死,图片文字排列CSS,DIV+CSS长存
  详细解决方案

网页排字,表格已死,图片文字排列CSS,DIV+CSS长存

热度:618   发布时间:2013-12-02 12:00:40.0
网页排版,表格已死,图片文字排列CSS,DIV+CSS长存
网络标准计划(?WaSP?)中的浏览器升级行动(?BUI?)已经促使许多设计人员朝着更加标准化的网页设计方向前进。使用CSS而不是表格来为网页布局能够节省用户带宽,同时增强页面的底层语义,可访问性及其范围。

“表格已死...”

已经有几位设计师在Jeffrey Zeldman的?引领?下发表了一些指南,这些指南曾经帮助我们度过无表格设计的困难时期。最初的努力主要是集中在通过CSS定位(CSS positioning)来代替表格创建两个或者更多的列。因此需要考虑一个(完全)不同的显示结构。这些边框技术已经被编辑为文档,你可以在Eric Costello 的网站?glish?以及Rob Chandanais 的网站?Blue Robot?上找到。

其它一些站点也有参与,包括Owen Briggs 的?方盒课程(Box lesson) 以及?由Eric Costello 撰写,Tantek ?elik 解释?的?方盒模型工作区?(box model hack/workaround)。Dotfile?列出了上百个使用CSS布局的站点。

“...表格长存”

当这些卓越的资源都在致力于仅用CSS定位来创建总体布局这一重点时,作为设计师的我们也发现了另一些很实际的问题。这些在表格中能轻易解决的问题,对CSS来说却不那么明显。这样的问题在?Webdesign-L?列表中以主题“表格已死 ... 表格长存”发表。

问题所在

假设你有一大堆的缩略图,每一张都链接着这幅图片的原始大小版本?―?这是一种相当普遍的网页。进一步假设,每一张图片都有一个简短的标题,你希望它们居中于图片下方。并且,考虑到浏览器窗口的大小问题,你希望将这些图片和标题成对出现,按行排列在屏幕上。但是,还必须能够随着浏览器宽度的改变而自动换行(流动式设计)。由于这最后一条要求,我们必须放弃使用表格,而运用CSS。

步步为营

让我们一步一步地来看。首先是要求缩略图的下方有居中的标题。这一步相对简单:找到HTML代码中放置图片的部分,添加换行,然后将标题放在居中对齐(用CSS实现)的段落里。

接下来要将这些图片和标题成对地排列在浏览器的窗口中。如果使用表格,每一对图片和标题将进入一个独立的单元格,而使用CSS我们需要把它们放进独立的层中。为了使它们在窗口中水平排列,只需在样式表中将层的浮动属性设置为向左浮动。

这段CSS代码应该是这样的:

div.float {
  float: left;
  }
  
div.float p {
   text-align: center;
   }

HTML代码如下:

<div class="float">
  <img src="/image1.gif" width="100" height="100"
  alt="image 1" /><br />
  <p>caption 1</p>
</div>

<div class="float">
  <img src="/image2.gif" width="100" height="100"
  alt="image 2" /><br />
  <p>caption 2</p>
</div>

<div class="float">
  <img src="/image3.gif" width="100" height="100"
  alt="image 3" /><br />
  <p>caption 3</p>
</div>
在浏览器中显示如下:

image 1

image 2

image 3

caption 1

caption 2

caption 3

?

接下来的要求只能用CSS来解决。如果图片/标题超出了浏览器窗口所能显示的范围,我们就希望它换行。层的这一向左浮动的属性已经解决了这个问题。如果将这些示例缩略图重复两次,它们就会在浏览器窗口中换行。


image 1

image 2

image 3

image 1

caption 1

caption 2

caption 3

caption 1

image 1

? ? ?

caption 1

?

?

?

现在,假设在页面上显示的不止一种缩略图,你希望通过背景和/或边框将它们从视觉上区分开来。那么只需将它们包在一个容器层(container DIV)之内即可:

div.container {
  border: 2px dashed #333;
  background-color: #ffe;
  }

但是我们这样做时会碰到一个问题。当你在CSS中将一个元素设置为浮动时,它不再占据任何“空间”并且背景和边框将显示在这些图片上方而不是围绕在它周围。我们需要在容器层中插入一些除浮动层之外的元素。例如间隔层(spacer DIV)。

div.spacer {
  clear: both;
  }

HTML代码如下(注意容器层内上下各有一个间隔层):

<div class="container">
<div class="spacer">
  &nbsp;
</div>

<div class="float">
  <img src="/image1.gif" width="100" height="100"
  alt="image 1" /><br />

  <p>caption 1</p>
</div>

<div class="float">
  <img src="/image2.gif" width="100" height="100"
  alt="image 2" /><br />
  <p>caption 2</p>
</div>

<div class="float">
  <img src="/image3.gif" width="100" height="100"
  alt="image 3" /><br />
  <p>caption 3</p>
</div>

<div class="spacer">
  &nbsp;
</div>
</div>

显示效果如下:

?

image 1

image 2

image 3

caption 1

caption 2

caption 3

?

基于?Sam Marshall?的代码。

层的嵌套与表格的嵌套之间的区别

现在我们已经有了不少嵌套的层。那么嵌套层究竟是如何优越于嵌套表格的呢?答案在于标记符(tag)的使用方式。这些层意味着一个逻辑的,结构的分组。即使它们是嵌套的,但它们仍然保持着标记的结构性。在我们的示例中,首先将图片与标题组合在一起(第一个层次),然后再将这些成对的图片/标题和与之类似的成对的图片/标题组合在一起(第二个层次)。这些都是运用层标记符出色地解决结构化分组的例子。

然而,表格意味着列首和/或行首与单元格中数据的一种关系。当我们表格用作布局的时候,它就失去了结构化的语义。我们现在还得返回来使用HTML代码进行布局。嵌套表格只会使问题变得更复杂。

窗体与功能

另一种常用的表格布局是将窗体元素和它们的标签排列整齐。这可能会引起争论 - 在这里用表格是恰当的。而我下面所介绍的CSS技术将证明,样式表在类似的设计中是非常有用的,请看下面的例子。

典型的窗体布局是这样的,左侧是右对齐的标签,右侧是左对齐的窗体元素,它们在中间相遇:

Name:
Age:
Shoe size:
Comments:
?

基于?Eric Meyer?的原始代码概念。

上方的窗体中并没有使用表格。我们再一次使用浮动属性来完成位置的设定。窍门是:创建一个层,它的用途类似我们过去在表格中常使用的行。接着,我们还要制作两个SPAN,一个用作标签,另一个用作窗体元素。设置标签SPAN为左浮动,窗体元素SPAN为右浮动。标签SPAN的文字右对齐,窗体元素SPAN的文字左对齐。

CSS如下:

div.row {
  clear: both;
  padding-top: 10px;
  }

div.row span.label {
  float: left;
  width: 100px;
  text-align: right;
  }

div.row span.formw {
  float: right;
  width: 335px;
  text-align: left;
  } 

在本例中,上面的样式表给出了这些SPAN的宽度。宽度可以是绝对值或百分比。用百分比表示时,总宽度应为100%或略小,这要根据内补丁(padding)和边框(border)的属性(以及你所设计的方盒模型)来确定。在本例中,我把窗体封装在另一个层中并给它添加了背景和边框。

代码如下:

<div style="width: 350px; background-color: #cc9;
border: 1px dotted #333; padding: 5px;
margin: 0px auto";>
  <form>
    <div class="row">
      <span class="label">Name:</span><span
class="formw"><input type="text" size="25" /></span>

    </div>
    <div class="row">
      <span class="label">Age:</span><span
class="formw"><input type="text" size="25" /></span>
    </div>

    <div class="row">
      <span class="label">Shoe size:</span><span
class="formw"><input type="text" size="25" /></span>
    </div>
    <div class="row">

      <span class="label">Comments:</span><span
class="formw">
        <textarea cols="25" rows="8">
        Go ahead - write something...
        </textarea>
      </span>
    </div>

  <div class="spacer">
  &nbsp;
  </div>
 </form>

</div>

居于最突出位置

你也许已经注意到了,容器层的样式属性中包含下列这条:margin:0px auto;?。在标准兼容的浏览器中,这一属性将使得400象素的容器层居中。另一些浏览器,如Windows的IE5.x则会忽略它,但文字居中这一属性却会(错误地)将层居中显示。为了让层在这些浏览器中居中显示,你可以通过将文字对齐属性设置为居中来使一个层居中,再将其内部的层的外补丁设置自动(并且文字左对齐这样文字才能正确显示)。关于居中的?这一?/?其它?技术,请参考Rob Chandanaisde 的站点 Layout Reservoir。

折中的办法

一种典型地用表格来完成的类似布局在本质上与上面的方法是相反的。你可能希望将两个元素分别置于浏览器窗口的两侧,而不是中间。这样的情况很常见,比如当你有一个小LOGO,想将它放在你的网页的右上角时,或是将一些导航元素放在左上角:

?
Home?>?Products[logo]
?

这里我们将使用同样的层和行,但是不同的SPAN。左侧的SPAN向左浮动,并且内容文字左对齐。右侧的SPAN向右浮动,内容文字右对齐。

CSS:

div.row span.left {
  float: left;
  text-align: left;
  font-weight: bold;
  color: #fff;
  width: 49%;
  }

div.row span.right {
  float: right;
  text-align: right;
  font-weight: bold;
  color: #fff;
  width: 49%;
  }

CSS帮助

ACRONYM(首字母缩写)和ABBR(缩略语)这两个标记符是非常有用的,如果几乎用不到,则是通过TITLE属性来扩展首字母缩写或缩略语。现在的大部分浏览器?并不提醒访问者们,页面文字背后存在着一些用于帮助理解首字母缩写和缩略语的注释。让我们来看看CSS如何。

在样式表中,你可以为这些标记符添加下边框,以吸引页面访问者的注意力。同时可以利用CSS将鼠标指针变成“帮助”状态(通常是一个问号),当然,浏览器必须支持。你不会被HTML的标记符所限制。创建一个名为.help的类并且利用SPAN为那些迷惑的读者们提供更多的信息。

CSS?如下:

abbr, acronym, .help {
  border-bottom: 1px dotted #333;
  cursor: help;
  }

... 用来协助?标题属性TITLE attribute)为缩略语或首字母缩写标记符添加下划线,而又要不同于超链接的下划线。将指针变成“帮助”状态意味这些字是不可点击的,标题属性则是将缩略语或首字母缩写展开。我第一次看到这样的效果是在站点?Sander Tekelenburg?上。

二次检查...

我第一次读到有关将列表内嵌显示的文章是在 Bos 和 Lie 的?Cascading Style Sheets?一书中。而第一次看到它应用是在 Christopher Schmitt 的网站?Babble List website?。这个技巧是让列表内嵌或水平显示。代替了:

  • Item one
  • Item two
  • Item three

而得到:

  • Item one?
  • Item two?
  • Item three

加入了内补丁和边框的效果:

  • Item one
  • Item two
  • Item three

CSS:

li.inline {
  display: inline;
  padding-left: 3px;
  padding-right: 7px;
  border-right: 1px dotted #066;
  }

li.last {
  display: inline;
  padding-left: 3px;
  padding-right: 3px;
  border-right: 0px;
  } 

HTML:

<ul>
<li class="inline">Item one</li>
<li class="inline">Item two</li>
<li class="last">Item three</li>
</ul> 
  相关解决方案