5

题目

最近在面试中遇到过这样一道面试题,让写出左中右,三栏布局,左栏右栏固定宽度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>

效果如下所示:

clipboard.png

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片段,这次再看下效果:

clipboard.png

实现了等高效果。当时我是记得可以利用负边距实现这个奇淫巧技的,但是笔试纸上写的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布局讲解


A_大白
1k 声望68 粉丝

Alibaba-高德,信息前端持续招人中,欢迎私信我,或者钉钉pws019。