题目
最近在面试中遇到过这样一道面试题,让写出左中右,三栏布局,左栏右栏固定宽度 200px,中间栏宽度自适应。要求三栏的高度随最高的一栏展示
解题
step1
常规拿到这个面试题,首先想到的是三个盒子左浮动右浮动,然后中间盒子给个左右外边距,防止内部元素被浮动元素覆盖。但是这样只是实现了基本的三列布局。
代码如下:
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<meta http-equiv=”X-UA-Compatible” content=”ie=edge”>
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.left {
float: left;
background:rosybrown;
}
.right {
float: right;
background: royalblue;
}
.left,.right {
width: 200px;
}
.center {
margin-left: 200px;
margin-right: 200px;
background-color: aqua;
}
</style>
</head>
<body>
<div class=”container”>
<div class=”left”>left</div>
<div class=”right”>right</div>
<div class=”center”>
1
<br>
2
<br>
3
<br>
4
<br>
5
<br>
</div>
</div>
</body>
</html>
效果如下所示:
step2
乍一看实现了三列布局,但是题目要求等高,这个可就麻烦了。常规的 css,非 table 布局很难解决这个问题。于是乎只能利用一些奇淫巧技。代码改动如下:
<style>
.container {
overflow: hidden;
}
.left,.right {
padding-bottom: 9999px;
margin-bottom: -9999px;
width: 200px;
}
.center {
margin-left: 200px;
margin-right: 200px;
background-color: aqua;
padding-bottom: 9999px;
margin-bottom: -9999px;
}
</style>
同样的 html 片段,这次再看下效果:
实现了等高效果。当时我是记得可以利用负边距实现这个奇淫巧技的,但是笔试纸上写的 css 写的对不对忘记了。
回顾(原理探究)
这里原理暂且不写,感兴趣的小伙伴可以查询下负边距相关的资料。
展开
在跟面试官聊了以后,其实面试官是想考察我对 flex 的使用。那么如果用 flex 该如何实现这种三列布局呢?
flex 实现的列布局
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<meta http-equiv=”X-UA-Compatible” content=”ie=edge”>
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.container {
display: flex;
}
.left {
width: 200px;
background: #f00;
}
.right {
width: 200px;
background: #f0f;
}
.center {
flex: 1;
background: #00f;
}
</style>
</head>
<body>
<div class=”container”>
<div class=”left”>
left
</div>
<div class=”center”>
center<br>
123
</div>
<div class=”right”>
right
</div>
</div>
</body>
</html>
要点就是父容器设置为 flex 容器,子元素会自动变为 flex 项目。这时候通过给 center 设置 flex:1,让其撑满剩余空间。
这里面试官继续问了: flex 是三个属性的缩写,那你知道是哪三个属性吗?这里直接说答案为:[<‘flex-grow’> <‘flex-shrink’>? || <‘flex-basis’>]
其中 flex-grow 规定了对 flex 项目对剩余空间的分配比例 (剩余空间多的话)flex-shrink 规定了容器空间不够时,容器项目要被压缩的比例。flex-basic 一般指项目占据主轴的空间,比如 200px;
疑问
这里只对 center 的值设置了 flex:1,那 left,right,center 的 flex 默认值分别展开是什么呢?
这里通过 F12 审查可以得到结果:.left 与.right => flex-basic:auto(宽 200px);flex-grow:0(不占剩余空间);flex-shrink:1(缩小比例占 1 份).center => flex-basic(0%);flex-grow:1(left 与 right 都为 0,所以它占据了全部的剩余空间);flex-shrink:1(缩小比例占 1 份) 因为当前空间足够,所以这里 flex-shrink 没有体现。
结语
大概与这道题相关的 css 知识有这么多,如果是你,能做到哪一步呢?
参考链接
阮一峰的 flex 布局讲解