本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前言
很多面试官在面试时会给求职者出这样一个问题,“如果要你实现三栏布局,你有哪些方式?”。这道题在我们前端er在求职时会遇到的高频题。“三栏布局”其实说的就是左右栏宽度固定,中间栏宽度自适应。
最近花了一点时间对三栏布局的几种方式进行了实现,以下分享一下我的几种思路。
三栏布局实现
absolute 绝对定位
每个元素都设置为绝对定位 absolute,设置中间自适应元素的 left 和 right 对应左右元素的高。
<body>
<div class="main">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div>
</body>
<style>
body {
margin: 0;
}
.main {
width: 100%;
height: 100px;
position: relative;
}
.left {
width: 100px;
height: 100%;
background-color: aqua;
position: absolute;
left: 0;
}
.center {
flex: 1;
height: 100%;
background-color: red;
position: absolute;
left: 100px; /*left 的宽度*/
right: 150px; /*right 的宽度*/
}
.right {
width: 150px;
height: 100%;
background-color: blueviolet;
position: absolute;
right: 0;
}
</style>
float 浮动
使用浮动实现:中间列设置 margin: 0 左右宽度 且不用设置宽度,左右两列分别向左右浮动。
内容必须放在最后面。
<body>
<div class="main">
<div class="left"></div>
<div class="right"></div>
<div class="center"></div>
</div>
</body>
<style>
body {
margin: 0;
}
.main {
width: 100%;
height: 100px;
}
.left {
float: left;
width: 100px;
height: 100%;
background-color: aqua;
}
.right {
float: right;
width: 100px;
height: 100%;
background-color: blueviolet;
}
.center {
margin-left: 100px;
margin-right: 100px;
height: 100%;
background-color: red;
}
</style>
flex 弹性布局
使用弹性布局实现,与使用浮动实现不同,要注意三栏按顺序排列,即left,center、right。
设置中间列 flex: 1,使其自动收缩。flex: 1 对应于flex-grow: 1;, flex-shrink: 1, flex-basis: 0%;,表明元素弹性伸展和收缩。
<body>
<div class="main">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div>
</body>
<style>
body {
margin: 0;
}
.main {
width: 100%;
height: 100px;
display: flex;
}
.left {
width: 100px;
height: 100%;
background-color: aqua;
}
.center {
flex: 1;
height: 100%;
background-color: red;
}
.right {
width: 150px;
height: 100%;
background-color: blueviolet;
}
</style>
圣杯布局和双飞翼布局
在学习实现三栏布局的同时接触到两个概念,圣杯布局和双飞翼布局。这两个布局的思想其实就是三栏布局,只不过它们的实现方式有所不同。
圣杯布局
将最外层的 padding-left 和 padding-right 设置成左右两列的宽度。每一列都设置 float: left。
左边列设置 margin-left: -100%,右边列设置margin-left: -自己的宽度,再将左右两个列用相对布局 position: relative 并分别配合 left 和 right 属性,以便左右两列移动后不遮挡中间列。
<div class="main">
<div class="center">center</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
<style>
.main {
height: 100px;
padding-left: 100px;
padding-right: 150px;
}
.left {
width: 100px;
height: 100%;
background-color: aqua;
float: left;
margin-left: -100%;
position: relative;
left: -100px;
}
.center {
width: 100%;
height: 100%;
background-color: red;
float: left;
}
.right {
width: 150px;
height: 100%;
background-color: blueviolet;
float: left;
margin-left: -150px;
position: relative;
right: -150px;
}
</style>
双飞翼布局
中间一列优先渲染:内容在 html 里面必须放在前面。
自适应中间列的必须放在 left 和 right 前面,且包含在一个父 div 里。内容列的父 div、左列和有列都设置为向左浮动。左列设置 margin-left: -100%,右列设置margin-left: -自己的宽度,中间内容列设置 margin: 0 左右的宽度。
<div class="bg">
<div class="main">
<div class="center"></div>
</div>
<div class="left"></div>
<div class="right"></div>
</div>
<style>
.bg {
width: 100%;
height: 100px;
}
.main {
width: 100%;
height: 100%;
float: left;
}
.main .center {
height: 100%;
margin-left: 100px;
margin-right: 150px;
background-color: aqua;
}
.left,
.right {
height: 100%;
float: left;
background-color: red;
}
.left {
width: 100px;
margin-left: -100%;
}
.right {
width: 150px;
margin-left: -150px;
}
</style>
margin 负值(个人见解)
上面几种实现方式有几种使用了 margin: 负值,之前都是使用正值,负值的用法与正值有所区别,在这里记录一下。
浅谈margin负值
要明白 margin 负值的作用,首先我们先学习一下 margin 的参考线。
margin 有两类参考线,一类是 top 和 left,一类是 right 和 bottom
-
left和top以包含块内容区域的左边和上边或相接元素
margin的右边和下边做参考线 -
right和bottom以元素本身
border的右边和下边做参考线
magin-left: -100%
这个百分比是以父元素内容长度的百分比,该父元素内容长度需要去除 padding、magin 和 border。所以 margin-left: -100% 其实就是相对于左边的参考线向左移动父元素内容长度的距离。
最后
欢迎大家在评论区一起交流,一起进步!