[面试] 圣杯布局与双飞翼布局

898 阅读6分钟

@1. 圣杯布局 【两边宽度固定 中间自适应的三列布局】

要求:三列布局;中间宽度自适应,两边内容定宽(:是固定宽度的)。

要求详细版

  • 上、下部各自占领屏幕所有宽度
  • 上下部之间的部分是一个三栏布局
  • 三栏布局两侧宽度不变,中间部分自动填充整个区域。
  • 中间部分的高度是三栏中最高的区域的高度。

好处:重要的内容放在文档流前面,可以优先渲染

原理:利用相对定位、浮动、负边距布局,而不添加额外标签

实现方式: 2种

【简单,最适合】@ 方法1 :flex弹性盒子

用弹性盒子来实现圣杯布局特别简单,只需要把中间的部分用flex布局即可。

<div class="header">

<h4>header</h4>

</div>

<div class="container">

//首先,既然是三栏式布局,我们就需要3个div:

<div class="left">

<h4>left</h4>

<p>left-content</p>

</div>

<div class="middle">

<h4>middle</h4>

<p>middle-content</p>

</div>

<div class="right">

<h4>right</h4>

<p>right-content</p>

</div>

</div>

<div class="footer">

<h4>footer</h4>

</div>

2.——————————————————————————————————————

.header, .footer {

border: 1px solid #333;

background: #ccc;

text-align: center;

}

.container {

display: flex;

}

.left {

width: 200px;

background: red;

}

.middle {

flex: 1;

background: blue;

}

.right {

width: 220px;

background: green;

}

解析一下思路:

  • header和footer同上面一样,横向撑满。footer不用再清除浮动了
  • container中的left、middle、right依次排布即可,不用特意将middle放置到最前面
  • 给container设置弹性布局 display: flex;
  • left和right区域定宽,middle设置 flex: 1; 即可

@ 方法2:浮动

<div class="header">

<h4>header</h4>

</div>

<div class="container">

<div class="middle">

<h4>middle</h4>

<p>middle-content</p>

</div>

<div class="left">

<h4>left</h4>

<p>left-content</p>

</div>

<div class="right">

<h4>right</h4>

<p>right-content</p>

</div> </div>

<div class="footer"> <h4>footer</h4> </div>

2.—————————————CSS代码————————————————————

.header, .footer {

border: 1px solid #333;

text-align: center;

}

.footer {

clear: both; }

.container {

padding:0 220px 0 200px;

overflow: hidden; }

.left, .middle, .right {

position: relative;

float: left;

min-height: 130px; }

.middle {

width: 100%;

background: blue; }

.left {

margin-left: -100%;

left: -200px;

width: 200px;

background: red; }

.right {

margin-left: -220px;

right: -220px;

width: 220px;

background: green; }

解析一下思路:

  • 在html中,先定义好header和footer的样式,使之横向撑满。
  • 在container中的三列设为浮动和相对定位(后面会用到),middle要放在最前面,footer清除浮动。
  • 三列的左右两列分别定宽200px和220px,中间部分middle设置100%撑满
  • 这样因为浮动的关系,middle会占据整个container,左右两块区域被挤下去了
  • 接下来设置left的 margin-left: -100%;,让left回到上一行最左侧
  • 但这会把middle给遮住了,所以这时给外层的container设置 padding: 0 220px 0 200px;,给left空出位置
  • 这时left并没有在最左侧,因为之前已经设置过相对定位,所以通过 left: -200px; 把left拉回最左侧
  • 同样的,对于right区域,设置 margin-left: -220px; 把right拉回第一行

这时右侧空出了220px的空间,所以最后设置 `right: -220px;##把right区域拉到最右侧就行了

@ 方法3 :css grid网格:有些浏览器不支持,不建议大规模使用

总结:总的来说,弹性布局是最适合实现圣杯布局的方法了,相较浮动,弹性布局的结构更清楚,更好理解,也不用担心移动端的适配问题。

而浮动的方法,在面试中可能会遇到,主要考察对布局的理解能力。所以,建议大家可以把浮动的例子拷贝下来,自行模拟一把,以便加深理解。

圣杯布局正常情况下没问题,但有一个问题【缺点】:一个最小宽度(min-width),当页面<最小宽度时布局就会乱掉。

所以要给body设置一个min-width。这个min-width肯定不能是试出来的,怎么计算呢?就是left-width * 2 + right-width,为什么呢?

简单的说就是:“由于设置了相对定位,所以当left原来的位置和right产生重叠时,由于浮动的原因一行放不下,就会换行。所以布局就被打乱了。使用@2 .双飞翼布局就可以避免这个问题。

@2. 双飞翼布局

/* 双飞翼布局重点 */

.left,

.main,

.right { float: left; //将图像向左浮动 }

.main {

width: 100%; }

. main-content {

margin-left: 200px;

margin-right: 300px; }

.left {

margin-left: -100%;

}

.right {

margin-left: -300px; //差了200 }

</style>

</head>

<body>

<div class="main"><div class="main-content">中心区</div></div>

<div class="left">left</div>

<div class="right">right</div>

</body>

</html>

可以看到,我们main里面又加了一个内容层【主要部分】(main-content

为啥加内容层呢? 【由于盒子模型,我们知道不能直接给main添加margin属性。因为我们已经设置了width:100%,再设置margin的话就会超过窗口的宽度。】

所以我们再创造一个内容层,将所有要显示的内容放到main-content中,给main-content设置margin就可以了。

l 因为不改变父元素所以只需要给main-content设置margin属性差200就OK

双翼布局与圣杯布局差不多,就是在main里面放一层maininner,padding:0 200px 即可,不要在container中使用padding,同时left和right也不要position定位了

补 圣杯/双飞翼布局的不同点(区别):

圣杯布局

借助的是其他非主要元素覆盖了其父元素的padding值所占据的宽度,同一个杯子,非主要元素其只是占据了全部容器的padding值部分;

双飞翼布局:

给内容层【主要部分】(main-content)外部又加了main,其他非主要元素所占据的空间是主要部分(main-content)的margin空间。像鸟的两个翅膀,与主要部分main脱离(main和main-content是下面双飞翼布局的元素id)。