• 依原始码顺序排列的栏段


    依原始码顺序排列的栏段
    (Source Ordered Columns)

    返回 p.i.e.


    你想要三栏式的版面(three column layout),而且页尾(footer)部分应该在所有栏段(column)的下方。不需要太华丽的技巧,只要一个固定的(static)栏段,两个分别往左右浮动的(float)栏段,再来就是有“清除(clear)”属性的页尾。最长的栏段就会把页尾推到底下去。

    然而浮动的栏段一定得放在固定的栏段前面,导致中间固定的栏段在原始码里会是最后的那一个。这点很讨厌,因为一旦不靠 CSS(例如使用文字接口浏览器),栏段就不会依正确顺序显示。比较具有亲和力的(accessible)方式应该是把栏段依洽当的原始码顺序排列,再强制它们依你想要的顺序显示在屏幕上。但是该怎么样做呢?

    答案是我们可以靠一点额外的浮动小把戏来做到。
    看到下面那些上了色的栏段吗?

    二号标头 <h2>

    One One One One One One One One One One One One One One One One One One One One One One One One One One One One
    Test link

    Two Two Two Two Two Two Two
    Test link

    Three Three Three Three Three Three Three Three Three Three Three
    Test link


    三号标头 <h3>

    One One One One One One One One One One
    Test link

    Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two
    Test link

    Three Three Three Three Three Three Three Three Three Three Three
    Test link


    三号标头 <h3>

    One One One One One One One One
    Test link

    Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two Two
    Test link

    Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three
    Test link

    页尾 (p.clearfooter)

    如果你偷瞧瞧原始档,就会注意到栏段的排列顺序跟屏幕上完全一样。也就是左边的栏段在最前面,右边的栏段在最后面。以上的三组栏段除了里面字数不同外,是完全一样的。注意页尾部分总是留在最长栏段的下方。

    做法

    做法就是在原始码里把前两个栏段(蓝色跟绿色)用向左浮动的区块包起来,并让第一个字段(蓝色)也向左浮动。

    懂了吗?因为容器是浮动的,(根据浮动组件的特性)要摆在原始码前面的位置。而容器里的第一个栏段也是浮动的,所以变成原始码里最先出现的栏段。接着是容器里的另一个栏段(中央绿色那个),以及接在容器后面的右方栏段(红色)。

    再仔细想想

    就这样来说,其实第一个栏段不见得要向左浮动。我们大可以让它改为向右浮动(得配合第二个栏段的边界(margin)设定),这样第一栏段(.first-col)就会被放到中央位置,第二栏段(.second-col)在左边,第三栏段(.third-col)在右边,听起来非常不错。

    二号标头 <h2> 范例在单一页面的运作状况

    One One One One One One One One One One One One One One One One One One One One
    Test link

    Two Two Two Two Two Two Two
    Test link

    Three Three Three Three Three Three
    Test link


    页尾 (p.clearfooter)

      上述“2 1 3”范例的极简版 HTML:
    
    <h2>Header</h2>
    
       <div class="float-wrapper">
    
         <div class="first-col">
    
        <p>One One One One One One One One One</p>
    
         </div>
    
         <div class="second-col">
        <p>Two Two Two Two Two Two</p>
    
         </div>
    
       </div>
    
     <div class="third-col">
    <p>Three Three Three Three Three</p>
    
     </div>
    
    <p class="clearfooter">Clearing Footer</p>
    
    
      CSS 部分:
    
    .float-wrapper {float: left;  66%;}
         /*** This can be floated left or right ***/
    
    
    .first-col {float: right;  50%;}
         /*** This can be floated left or right ***/
    
    
    .second-col {margin-right: 50%;}
         /*** This gets margined the same direction 
            as div.first-col gets floated ***/
    
    .third-col {margin-left: 66%;}
         /*** This gets margined the same direction 
           as div.float-wrap gets floated ***/ 
    
    .clearfooter {clear: both;}
    
     p {padding: 10px;}
    

    你必须要知道

    你可以靠着决定第一个栏段(.first-col)的浮动方向,来选择要让第一栏段(.first-col)或第二栏段(.second-col)放置在屏幕的中央位置。另外,如果把容器(.float-wrapper)也掉换个方向,栏段在屏幕上的顺序就可以是 3, 2, 1 或 3, 1, 2。

    如果你想修改栏段的宽度(width),记得也要修改没有浮动的第二栏段及第三栏段的边界(margin)设定,以符合相对应的浮动组件宽度。(见上面的程序代码)

    我在栏段里使用了段落卷标 <p>,这不仅是要让它较具亲和力(accessible),也因为要把边界(margin)、边框(border)或补白(padding)等属性套用在栏段上是很“困难”的。别让我阻止你去闯出条路,但是先搞清楚,这会让你掉进各家浏览器差异、臭虫的泥沼,还有最麻烦的 IE 区块模块(box model)里。大伙,我谈的可是骇客之城(Hack City),去那得要张大眼睛。要不然,还是乖乖地用巢状的 <p>(或其它的)卷标来维持与设计栏段的内容吧。

    在 <p> 卷标上套用补白(padding)、边框(border),以及水平方向边界(margin)属性多半没有问题,但是垂直方向的边界(margin)就会随浏览器的不同而有所差异,必须靠着剖析(hacking)原始码来维持一致性。在 Windows 环境的主要浏览器里,唯有 Opera 6 能让垂直边界显示正常。Opera 7/beta 则没办法做到。

    当这些范例有设定背景(例如绿色)时,IE 6 会呈现得非常怪。解决方法是在特定组件上加上“position: relative”属性,详细的做法可以查阅原始档。此外如果使用 Mozilla 与 Netscape 6/7 看前面两个范例,有时候第二栏段与第三栏段之间会有 1px 的空隙,这是“舍入误差(rounding errors)”造成的。我已经调整过栏段的宽度(width)跟边界(margin),不会在主要分辨率(resolution)出现空隙,但是在某些屏幕宽度仍会冒出来。我以后会用范例说明这个现象。

    危险!威尔鲁宾逊!危险!危险......
    (译注:这是“LIS 太空号”里的台词)

    这个版面包含浮动组件,而浮动组件在尺寸过大时会自动换行(wrap),导致版面支离破碎。因此当栏段里的内容太宽时,产生的结果就会让人“不大愉快”。Opera 以及用 Gecko 为核心的浏览器(如 Netscape 6/7 等)会直接把过宽的内容叠在右边的组件上;IE 则不会(这种做法也没什么错)。

    当 IE/win 遇到容器里的内容过宽的时候,会不恰当地把容器“放大”。这通常只是让人觉得讨厌而已,但在这个例子里,放大栏段会导致浮动组件自动换行,对三栏式版面造成破坏性的大浩劫。IE5/mac 也会造成版面破碎,不过它的方式更怪异。因此在加入非文字内容时得非常小心。过长的网址里没有空白让文字换行,也常常导致这类问题。

    IE 里文字凸出的 3px 落差真难看

    如果你实作了这个版面,也许会注意到(在 IE 里)文字靠左对齐的部分有点奇怪的小缺陷。当文字区块的左侧边界(margin)撞到栏段时,它会忽然向左凸出,造成难看的“文字干扰(disturbance in the font”,我有准备范例来详细说明。本质上来说,一个非浮动的组件接在浮动组件后面时,就有可能会凸出来。

    这个问题似乎可以轻松地对第二栏段及第三栏段套用“ 100%”来解决(但前提是没有设定边界(margin))。IE 会用固定的(static)栏段填满紧邻浮动组件造成的空间,这次不会再凸出了。

    但是不幸地,这种做法完全违背 W3C 规格(specification)关于浮动组件的描述。所以如果你用了这种语法,其它试图分析它的浏览器都会发生问题。我在另一个范例描述了IE 的不当行为
    (IE 可真惹人厌)

    就只能这样?让 IE 宣告获胜?

    当然不是!幸好我们有办法来避免这些 IE 特有的情况。只要把栏段都换成浮动组件就好了。哇,那还不简单!老实说不是这么容易啦,不过是个行得通的方法。

    制作全部浮动的三栏式版面

    因为浮动组件会导致 3px 的凸出,却并非显示在浮动组件身上,所以让所有栏段一起浮动就可以避免掉整个问题。构想是让第一栏段跟第二栏段往相对的方向浮动,并把它们放在同一个浮动容器里,再让第三栏段与这个容器往相对的方向浮动。一旦所有组件都浮动的时候,就没有哪个“固定的”栏段得摆在最后面,所以任何栏段都可以出现在屏幕任意位置。你有完全的支配权。

    然而这种支配权是有代价的。跟固定的栏段不同,浮动组件必须要设定“宽度(width)”。如果组件全都像上述范例般地使用百分比作为宽度的单位,有些浏览器会不洽当地自动换行。原因是百分比(以及 <em>)的“舍入误差(rounding errors)”可能会让组件的宽度多了 1px,而导致自动换行。

    所以栏段必须缩短宽度以避免自动换行,但是这样会产生栏段之间的小间隔(gap)。如果栏段没有设定背景的话,那些间隔应该不会被注意到,而凸出的 3px 已经消失了。一切都维持原状。

    注意:纯粹因为个人喜好,我在这个范例(.demo-allfloat)里加入了边框跟边界(请看下方附注里对于在 IE5.5 里使用边框及边界的警告)。

    二号标头 <h2> 范例在单一页面的运作状况

    One One One One One One One One One One One One One One One One One One One One One One One One
    Test link

    Two Two Two Two Two Two
    Test link

    Three Three Three Three Three
    Test link

    页尾 (p.clearfooter)

      上述“全部浮动(all-float)”范例的极简版 HTML:
    <h2>Header</h2>
    
       <div class="float-wrapper">
    
         <div class="first-float">
        <p>One One One One One One One One One</p>
    
         </div>
    
         <div class="second-float">
    
        <p>Two Two Two Two Two Two</p>
         </div>
    
       </div>
    
     <div class="third-float">
    
    <p>Three Three Three Three Three</p>
     </div>
    
    <p class="clearfooter">Clearing Footer</p>
    
    
      CSS 部分:
    
    .float-wrapper {float: left;  66%;}
         /*** This can be floated left or right ***/
    
    .first-float {float: right;  49%;}
         /*** This must be floated opposite 
                to .second-float ***/
    
    
    .second-float {float: left;  49%;}
         /*** This must be floated opposite 
                to .first-float ***/
    
    .third-float {float: right;  33%;}
         /*** This must be floated opposite 
                to .float-wrap ***/ 
    
    .clearfooter {clear: both;}
    
     p {padding: 10px;}
    
    

    你必须要知道

    如果你想把第三栏段放在屏幕中央位置,只要改用容器包住第二栏段跟第三栏段,而非原本的第一栏段及第二栏段。接着只要配合洽当的浮动方向,就可以轻松地让第三栏段放在中央。

    为了配合 IE,这个全部浮动的版面需要修掉两个臭虫。首先为了避免 IE6/win 的臭虫,必须在范例本身上套用“position: relative”属性。但这样做又会导致更多的臭虫,所以得在容器跟第三栏段上加上“position: relative”属性(请看原始文件)。

    其次是在 IE5.x/win 下会出事,因为对它来说“auto”的预设宽度就是“检视区宽度(viewport width)”。这个范例里可以套用“ 100%”来处理,但是要注意!IE6 遇到这个会出事,所以“100%”只能用在 IE5.x/win 上。这可以利用一些手段来解决(请参考原始档)。如果两侧没有设定边框跟边界,就不必用上这些方法。

    因为这个版面用上了双向的巢状浮动组件,在日后要增加浮动组件或定位组件(positioned element)时就得小心点,以免又招来一堆可怕的臭虫。你得要测试、测试、再测试。

    你说你想用“像素尺寸(pixel sized)”制作版面?

    当然没问题!事实上制作“精准的”版面可以解决上个例子里的小间隔问题。我再次地修改了版面里栏段的宽度值来证明这件事。看看吧。

    二号标头 <h2> 范例在单一页面的运作状况

    One One One One One One One One One One One One One One One One One One One One One One One One One One One One One One One One One One One One One
    Test link

    Two Two Two Two Two
    Test link

    Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three Three
    Test link

     

    页尾 (p.clearfooter)

    上述“rigid-all-float”范例的极简版 HTML:
    
      <div class="rigid">
    
    <h2>Header</h2>
    
       <div class="float-wrapper-rigid">
    
         <div class="first-float-rigid">
        <p>One One One One One One One One One</p>
    
         </div>
    
         <div class="second-float-rigid">
    
        <p>Two Two Two Two Two Two</p>
         </div>
    
       </div>
    
     <div class="third-float-rigid">
    
    <p>Three Three Three Three Three</p>
     </div>
    
    <p class="clearfooter>Clearing Footer</p>
    
      </div>
    
      CSS 部分:
    
    .rigid { 600px; margin: 0 auto;}
    
    
    .float-wrapper-rigid {float: left;  450px;}
         /*** This can be floated left or right ***/
    
    .first-float-rigid {float: right;  300px;}
         /*** This must be floated opposite 
                to .second-float ***/
    
    .second-float-rigid {float: left;  150px;}
         /*** This must be floated opposite 
                to .first-float ***/
    
    
    .third-float-rigid {float: right;  150px;}
         /*** This must be floated opposite 
                to .float-wrap ***/ 
    
    .clearfooter {clear: both;}
    
     p {padding: 10px;}
    
    

    你必须要知道

    如果页尾有设定背景的话,IE5.5 跟 IE6 遇到上述“宽度精准”的版面就会出现不少臭虫,就算套用“透明(transparent)”或“继承(inherit)”属性也无法避免。这可以藉由在第三栏段、页尾之间放个“行内区块(line box”解决,也许是一个 <p> 卷标或是包含至少一个行内组件(inline element)的 div。

    不过这种精准的版面不会遇上之前提到的 IE “背景范例”臭虫,所以你大可在版面里加入背景,而不必为 IE6 做什么特殊处理,这得感谢这个范例里的“宽度设定”。

    在“符合标准(standards compliant)”的浏览器里,把 div.rigid 的两侧边界设为“auto”可以让这个范例置中对齐,但是 IE5.xwin 可不遵循这些,所以我得利用“text-align”来强制浏览器把这个范例置中。IE5.x/win 也有个声名狼藉的“区块模块问题(box model problem)”,如果我没有用点小技巧的话,两侧放的装饰边框就会让栏段的自动换行。
    (你可以在原始档里看到这些技巧的细节)

    你有没有对于老是因为“那个浏览器”而出问题而感到厌倦啊?大伙,让我们欢迎“Navigator 4”。

    说起 Navigator 4.......

    我猜有些人会想知道这些三栏式版面是否能在 Navigator 4 里正常运作。答案是“或多或少吧”。我有另外准备一个能在 Navigitor 4 里运作的范例,只是请别要求太多。

    我努力尝试着让 Navigitor 4 的表现能令人满意,但是失败了。以百分比为尺寸的版面的确可以运作,但是栏段间的水平间隔会依据屏幕尺寸做出令人费解的变动。我相信 Navigitor 4 只能靠着大量的步骤来表现用百分比做基础的浮动组件宽度。那就是说,当屏幕尺寸渐渐缩小时,间隔也会越来越小,当区块终于接触到的时候,就赶紧让区块的尺寸缩小一点。如此一来栏段间就可以显示间隔。

    当然,企图在这种情况下改变栏段尺寸,充其量不过是种冒险的行为。栏段确实依照正确的顺序,也大约是在一样的高度,但是“间隔”只能在一到两种(如果你运气好)特定的屏幕尺寸下被排除。

    像素尺寸的版面有也有自己的重设尺寸(re-sizing)问题,因为当屏幕缩小时,浏览窗口不会出现滚动条(scrollbar);更确切地说,一直要到第三栏段被“挤压(squeezed)”成剩下一个“字(word)”宽时,水平方向的滚动条才会出现,一切都太迟了。

    如果你要得配合 Navigitor 4 的话,请使用百分比的方式,并且与易变的间隔和平相处。另外要记得,对 Navigitior 4 适用的数值未必也适用在其它浏览器上,而必须做些处理来达到类似的效果。

    研究 & 发展

    这个范例甚至在正式发表前就快要过时了!(我为此感到自豪)
    Alex Robinson 的网站已经有些这个范例的变种程序代码。快去那里看看,并且试着戳看看他的版面有没有漏洞。Alex 会希望你这样做的。(我正在做呢......)

    如果你根据这个版面的概念写了个很酷的新版本(就像 Alex),而且觉得应该在这里放个连结,请联络我好吗? :-)

    结论

    请知道,这页里的版面制作细节都非常新,也还没有对各种应用上的变化做过广泛测试。我相信在测试之后,许多问题都会冒出来,所以得告诫你用“一步步来”的态度来面对。从最基本的版面开始着手,加入你要的东西,并注意因此产生的臭虫。

    另外当你要把既有的三栏式版面转换成这一个,却遇上些神秘的臭虫时别太惊讶。
    (注意喔,我可没说“......IE 神秘的臭虫”,因为我实在没把握......)

    这个让栏段依原始码顺序排列的方法可以延伸到三栏以上,只要用第二个浮动容器把第三栏段跟第四栏段包起来就可以了。所以会变成这样:[{1 2} {3 4}],或是其它类似的排列方式。祝你玩得愉快!

    这项依原始码顺序排列的三栏式技术在符合标准的浏览器里似乎是够结实(robust),一旦那些比较差的浏览器被历史埋没之后,我认为这些方法将会被广泛地采用。

    贡献者

    喔,我知道你在想什么:“Big John 这家伙真是天才!”唔,是没错啦,但这页里大部分是 css-discuss list 里其它人们慷慨提供的辛苦作品,包括(但不仅是)Scott SauyetDouglas LivingstoneVictor CastonAlex RobinsonMike Papageorge,以及 Holly Bergevin。在这个邮递论坛(e-list)里常常会有很棒的合作作品。

    我得要特别感谢Holly Bergevin,他说服我花时间去制作这个范例,给我非常多的协助,也展现出“打死臭虫”方面的天份。 :)


    原作者:
    Big John   e-mail ©positioniseverything
    最后更新日期: Febuary 5, 2003
    Created Groundhog Day (Feb 2nd), 2003

    繁体中文翻译:hlb
    简体中文翻译: onestab


  • 相关阅读:
    .NET Core技术研究-通过Roslyn代码分析技术规范提升代码质量
    ASP.NET Core技术研究-全面认识Web服务器Kestrel
    .NET Core技术研究-主机Host
    ASP.NET Core技术研究-探秘依赖注入框架
    ASP.NET Core技术研究-探秘Host主机启动过程
    .NET Core技术研究-中间件的由来和使用
    深入浅出腾讯BERT推理模型--TurboTransformers
    深入浅出PyTorch(算子篇)
    深入浅出Transformer
    生产者消费者问题总结
  • 原文地址:https://www.cnblogs.com/fuyingke/p/113571.html
Copyright © 2020-2023  润新知