前端經(jīng)典網(wǎng)頁布局的實(shí)現(xiàn)方案你了解多少?

前端開發(fā),離不開日常的網(wǎng)頁結(jié)構(gòu)布局,現(xiàn)下有很多第三方的組件庫,也自帶著很多布局的方案,例如Ant Design中就擁有一套自己的Grid 24柵格系統(tǒng)Layout布局,方便我們進(jìn)行網(wǎng)頁排版。

接下來,我們從前端技術(shù)角度上,去分析一下3種經(jīng)典布局的實(shí)現(xiàn)方案。

首先,我們列出一些比較常規(guī)的布局:

  • 圣杯布局
  • 雙飛翼布局
  • 多列等分布局

1. 圣杯布局

圣杯布局: 左右兩欄的寬度固定不變,中間那一欄寬度自適應(yīng),且中間盒子的內(nèi)容優(yōu)先渲染。

最早的圣杯布局的實(shí)現(xiàn)方案是:利用浮動和負(fù)邊距來實(shí)現(xiàn)。

父級元素設(shè)置左右的 padding,三列均設(shè)置向左浮動,中間一列放在最前面,寬度設(shè)置為父級元素的寬度,因此后面兩列都被擠到了下一行,通過設(shè)置 margin 負(fù)值將其移動到上一行,再利用相對定位,定位到兩邊。

圣杯布局的優(yōu)缺點(diǎn):

  • 優(yōu)點(diǎn):不需要額外的DOM結(jié)構(gòu),中間欄放在文檔流前面是優(yōu)先渲染
  • 缺點(diǎn):特殊情況下,當(dāng)中間盒子寬度小于左盒子的時(shí)候 就會發(fā)生布局混亂

我們可以通過3種技術(shù)方案來實(shí)現(xiàn)圣杯布局的布局效果,分別是float、float優(yōu)化、Flex

實(shí)現(xiàn)代碼:

HTML結(jié)構(gòu):

<div class="main">
    <!--   如果是圣杯布局的原始方案,此處的center盒子要放在最前面 -->
  <div class="center"></div>
   <div class="left"></div>
  <div class="right"></div>
</div>
  • 實(shí)現(xiàn)方案1:float+position+負(fù)邊距
.main {
    height: 200px;
    /* 外層大盒子設(shè)置左右的padding,給兩側(cè)小盒子預(yù)留出位置 */
    padding: 0 200px;
}
.center, .left, .right {
    /* 三個(gè)盒子統(tǒng)一左浮動 */
    float: left;
}

/* 注意,在HTML結(jié)構(gòu)中,center盒子一定要位于left和right盒子之前 */
.center {
    /* 中間盒子占據(jù)父盒子寬度的100% */
    width: 100%;
    height: 100%;
    background: lightgreen;           
}

.left {
    width: 200px;
    height: 100%;
    background: lightseagreen;

    /* left被center盒子擠到了下方,設(shè)置margin負(fù)值會讓三個(gè)盒子在一行上顯示 */
    margin-left: -100%;

    /* 通過定位負(fù)值讓left盒子位于main盒子預(yù)留出的padding的位置 */
    position: relative;
    left: -200px;
}

.right {
    width: 200px;
    height: 100%;
    background: lightskyblue;
    /* right被center盒子擠到了下方,設(shè)置margin負(fù)值會讓三個(gè)盒子在一行上顯示 */
    margin-left: -200px;

    /* 通過定位負(fù)值讓right盒子位于main盒子預(yù)留出的padding的位置 */
    position: relative;
    right: -200px; 
}
  • 實(shí)現(xiàn)方案2:float優(yōu)化
.main {
    width: 100%;
    height: 100px;
}

.left {
    width: 200px;
    height: 100%;
    background: lightcoral;
    /*  左盒子左浮動  */
    float: left;
}

.right {
    width: 200px;
    height: 100%;
    background: lightgreen;
    /* 右盒子右浮動 */
    float: right;
}

.center {
    height: 100%;
    background: lightsalmon;
    /* 中間盒子左浮動 */
    float: left;
    /* 中間盒子使用css的calc()去自動計(jì)算寬度,思想為:父盒子寬度100% - (左盒子 + 右盒子) */
    /* 注意:如果網(wǎng)頁中在意極致加載速度等優(yōu)化效率時(shí),盡量不要大量使用calc()函數(shù)  */
    width: calc(100% - 400px);
}
  • 實(shí)現(xiàn)方案3:Flex
.main {
    width: 100%;
    height: 100px;
    /*  父盒子轉(zhuǎn)為flex彈性盒子  */
    display: flex;
    /*  子元素居中  */
    justify-content: center;
    align-items: center;
}

.left {
    width: 200px;
    height: 100%;
    background: lightcoral;
}

.right {
    width: 200px;
    height: 100%;
    background: lightgreen;
}

.center {
    height: 100%;
    background: lightsalmon;
    /*  中間盒子占據(jù)剩下的全部空間  */
    flex: 1;
}

當(dāng)然,實(shí)現(xiàn)圣杯布局的效果,還可以使用其它的方案,比如Grid布局方式,只要能夠?qū)崿F(xiàn)其圣杯布局的效果,用什么方式均可以。


2. 雙飛翼布局

概念:雙飛翼布局最早是淘寶團(tuán)隊(duì)提出的,是針對圣杯局部優(yōu)化的解決方案。主要是優(yōu)化了圣杯布局中開啟定位的問題

雙飛翼布局的實(shí)現(xiàn),本質(zhì)上也是利用了浮動和外邊距負(fù)值的思想

雙飛翼布局與圣杯布局的不同之處在于,圣杯布局的左中右三列容器,中間center盒子多了一個(gè)子容器,通過控制center中子容器的margin空出左右兩列的寬度。

<body>
  <div class="main">
    <div class="center">
      <div class="inner"></div>
    </div>
    <div class="left"></div>
    <div class="right"></div>
  </div>
</body>
.main {
    height: 200px;
}

.center,
.left,
.right {
    /* 三個(gè)盒子統(tǒng)一左浮動 */
    float: left;
}

.center {
    /* 中間大盒子占據(jù)父盒子寬度的100% */
    width: 100%;
    height: 100%;
    background: lightgreen;
}

.center .inner {
    height: 100%;
    /* 預(yù)留出左右兩個(gè)盒子的空間 */
    margin: 0 200px;
    background: lightcoral;
}

.left {
    width: 200px;
    height: 100%;
    background: lightseagreen;

    /* left被center盒子擠到了下方,設(shè)置margin負(fù)值會讓三個(gè)盒子在一行上顯示 */
    margin-left: -100%;
}

.right {
    width: 200px;
    height: 100%;
    background: lightskyblue;
    /* right被center盒子擠到了下方,設(shè)置margin負(fù)值會讓三個(gè)盒子在一行上顯示 */
    margin-left: -200px;
}

3. Flex實(shí)現(xiàn)多列等分布局

關(guān)鍵點(diǎn):列數(shù)可自由控制(無固定寬度)

 <div class="main">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>
.main {
    width: 100%;
    display: flex;
    /* 設(shè)置換行 */
    flex-wrap: wrap;
    /* 用來設(shè)置網(wǎng)格行與列之間的間隙,是row-gap(行間隙)和column-gap(列間隙)的簡寫形式 */
    gap: 20px;
}
.main .item {
    height: 200px;
    /* 關(guān)鍵點(diǎn)在于子盒子寬度的計(jì)算上 */
    /* flex: 0 0 calc((父元素寬度 - 列之間的寬度*(列數(shù)-1)) / 列數(shù)); */
    flex: 0 0 calc((100% - 20px * 3) / 4);
    background: lightskyblue;
}

以上3中布局,是我們開發(fā)中經(jīng)常見到的布局方式,每種布局方式,都不僅限于一種技術(shù)來實(shí)現(xiàn),可以是FloatPosition,也可以是Flex,還可以是Grid,甚至有的開發(fā)者對Boostrap很熟悉,也是一種實(shí)現(xiàn)方式。

個(gè)人認(rèn)為,每種技術(shù)方案的使用,都有其優(yōu)缺點(diǎn),或考慮兼容性,或考慮性能,選擇適合當(dāng)下項(xiàng)目的內(nèi)容,適當(dāng)做取舍,才是最關(guān)鍵的。

關(guān)注我,下期我們一起探討GridFlex的不同之處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容