几种常见布局

Table布局

     经典得一塌糊涂的表格布局,在渐进增强面前落花流水——表格布局要求书写HTML代码时,首先考虑布局,而不是内容。不啰嗦,直接枪毙。

Float布局

  

  优点是简单

  缺点:你的页面是否能够一直保持一致的展现效果将取决于浏览器的实现是否保持一致。特别是当浮动元素是一个更为复杂的布局中的一部分的话,将变得更加不堪一击

绝对定位布局

  

  绝对定位非常简单,非常精准。但面对不可预料的高度时,绝对定位就死翘翘了。

 

  参考:

    文章http://www.shauninman.com/archive/2006/05/22/clearance_position_inline_absolute

    Demo:http://bluerobot.com/web/layouts/layout3.html

负边距布局

  两栏:

  

  

  三栏:

  

  

  这样发现sub、extra、main的bottom不对其,可以用背景图片解决(Dan Cederholm’s “Faux Columns,”: http://www.alistapart.com/articles/fauxcolumns/),详情见参考文。

  但对于三栏布局,Ryan给出的解决方案需要添加额外的包裹层,对DOM结构也依旧存在依赖关系。

  这个方法的最大价值是:开启了负边距的神奇大门,让布局的实现思路立刻活跃了起来。

 

  参考:

    Ryan Brill在2004写了一篇文章:http://www.alistapart.com/articles/negativemargins/

    Demo:http://www.alistapart.com/d/negativemargins/ex5.htm

圣杯布局

  2006年,Matthew Levine开始寻找布局圣杯:In Search of the Holy Grail. 这是一篇让人赞叹振奋的文章。Matthew灵活运用容器的内边距、浮动元素的负边距和相对定位,接近完美的实现了三栏布局。DOM结构也很好,无需额外标签。但是,我们来看看多达27页的评论吧。圣杯布局最令人头疼的是:在IE6下,左栏经常会神奇消失!!!(比如将IE6的窗口高度拖小点)评论中还反馈在IE7下也存在不少问题(我测试后,发现在IE7正式版下没问题,评论中的IE7可能是beta版)。另外在Chrome下表现也有点诡异,需要小小hack. 还有那繁琐的padding, margin, left, right计算,时刻需要一颗清晰的大脑,喝点小酒就彻底晕了……

  2008年11月4日补充:这里又一个改进版的圣杯布局,解决了所有问题,缺点是包裹层太多,唉。

  总之:这是一个很美妙的布局,但在IE6尚未退出历史舞台的当今,圣杯布局可能并不是我们真正要找的圣杯。

  

  

  

  具体步骤:

  1、  首先给一个header、footer、container

  

  给container padding一个我们想要的留出的左右的距离

  

  效果如图:

  

  2、  加入column

    

  添加样式:

   

  效果如图:

  

  3、  给left添加以下样式:

  效果:

  

  将左栏定位在左边的空白位置,添加position:relative;然后定位right:200px;

   

  效果:

   

  4、  将右栏定位到空白处:

   

   效果:

  

  5、  补充:

    当窗口缩小到小于leftWidth+rightWidth时,这个布局就被破坏了,所以给body添加min-width:leftWidth+rightWidth

   

    这时在IE6下,left栏跑到了整个窗口的左边,为了解决这个问题,添加一个left:leftWidth。

   

伪绝对定位布局

  聪明的同行们对完美布局的追求孜孜不倦。2008年我们迎来了奥运。Eric Sol 给奥运的献礼是一个聪明的布局尝试:Faux Absolute Positioning.

  这个布局思路很简单:先相对定位到最右边,再用margin-left移过来。关于这个布局,曾经引发了淘宝UED内部的热烈讨论。若干月后,我和明城在不同的项目中采用了这一方法,结果发现在ie下,某些页面会闪屏(页面加载时能看见左移)。当时项目紧,没细究,上周想重现却怎么也重现不了(明城说页面非常复杂的时候会闪屏,但具体原因没找出来)。今天看原文的评论,有人指出在IE6下,设置背景图会导致这个布局彻底完蛋

  仔细想来,这个布局最让人担心的是:为什么一开始要将所有item都left: 100%? 这个太邪恶了,让人不放心。

“借尸还魂”的Table布局

  乍一看,这个布局很雷人:基于display:table的CSS布局。作者作了解释:在css里使用table-cell之类的声明,仅是声明渲染方式,并不影响HTML文档中的语义。从这个角度讲,这种布局方式的确不错,而且很容易就可以做到等高,也不用考虑清除浮动等扰人的问题。

但是,又是IE成了绊脚石。在IE中,这个布局需要IE8才支持。不过,即便所有浏览器都支持了,我为什么老觉得有点“借尸还魂”的感觉?

双飞翼布局

考虑以下DOM结构:

<div id="page">

    <div id="hd"></div>

    <div id="bd">

        <div class="main"></div>

        <div class="sub"></div>

        <div class="extra"></div>

    </div>

   <div id="ft"></div>

</div>

  利用浮动元素的负边距来定位:

     

 .main {

        float: left;

        width: 100%;

    }

    .sub {

        float: left;

        width: 190px;

        margin-left: -100%;

    }

    .extra {

        float: left;

        width: 190px;

        margin-left: -190px;

    }

   可以看出,通过简单的负边距,已经让sub和extra定位到正确的位置。剩下的问题是如何让main也定位到正确的位置。

  一个自然的想法是,给main的容器#bd添加padding:

#bd {

        padding: 0 230px 0 190px;

    }

  这样能让main定位到正确的位置,但sub和extra的位置不对了。这是一个思考的关卡。既然sub和extra的位置不对,那就想办法调整到正确的位置。相对定位隆重登场:

.sub {

        float: left;

        width: 190px;

        margin-left: -100%;

        position: relative;

        left: -190px;

    }

    .extra {

        float: left;

        width: 230px;

        margin-left: -230px;

        position: relative;

        right: -230px;

    }

  很明显,这就是圣杯布局!

  组合这三种基本技术,我们可以继续尝试各种想法。比如伪绝对定位布局(这个布局不难想到,难的是第一个想到),类似的还有逆伪绝对定位布局(先都移动到最左边,然后再margin-right一个个移过来)等等。

  在不增加任何额外标签的假设上,我尝试了各种想法,但始终都没找到完美的布局实现(圣杯布局是我觉得所有想法中最接近完美的)。

  既然不添加额外标签时,完美布局的实现如此困难,那如果允许添加一个额外标签呢?在淘宝UED内部的探讨中,给main增加了一层包裹:

<div id="main" class="column">

      <div id="main-content">#main</div>

</div>

  里层main-content的作用就是将main定位到合适的位置,并方便设置padding等属性。想到此处,就像牛顿被苹果砸傻了一样,原来的main定位问题迎刃而解:

<div id="page">

    <div id="hd"></div>

    <div id="bd">

        <div class="main">

            <div class="main-wrap"></div>

        </div>

        <div class="sub"></div>

        <div class="extra"></div>

    </div>

   <div id="ft"></div>

</div>

CSS仅需增加一行:

.main-wrap {

    margin: 0 230px 0 190px;

}

  一切如此简单!除了添加了一个额外标签,其它各方面,表现都很完美(试了下IE5.5, 也没任何问题)。目前只用到了浮动和负边距,如果再引入相对定位,还可以实现三栏布局的各种组合:

 .extra {

        float: left;

        width: 230px;

        margin-left: -100%;

        position: relative;

        left: 190px;

    }

    .main-wrap {

        margin-left: 430px;

    }

  仔细查看example5和example4的源代码,可以发现DOM结构是完全一样的,仅仅CSS稍有不同。这意味着HTML结构和CSS布局在一定程度上解耦了,我们开发HTML代码时,从内容出发即可,无需过多的考虑布局。这正是渐进增强在前端工作流程上的体现。

  如果把三栏布局比作一只大鸟,可以把main看成是鸟的身体,sub和extra则是鸟的翅膀。这个布局的实现思路是,先把最重要的身体部分放好,然后再将翅膀移动到适当的地方。因此请容许我给这个布局实现取名为双飞翼布局(Flying Swing Layout.

  就如上图中的鸟有各种姿势一样,利用双飞翼布局,我们也可以实现各种布局。这里有个尝试页面,利用双飞翼,实现了一套栅格化布局系统

  优点

    实现了内容与布局的分离,即Eric提到的Any-Order Columns.

    main部分是自适应宽度的,很容易在定宽布局和流体布局中切换。

    任何一栏都可以是最高栏,不会出问题。

    需要的hack非常少(就一个针对ie6的清除浮动hack:_zoom: 1;)

    在浏览器上的兼容性非常好,IE5.5以上都支持。

  不足

    main需要添加一个额外的包裹层。

    等待你的发现与反馈

  补充

    双飞翼布局的想法与实现受了圣杯布局UED内部讨论的PPT的启发。尝试后发现一切如此简单,都有点奇怪为什么网络上一直没有文章来阐述。

    前些日子主要精力都放在了阅读ALA上的文章,没怎么注意其它信息。昨天才仔细阅读Eric的Any-Order Columns和Alex的One True Layout, 发现这种思路和想法早就有人尝试过了。比如Eric原文中的例子是定宽的,但稍微修改,就可以演化为双飞翼布局。Alex的One True Layout, 给的例子被墙了,就一直没细看,今天才找代理过去瞄了一眼,一瞄不要紧,原来One True Layout就是双飞翼,不过Alex只用到了浮动和负边距,因此没有提及main - sub - extra这种排列的实现。

    此外,中午还有一个非常震惊的发现:Alessandro早做了一个很详细的页面Layout Gala, 列举了40种布局,用的就是双飞翼!

巧合让人有点沮丧,但更让我高兴。因为Alex和Alessandro的工作,证明了这种布局的普适性。因此不用像采用伪绝对定位布局时一样,得担心新技术带来的风险!可以说,双飞翼布局已经是一个成熟的布局,但因为Alex的被墙,以及Alessandro的宣传力度不够,导致这个布局被我重新“发现”了一次。特撰此文,并取名为“双飞翼布局”,希望这个布局能让更多的人知道,并应用于实践中。

伪绝对定位

    首先有一个外容器,id=”canvas”来包含列,也就是栅格中的一行。 canvas用来定义你所需要的宽度。需要有overflow:hidden;(用来计算内容item里面的float元素所带来的高度,同时解决等高列问题)。其中每一行定义为line,我们这里假设他宽度为950px

.line {
 float: left;(计算内容item里面的float元素所带来的高度)
 width: 100%;
 display: block;(float之后自动具有block,是不需要的)
 position: relative;
}

 line:position: relative;之后,所有列元素,也就是item都将基于canvas的左上角为定位元坐标。里面每一块内容叫:item

.item {
 position: relative;
 float: left;
 left: 100%;
} 

  left: 100%;将每个item的定位坐标初始化为line的最右侧; float和position: relative;的作用:float让他脱离文本流,position可以去控制iteam的位置。 定位采用margin-left的负值来定位。
  请注意,item的初始坐标都是line的最右侧。我们从左往右依次在源码中排列item,我们将他们标识为:item1,  item2,item3.宽度分别为:180px,500px,250px(item与item间隔10px) 。
  那么最左侧的item1,margin-left=-100%,也就是整个line的宽度。

  item2,margin-left:950-180-10=760px,请注意是负值

  item3,margin-left:950-180-500-10-10=250

  这样我们完成了一个典型的淘宝三栏布局。

  优点

  通过这种伪绝对定位。我们可以将任何单元在预先定义好的栅格中排列。所有的单元只需要简单的浮动,多亏有了clear,可以有和普通文档流一样的优 点。栅格 中的每一行的高度或者依赖于其中的内容,或者被css所定义,无论定义了多少列,每一行都是100%的宽度。而且我们可以避免使用笨拙的正值的 margin或者padding来调整元素间的空白。这些技巧都不需要因为ie6的盒模型错误导致所需要的css hack。
  这个技术另外一个优点是很大程度上减轻了脆弱的浮动。当浮动盒模型的内容的宽度大于盒模型本身时,它将把下一个盒对象推到右边(通常情况下,这个盒对象会落到下方)。
  通过伪绝对定位,该盒模型将无论如何都保持在原位,而盒模型中的内容,可能会重叠到一起,这依赖于是否overflow:hidden。现象谨此而已,而且根据我们的观察,内容发生重叠比破坏布局要好得多。
坦白的说,我对这项技术的结果非常满意。它合理的利用了被广泛在浏览器中所应用的的HTML 4.01 , CSS 2.1 ,负值margin。


  它有更多的好处:

    它可以工作在流体设计下;

    他可以与等高列(equal height columns )很好的结合起来(尽管他是一个已经被解决了的问题);

    他可以很好的结合等宽布局(fixed-width)或者活动宽度(flexible-width)列。

    甚至可以递归的使用这种布局结构。例如将单元作为新行或单元的容器


  缺点
  伪绝对定位布局非常具有创造力,天生为栅格布局设计而出现。而且越是复杂的结构越值得这样去做。如果你只需要实现2列定宽设计,这项技术也许不是那么值得。
  另外,伪绝对定位布局也不是适用于所有的情况。如果你需要把元素左对齐,那么你使用的单元与那种父容器指定宽度的单元将会不一样,因为你无法计算 offset。例如:如果父容器宽度是800px,里面的单元与右侧要间隔2em,那么你无法计算margin-left的负值,因为你不知道800px 是多少em
  而且它只是一项新技术,并没有被成千上万的人测试过。所以它如仍然是实验性的。所以在你实际的markup,css和浏览中,也许会出现你无法预料的情况。
  剩下的一点是:如果有一个元素,它的父容器小于在排列比在html源码中靠前的那个元素,在同一行中的后续的元素将会被推到右侧,距离等于第一个元素和父容器宽度之差。

原文:Faux Absolute Positioning
参考阅读:In Search of the Holy Grail

posted @ 2013-01-14 16:20  ~小章鱼~  阅读(321)  评论(0编辑  收藏  举报