圣杯布局和双飞翼布局

双飞翼布局与圣杯布局

圣杯布局和双飞翼布局是前端工程师需要日常掌握的重要布局方式。两者的功能相同,都是为了实现一个两侧宽度固定,中间宽度自适应的三栏布局。

特点:

  1. 两侧宽度固定,中间宽度自适应(三栏布局)
  2. 中间部分在DOM结构上有限,以便先行渲染
  3. 允许三列中的任意一列成为最高列
  4. 只需要使用一个额外的div标签

圣杯布局:
DOM结构:

<div class="header"></div>
<div class="container">
  <div class="center"></div>
  <div class="left"></div>
  <div class="right"></div>
</div>
<div class="footer"></div>

首先定义出整个布局的DOM结构,主体部分是由container包裹的center,left,right三列,其中center定义在最前面。

CSS代码:
假设左侧的固定宽度为200px,右侧的固定宽度为150px,则首先在container上设置:

#container {
  padding-left: 200px;
  padding-right: 200px;
}

为左右两列预留出相应的空间,得到如下示意图:

image

随后分别为三列设置宽度与浮动,同时对footer设置清除浮动:

#container .column {
  float: left;
}

#center {
  width: 100%;
}

#left {
  width: 200px; 
}

#right {
  width: 150px; 
}

#footer {
  clear: both;
}

得到如下效果:

image

根据浮动的特性,由于center的宽度为100%,即占据了第一行的所有空间,所以leftright被“挤”到了第二行。

接下来的工作是将left放置到之前预留出的位置上,这里使用负外边距(nagetive margin)

#left {
  width: 200px; 
  margin-left: -100%;
}

得到:

image

随后还需要使用定位(position)方法:

#left {
  width: 200px; 
  margin-left: -100%;
  position: relative;
  right: 200px;
}

这里使用position: relativeright: 200pxleft的位置在原有位置基础上左移200px,以完成left的放置:

image

接下来放置right,只需添加一条声明即可:

#right {
  width: 150px; 
  margin-right: -150px; 
}

得到最终的效果图:

image

最后,为了保证布局效果的正常显示,我们要给页面设置一个最小宽度。由于两侧都有固定宽度,而left使用了position: relative,所以就意味着在center开始的区域,还存在着一个left的宽度。所以页面的最小宽度应该设置为200+150+200=550px

body {
  min-width: 550px;
}

圣杯布局代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      min-width: 550px;
    }

    #container {
      padding-left: 200px;
      padding-right: 150px;
    }

    #container .column {
      float: left;
    }

    #center {
      width: 100%;
      background: cadetblue;
    }

    #left {
      width: 200px;
      margin-left: -100%;
      position: relative;
      right: 200px;
      background-color: coral;
    }

    #right {
      width: 150px;
      margin-right: -150px;
      background-color: skyblue;
    }

    #footer {
      clear: both;
      height: 100px;
      background-color: beige;
    }

    #header {
      height: 100px;
      background-color: brown;
    }
  </style>
</head>

<body>
  <div id="header">header</div>
  <div id="container">
    <div id="center" class="column">center</div>
    <div id="left" class="column">This is the main content.
      Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
      dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit
      lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit
      esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
      dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.

      Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
      dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit
      lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit
      esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
      dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.</div>
    <div id="right" class="column">This is the right sidebar.
      Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
      dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit
      lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit
      esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
      dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.</div>
  </div>
  <div id="footer">footer</div>
</body>

</html>

双飞翼布局
DOM结构

<body>
  <div id="header"></div>
  <div id="container" class="column">
    <div id="center"></div>
  </div>
  <div id="left" class="column"></div>
  <div id="right" class="column"></div>
  <div id="footer"></div>
<body>

双飞翼布局的DOM结构与圣杯布局的区别是container仅包裹住center,另外将.column类从center移至container

CSS:
按照与圣杯布局相同的思路,首先设置各列的宽度与浮动,并且为左右两列预留出空间,以及为footer设置浮动清除:

    .column {
      float: left;
    }

    #container {
      width: 100%;
    }

    #center {
      margin-left: 200px;
      margin-right: 150px;
      background: cadetblue;
    }

    #left {
      width: 200px;
      background-color: coral;
    }

    #right {
      width: 150px;
      background-color: skyblue;
    }

    #footer {
      clear: both;
      background-color: beige;
    }

    #header {
      background-color: brown;
    }

得到如下效果图:

image

left放置到预留位置:

#left {
  width: 200px; 
  margin-left: -100%;
}

得到:

image

right放置到预留位置:

#right {
  width: 150px; 
  margin-left: -150px;
}

得到

image

最后计算最小页面宽度:由于双飞翼布局没有用到position:relative进行定位,所以最小页面宽度应该为200+150=350px但是当页面宽度缩小到350px附近时,会挤占中间栏的宽度,使得其内容被右侧栏覆盖,如下所示:

image

因此在设置最小页面宽度时,应该适当增加一些宽度以供中间栏使用(假设为150px),则有:

body {
  min-width: 500px;
}

双飞翼布局代码如下所示:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      min-width: 500px;
    }

    .column {
      float: left;
    }

    #container {
      width: 100%;
    }

    #center {
      margin-left: 200px;
      margin-right: 150px;
      background: cadetblue;
    }

    #left {
      width: 200px;
      margin-left: -100%;
      background-color: coral;
    }

    #right {
      width: 150px;
      margin-left: -150px;
      background-color: skyblue;
    }

    #footer {
      clear: both;
      background-color: beige;
    }

    #header {
      background-color: brown;
    }
  </style>
</head>

<body>
  <div id="header">header</div>
  <div id="container" class="column">
    <div id="center">This is the main content.
      Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
      dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit
      lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit
      esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
      dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.

      Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
      dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit
      lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit
      esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
      dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.</div>
  </div>
  <div id="left" class="column">This is the left sidebar.
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore
    magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis
    nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse
    molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui
    blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.</div>
  <div id="right" class="column">This is the right sidebar.
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore
    magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis
    nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse
    molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui
    blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.</div>
  <div id="footer">footer</div>
</body>

</html>

对比圣杯布局和双飞翼布局

  • 圣杯布局结构上更加自然和直观,在平时的开发中更容易形成这样的布局结构;
  • 双飞翼布局由于不使用定位,所以更加简洁,允许页面的最小宽度小于圣杯布局。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值