建议先了解负值margin对浮动元素的影响 https://blog.csdn.net/weixin_42207975/article/details/107386711 。
网站布局中的三栏布局,可以用圣杯布局与双飞翼布局来实现。
三栏布局有其中几个要点:
- “中间”的主体部分在DOM结构上优先,以便优先渲染(详见HTML)。
- 两侧部分宽度固定,中间宽度自适应。
- 允许三个列中任意一列成为最高列。
圣杯布局
<div class="container">
<div class="main"></div>
<div class="left"></div>
<div class="right"></div>
</div>
.container {
min-width: 200px;
padding: 0 150px 0 200px;
}
.main,
.left,
.right {
float: left;
position: relative;
}
.main {
width: 100%;
}
.left {
width: 200px;
margin-left: -100%;
left: -200px;
}
.right {
width: 150px;
margin-left: -150px;
left: 150px;
}
实现思路
- 用一个 container 同时包裹 main、left、right 三个部分,并把三者设置为左浮动以及相对定位(方便后续调整位置)。
- 初始时,因为main部分设置宽度为100%,所以left和right被挤到下面的行去了。
- 通过设置负值margin-left:-100%将left的总体宽度减少至0而上到第一行,并继续向左移动直至左端与main左端重叠,接着通过相对定位将left移动至其右端与main左端重叠。
- 同理,通过负值margin-left:-150px将right移动到第一行,接着通过相对定位将其移至左端与main右端重叠。或者,直接设置margin-right:-150px,也可以直接达到这两个的效果。
- 此时,left和right都已经移动到了main的两端,且位于container外侧(下图情况一),所以需要给container设置padding,让这left和right回到container内部的位置。
- 最后,给container设置最小宽度,设置为left和right两者中的较大值即可。因为上述的总体宽度为0,只是相对于与其布局浮动等情况相似的兄弟元素而言,从而影响了它的样式。但对于container,left和right的实际宽度不为0,所以如果container的宽度过小,会导致装不下它们,位置错乱(下图情况二),更别说想要改变位置了。
双飞翼布局
<div class="container">
<div class="main"></div>
</div>
<div class="left"></div>
<div class="right"></div>
.container {
width: 100%;
}
.container,
.left,
.right {
float: left;
}
.main {
margin: 0 150px 0 200px;
}
.left {
width: 200px;
margin-left: -100%;
}
.right {
width: 150px;
margin-left: -150px;
}
实现思路
- 用一个container包裹住main,并设置宽度为100%,然后把container、left、right三者设置为左浮动。
- 给left设置margin-left:100%,让它左端与container左端重合。
- 给right设置margin-left:-150px,让它右端与container右端重合。
- 因为默认情况下,main继承了width的100%宽度,所以left、right此时覆盖了main的左右两端的一部分宽度(下图情况一)。为了处理这种情况,需要给main设置左右两边的margin,给left、right空出位置。
两种布局的对比
- 双飞翼布局完美解决了圣杯布局的布局错乱问题;
- 双飞翼布局CSS代码逻辑更简单,但需要用一个额外的标签包裹main;
- 上述两段代码中的container角色不同,圣杯布局中的container充当父盒子作用(换做其他标签亦可),双飞翼布局中container用于包裹住main。