zoukankan      html  css  js  c++  java
  • 渐进增强式布局探讨(下)

    上篇中讨论了各种已有的布局实现。仔细分析各种布局的技术实现,可以发现下面三种技术被经常使用:

    • 浮动 float
    • 负边距 negative margin
    • 相对定位 relative position

    这是实现布局的三个最基本的原子技术。只要巧妙组合,并加以灵活运用,就能“拼”出各种布局的实现方案。

    尝试之路

    考虑以下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;
    100%;
    }
    .sub {
    float: left;
    190px;
    margin-left: -100%;
    }
    .extra {
    float: left;
    190px;
    margin-left: -190px;
    }

    这样我们得到了第一个尝试页面 pe_layout_example1.html.
    可以看出,通过简单的负边距,已经让subextra定位到正确的位置。剩下的问题是如何让main也定位到正确的位置。

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

        #bd {
    padding: 0 230px 0 190px;
    }

    效果请看: pe_layout_example2.html.
    这样能让main定位到正确的位置,但subextra的位置不对了。这是一个思考的关卡。既然subextra的位置不对,那就想办法调整到正确的位置。相对定位隆重登场:

        .sub {
    float: left;
    190px;
    margin-left: -100%;
    position: relative;
    left: -190px;

    }
    .extra {
    float: left;
    230px;
    margin-left: -230px;
    position: relative;
    right: -230px;

    }

    demo页面: pe_layout_example3.html. 很明显,这就是圣杯布局!

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

    demo页面: pe_layout_example4.html.

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

        .extra {
    float: left;
    230px;
    margin-left: -100%;
    position: relative;
    left: 190px;

    }
    .main-wrap {
    margin-left: 430px;
    }

    demo页面: pe_layout_example5.html.

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

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

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

    优点

    1. 实现了内容与布局的分离,即Eric提到的Any-Order Columns.
    2. main部分是自适应宽度的,很容易在定宽布局和流体布局中切换。
    3. 任何一栏都可以是最高栏,不会出问题。
    4. 需要的hack非常少(就一个针对ie6的清除浮动hack:_zoom: 1;
    5. 在浏览器上的兼容性非常好,IE5.5以上都支持。

    不足

    1. main需要添加一个额外的包裹层。
    2. 等待你的发现与反馈。

    补充

    双飞翼布局的想法与实现受了圣杯布局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的宣传力度不够,导致这个布局被我重新 “发现”了一次。特撰此文,并取名为“双飞翼布局”,希望这个布局能让更多的人知道,并应用于实践中。

    每一个超人背后~都有一只默默承受的小怪兽~
  • 相关阅读:
    命名函数
    匿名函数
    Elixir基础
    Elixir特性
    linux下安装erlang
    更具先序、中序遍历生成二叉树
    第一章 TCP/IP协议族
    React Native开发之expo中camera的基本使用
    Vue中异步组件(结合webpack,转载)
    vue中将html字符串转换成html后的一些问题
  • 原文地址:https://www.cnblogs.com/html5salon/p/2548992.html
Copyright © 2011-2022 走看看