CSS相關面試題——三欄等高佈局

題目

最近在面試中遇到過這樣一道面試題,讓寫出左中右,三欄佈局,左欄右欄固定寬度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佈局講解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章