在網(wǎng)頁(yè)設(shè)計(jì)時(shí),自動(dòng)布局模型盡管沒(méi)有固定布局那么快,不過(guò)對(duì)你來(lái)說(shuō)可能更熟悉,因?yàn)檫@正是HTML 表使用多年的模型。在大多數(shù)當(dāng)前用戶代理中,只要表的width為auto就會(huì)觸發(fā)使用這個(gè)模型,而不論table-layout的值是什么,不過(guò)這一點(diǎn)不能保證。
為什么自動(dòng)布局比較慢,因?yàn)樵谟脩舸頄丝赐瓯淼乃袃?nèi)容之前無(wú)法確定表的布局。也就是說(shuō),自動(dòng)布局要求用戶代理毎得到一個(gè)新單元格時(shí)都完成整個(gè)表的布局。這通常需要用戶代理完成一些計(jì)算,然后再返回頭來(lái)對(duì)表完成第二組計(jì)算。必須充分分析單元格的內(nèi)容,因?yàn)榕cHTML表類(lèi)似,表布局完全取決于單元格的內(nèi)容。如果最后一行一個(gè)單元格中有一個(gè)400像素寬的圖像,就會(huì)要求它上面的所有單元格(同列中的單元格)都是400像素寬,因此,必須計(jì)算每個(gè)單元格的寬度,而且在確定表的布局之前還必須做一些調(diào)整(可能觸發(fā)另一輪內(nèi)容寬度計(jì)算)。
這個(gè)模型的詳細(xì)過(guò)程見(jiàn)以下步驟:
1、對(duì)于一列中的各個(gè)單元格,計(jì)算最小和最大單元格寬度。
a. 確定顯示內(nèi)容所需的最小寬度。要記住,內(nèi)容可以流入多行,不過(guò)不能超出單元格框。如果單元格的width值大于最小可能寬度,則把最小單元格寬度設(shè)豎為該width值。如果單元格的width值為auto,最小單元格寬度則設(shè)置為最小內(nèi)容寬度。
b. 對(duì)于最大寬度,要確定完全顯示內(nèi)容而且不包括換行符所需的寬;度(除非明確要求,例如指出可以有<br>元素),這個(gè)值就是最大單元格寬度
2、對(duì)于各一列,計(jì)算最小和最大列寬。
a. 列的最小寬度由該列中所有單元格的最小單元格寬度的最大值確定。如果為該列指定的width值大于列中所有最小單元格寬度,最小列寬則設(shè)置為這個(gè)width 值。
b. 要計(jì)算最大寬度,取該列中所有單元格的最大單元格寬度的最大值。如果已經(jīng)為列指定了一個(gè)width值,而且大于該列中的所有最大單元格寬度,最大列寬則設(shè)置為該width值。這兩種行為改寫(xiě)了傳統(tǒng)的HTML表行為,對(duì)于HTML 表,會(huì)強(qiáng)制列擴(kuò)展為與其最寬的單元格同寬。
3、如果一個(gè)單元格跨多列,最小列寬之和必須等于這個(gè)跨列單元格的最小單元格寬度。類(lèi)似地,最大列寬之和必須等于跨列單元格的最大寬度。如果列寬之和與單元格寬度有差距,用戶代理會(huì)把這個(gè)差距在所跨的列上平均分配。
另外,用戶代理必須考慮到這樣一個(gè)問(wèn)題:如果一個(gè)列的Width值為百分?jǐn)?shù)值,這個(gè)百分?jǐn)?shù)要相對(duì)于表的寬度計(jì)算,即便它還不知道這個(gè)寬度是多少!它必須把這個(gè)百分?jǐn)?shù)保存起來(lái),在算法的下一部分使用。
此時(shí),用戶代理已經(jīng)確定了各列可能是多寬或多窄。有了這個(gè)信息,可以再真正得出表的寬度。這個(gè)過(guò)程如下:
1、如果表的計(jì)算寬度值不是auto,將這個(gè)計(jì)算表寬度值與所有列寬再加上所有邊框和單元格間隔之和相比較(設(shè)置為百分?jǐn)?shù)寬度的列往往在此時(shí)計(jì)算具體寬度)。二者中較大的一個(gè)就是表的最終寬度。如果表的計(jì)算寬度值大于列寬、邊框和單元格間隔之和,所有列的寬度都會(huì)增加一個(gè)相等的量,使得剛好將表完全填充。
2、如果表的計(jì)算寬度值為auto,通過(guò)將列寬、邊框和單元格間隔相加來(lái)確定表的最終寬度。這說(shuō)明表的寬度只能恰好顯示其內(nèi)容,而不能有多余,這類(lèi)似于傳統(tǒng)的HTML表。設(shè)置為百分?jǐn)?shù)寬度的列會(huì)以這個(gè)百分?jǐn)?shù)作為一個(gè)限制,不過(guò)用戶代理有可能并不滿足這個(gè)限制。
只有在完成了最后一步之后,用戶代理才算真正建立了表的布局。
以下樣式和標(biāo)記有助于說(shuō)明這個(gè)過(guò)程:
table{table-layout: auto; width: auto;
border-collapse: collapse;}
td {border: 1px solid;}
col#c3 {width: 25%;}
#r1c1 {width: 40%;}
#r2c2 {width: 50px;}
#r2c3 {width: 35px;}
#r4cl {width: 100px;}
#r4c4 {width: 1px;}
<table>
<colgroup>
<col id="cl"><col id="c2"><col id="c3"><col id="c4">
</colgroup>
<td id=" r1c1">1-1</td><td id="r1c2 ">l-2</td>
<ta id="r1c3">1-3</td><td id="r1c4">l-4</td>
</tr>
<tr>
<td id="r2c1">5-1</td><td id="r2c2">2-2</td>
<td id="r2c3">2-3</td><td id="r2c4">2-4</td>
</tr>
<tr>
<td id=" r3c1">3-1</td><td id="r3c2">3-2</td>
<td id="r3c3">3-3</td><td id="r3c4">3-4</td>
</tr>
<tr>
<td id="r4c1">4-1</td><td id="r4c2">4-2</td>
<td id="r4c3">4-3</td><td id="r4c4">4-4</td>
</tr>
</table>
下面依次在網(wǎng)頁(yè)設(shè)計(jì)時(shí)考慮對(duì)各個(gè)列會(huì)發(fā)生什么:
對(duì)于第一列,唯一明確的單元格或列的寬度是單元格4-1的寬度,其width指定為100px。由于它的內(nèi)容太短,所以最小和最大列寬都是100px (如果列中一個(gè)單元格的文本有很多句,則要把最大列寬增加到足以不換行顯示所有文本所需的寬度值)。
第二列中聲明了兩個(gè)寬度:?jiǎn)卧?-2的width指定為40%,單元格2-2的width 指定為50px。這一列的最小寬度為50px,最大寬度為最終表寬度的40%。
對(duì)于第三列,只是單元格3-3有明確的寬度(35px),不過(guò)該列本身也指定了寬度,width為25%。因此,最小列寬為35px,最大寬度為最終表寬度的25%。
對(duì)于第四列,只為單元格4-4指定了寬度為1pxs這比最小內(nèi)容寬度小,所以最小和最大列寬都等于單元格的最小內(nèi)容寬度,計(jì)算為25像素。
用戶代理現(xiàn)在知道了,這4個(gè)列的最小和最大列寬如下:
最小100px /最大100px
最小50px /最大40%
最小35px /最大25%
最小25px /最大25px
因此,在網(wǎng)頁(yè)設(shè)計(jì)中,表的最小寬度就是所有這些列的最小寬度再加上邊框之和,總共是215像素。表的最大寬度是130px +65%,最后得出371.42857143像素(假設(shè)130px表示總表寬度的35%)。將這個(gè)小數(shù)取整為371像素后,假設(shè)用戶代理實(shí)際使用的就是這個(gè)寬度。因此,第二列將是148像素寬,第三列將是93像素寬。用戶代理不必真正使用最大值,完全可以選擇其他方案。
當(dāng)然,這是一個(gè)相當(dāng)簡(jiǎn)單直接的例子(不過(guò)看上去可能并非如此):所有內(nèi)容基本上都有相同的寬度,聲明的大多數(shù)寬度都使用像素?cái)?shù)指定。如果表中包含間隔GIF、文本段落。表單元素等,要得出表的布局,過(guò)程可能要麻煩得多。