七種右邊固定,左邊自適應兩欄佈局
阿新 • • 發佈:2019-02-12
參考文章實現了``右邊固定,左邊自適應``的兩欄佈局的七種方法。最終的效果,可以檢視這裡https://hangforfreedom.github.io/some-cases/demo-4/demo.html。
與原案例不同的是右邊``div``和左邊``div``在html原始碼中的書寫的先後順序也是不同的。
所以我將右邊div分為兩個類,一個是書寫在左邊div上面的``top-right``,一個是書寫在左邊div後面的``bottom-right``。程式碼如下:
在這裡,為了簡單的計算左側盒子準確的寬度,設定子元素的``box-sizing: border-box;``以及父元素的``box-sizing: content-box;``。
同時,作為兩個``inline-block``的盒子,必須設定``vertical-align``來使其頂端對齊。
* 需要知道右側盒子的寬度,兩個盒子的距離,還要設定各個元素的``box-sizing``
* 需要消除空格字元的影響
* 需要設定``vertical-align: top;``滿足頂端對齊。
* 需要知道右側盒子的寬度,兩個盒子的距離,還要設定各個元素的``box-sizing``
* 父元素需要清楚浮動
但是``block``級別的元素都是獨佔一行的,所以要想辦法讓兩個``block``排列到一起。
> 我們知道,``block``級別的元素會認為浮動的元素不存在,但是``inline``級別的元素能識別到浮動的元素。這樣,``block``級別的元素就可以和浮動的元素同處一行了。
以上是原作者在文章中解釋到的。不過,在我的案例中,我嘗試著改動右側``div``和左側``div``的書寫順序,才實現了右側固定,左側自適應的效果。所以程式碼中的類為``top-right``。
為了讓右側盒子和左側盒子保持距離,需要為右側盒子留出足夠的距離。這個距離的大小為右側盒子的寬度以及兩個盒子之間的距離之和。然後將改值設定為左側盒子的``margin-right``。
缺點:
* 需要清除浮動
另外一種讓兩個``block``排列到一起的方法是對右盒子使用``position: absolute;``的絕對定位。這樣,左側盒子也能無視掉它。
* 使用了絕對定位,則需要在父元素中使用相對定位``position: relative;``
上面的方法都需要通過右側盒子的寬度,計算某個值,下面三種方法都是不需要計算的。只需要設定兩個盒子之間的間隔。
* 父元素需要清除浮動
<strong>需要注意</strong>的是,``flex``容器的一個預設屬性值:``align-items: stretch;``。這個屬性導致了列等高的效果。
為了讓兩個盒子高度自動,需要設定:``align-items: flex-start;``。
* ``grid``佈局也有列等高的預設效果。需要設定:``align-items: start``
* ``grid``佈局還有一個值得注意的小地方和``flex``不同:在使用``margin-right``的時候,``grid``佈局預設是``box-sizing``設定的盒寬度之間的位置。而``flex``則是使用兩個div的``border``或者``padding``外側之間的距離
連結:
* 本文參考文章:右邊固定,左邊自適應 https://segmentfault.com/a/1190000010698609
與原案例不同的是右邊``div``和左邊``div``在html原始碼中的書寫的先後順序也是不同的。
所以我將右邊div分為兩個類,一個是書寫在左邊div上面的``top-right``,一個是書寫在左邊div後面的``bottom-right``。程式碼如下:
基本的樣式是:兩個盒子相距``20px``,右盒子寬``200px``,左盒子自適應。基本的CSS樣式如下:<div class="wrapper wrapper-inline-block" id="wrapper"> <div class="top-right"> /*書寫在左側div之上*/ 我是右邊div:top-right<br><br> 基本樣式:兩個div相距20px,右側div寬200px<br><br><br><br><br> </div> <div class="left"> 我是左邊div:left<br> 高度有可能會很小,也可能很大。<br> 我是自適應。我是自適應。我是自適應。我是自適應。我是自適應。我是自適應。我是自適應。 <br> </div> <div class="bottom-right"> /*書寫在左側div之下*/ 我是右邊div:bottom-right<br><br> 基本樣式:兩個div相距20px,右側div寬200px<br><br><br><br><br> </div> </div>
.wrapper{
padding: 15px 20px;
border: 1px solid #f60;
}
.left{
margin-right: 20px;
border: 5px solid #ddd;
}
.top-right,
.bottom-right{
width: 200px;
border: 5px solid #ddd;
}
下面的程式碼就是基於這套基本程式碼做覆蓋,通過容器新增不同的類來實現效果。 # 雙``inline-block``方案
這種方法是通過``width: calc(100% - 225px)``來動態計算左盒子的寬度。``225px``指的是左盒子距離右盒子的距離,以及右盒子具體的寬度``(content+padding+border)``,以及計算父容器寬度的``100%``需要減去的數值。同時,還需要知道左側盒子的寬度是否包含``border``的寬度。.wrapper-inline-block{ box-sizing: content-box; font-size: 0; /*消除空格的影響*/ } .wrapper-inline-block .left, .wrapper-inline-block .bottom-right{ display: inline-block; vertical-align: top; /*頂端對齊*/ font-size: 14px; box-sizing: border-box; } .wrapper-inline-block .left{ width: calc(100% - 225px); }
在這裡,為了簡單的計算左側盒子準確的寬度,設定子元素的``box-sizing: border-box;``以及父元素的``box-sizing: content-box;``。
同時,作為兩個``inline-block``的盒子,必須設定``vertical-align``來使其頂端對齊。
另外,為了準確的應用計算出來的寬度,需要消除``div``之間的空格,需要通過設定父容器的``font-size: 0;``,或者登出消除``html``中的空格等方法。
缺點:* 需要知道右側盒子的寬度,兩個盒子的距離,還要設定各個元素的``box-sizing``
* 需要消除空格字元的影響
* 需要設定``vertical-align: top;``滿足頂端對齊。
# 雙``float``方案
.wrapper-double-float{
overflow: auto; /*清除浮動*/
box-sizing: content-box;
}
.wrapper-double-float .left,
.wrapper-double-float .bottom-right{
float: left;
box-sizing: border-box;
}
.wrapper-double-float .left{
width: calc(100% - 225px);
}
本方案和雙``inline-block``方案原理相同,都是通過動態計算寬度來實現自適應。但是,由於浮動的``block``元素在有空間的情況下會依次緊貼,排列在一行,所以無需設定``display: inline-block;``,自然也就減少了頂端對齊,空格字元佔空間等問題。 不過由於應用了浮動,父元素需要清除浮動。
缺點:* 需要知道右側盒子的寬度,兩個盒子的距離,還要設定各個元素的``box-sizing``
* 父元素需要清楚浮動
# ``float+margin-right``方案
.wrapper-float{
overflow: hidden; /*清除浮動*/
}
.wrapper-float .left{
margin-right: 225px
}
.wrapper-float .top-right{
float: right;
}
上面兩種方案都是利用了CSS的``calc()``函式來計算寬度值。下面兩種方案則是利用了``block``級別的元素盒子的寬度具有<strong>填滿父容器,並隨著父容器的寬度自適應的流動特性</strong>。 但是``block``級別的元素都是獨佔一行的,所以要想辦法讓兩個``block``排列到一起。
> 我們知道,``block``級別的元素會認為浮動的元素不存在,但是``inline``級別的元素能識別到浮動的元素。這樣,``block``級別的元素就可以和浮動的元素同處一行了。
以上是原作者在文章中解釋到的。不過,在我的案例中,我嘗試著改動右側``div``和左側``div``的書寫順序,才實現了右側固定,左側自適應的效果。所以程式碼中的類為``top-right``。
為了讓右側盒子和左側盒子保持距離,需要為右側盒子留出足夠的距離。這個距離的大小為右側盒子的寬度以及兩個盒子之間的距離之和。然後將改值設定為左側盒子的``margin-right``。
缺點:
* 需要清除浮動
* 需要計算左側盒子的``margin-right``
# 使用``absolute+margin-right``方案
另外一種讓兩個``block``排列到一起的方法是對右盒子使用``position: absolute;``的絕對定位。這樣,左側盒子也能無視掉它。
.wrapper-absolute{
position: relative;
}
.wrapper-absolute .top-right{
position: absolute;
right: 20px;
}
.wrapper-absolute .left{
margin-right: 225px;
}
當然,右側盒子使用絕對定位後,不僅要調整它的位置``right: 20;``,還要對其父元素使用相對定位``position: relative``。這樣保證了和左側盒子距離的準確性。
缺點:* 使用了絕對定位,則需要在父元素中使用相對定位``position: relative;``
* 更改書寫順序,右``div``在上左``div``在下
# 使用``float+BFC``方案
上面的方法都需要通過右側盒子的寬度,計算某個值,下面三種方法都是不需要計算的。只需要設定兩個盒子之間的間隔。
.wrapper-float-bfc{
overflow: auto;
}
.wrapper-float-bfc .top-right{
float: right;
margin-left: 20px;
}
.wrapper-float-bfc .left{
margin-right: 0;
overflow: auto;
}
這個方案同樣是利用了左側浮動,但是左側盒子通過``overflow: auto;``形成了BFC,因此左側盒子不會與浮動的元素重疊。 這種情況下,只需要為右側的浮動盒子設定 ``margin-left``,就可實現兩個盒子的距離了。而左側盒子是``block``級別的,所以寬度能實現自適應。
缺點:* 父元素需要清除浮動
# ``flex``方案
.wrapper-flex{
display: flex;
align-items: flex-start;
}
.wrapper-flex .bottom-right{
flex: 0 0 auto;
}
.wrapper-flex .left{
flex: 1 1 auto;
}
``flex``可以說是最好的方案了,程式碼少,使用簡單。 <strong>需要注意</strong>的是,``flex``容器的一個預設屬性值:``align-items: stretch;``。這個屬性導致了列等高的效果。
為了讓兩個盒子高度自動,需要設定:``align-items: flex-start;``。
# ``grid``方案
.wrapper-grid{
display: grid;
grid-template-columns: 2fr 200px;
align-items: start;
}
.wrapper-grid .left,.wrapper-grid .bottom-right{
box-sizing: border-box;
}
.wrapper-grid .bottom-right{
grid-column: 2;
}
.wrapper-grid .left{
grid-column: 1;
}
注意:* ``grid``佈局也有列等高的預設效果。需要設定:``align-items: start``
* ``grid``佈局還有一個值得注意的小地方和``flex``不同:在使用``margin-right``的時候,``grid``佈局預設是``box-sizing``設定的盒寬度之間的位置。而``flex``則是使用兩個div的``border``或者``padding``外側之間的距離
連結:
* 本文參考文章:右邊固定,左邊自適應 https://segmentfault.com/a/1190000010698609