[CSS] flex和float應用情境

20 mins.
  1. 1. 情境說明
    1. 1.1. 基本題
    2. 1.2. 進階題
  2. 2. 使用flex
    1. 2.1. desktop、mobile呈現
    2. 2.2. ipad呈現
      1. 2.2.1. 基本題
      2. 2.2.2. 進階題
  3. 3. 使用float
    1. 3.1. desktop
    2. 3.2. ipad呈現
    3. 3.3. mobile
    4. 3.4. 小技巧
  4. 4. 結論

一直以來都很習慣用flex來解決排版上面的問題,但最近剛好遇到了一個情況,其實用float會更加方便,今天就來探討一下這個案例

情境說明

基本題

有一個畫面是這樣的,在desktop的寬度下顯示三欄

desktop

ipad寬度顯示兩欄

ipad

mobile顯示一欄

mobile

進階題

每一個欄的高度都不是固定,會根據資料來變化,並且有max-height超過時,每個欄要自己有scrollbar

使用flex

不管看到幾欄,起手勢就是先來用個flex(誤),先來看看要怎麼樣用flex來實作這塊

desktop、mobile呈現

這種三欄一欄的變化,對於flex來說根本是輕而易舉,只要稍微調整一下就好

  • html
1
2
3
4
5
<div class="container">
<div class="item item1">1</div>
<div class="item item2">2</div>
<div class="item item3">3</div>
</div>
  • css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.container{
background: #cacaca;
height: 300px;
display: flex;
}

.item{
flex: 1;
background: #E7F6FC;
height: 100%;
border: 1px solid black;
}
/* mobile */
@media screen and (max-width: 599px){
.container{
flex-direction: column;
}
}

ipad呈現

使用flex最麻煩的會是ipad的2*1+1的呈現方式,因為比較不好這樣操作,這邊會分作兩種模式來寫

基本題

html不變,只是調整一下css的寫法,加上wrap讓第三欄自動的換行,這這個缺點就是第一欄和第二欄的高度不夠彈性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@media screen and (max-width: 1023px){
.container{
flex-direction: column;
flex-wrap: wrap;
}

.item3{
flex-basis: 100%;
}
}

/* mobile */
@media screen and (max-width: 599px){
.container{
flex-direction: column;
flex-wrap: unset;
}

.item3{
flex: 1;
}
}

進階題

先來做個簡單的微調,看看當欄位資料超過100%會發生什麼事情

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

@media screen and (max-width: 1023px){
.container{
flex-direction: column;
flex-wrap: wrap;
}

.item1{
flex-basis: 30%;
}

.item2{
flex-basis: 75%;
}

.item3{
flex-basis: 100%;
}
}

錯誤的兩欄

ㄟ~奇怪,怎麼變成三欄了,說好的兩欄呢!?但應該要怎麼完成我們的需求?其實非常的簡單就是把item1item2包起來,以結構上來說就是變成兩欄的變化

先來把html做個調整

1
2
3
4
5
6
7
<div class="container">
<div class="column column1">
<div class="item item1">1</div>
<div class="item item2">2</div>
</div>
<div class="column column2">3</div>
</div>

這邊就不寫其他尺寸的css,只先寫一種case

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.container{
background: #cacaca;
height: 300px;
display: flex;
}

.column{
flex: 1;
background: #E7F6FC;
height: 100%;
border: 1px solid black;
}

.column1{
display: flex;
flex-direction: column;
}

.item{
border: 1px solid red;
flex: 1;
}

使用float

看完flex以後,接著來看看怎麼使用float做到同樣的效果,只是float比較討厭的一點就是必須要清除,不然空間會有問題

desktop

  • html
1
2
3
4
5
6
<div class="container">
<div class="item item1">1</div>
<div class="item item2">2</div>
<div class="item item3">3</div>
<div class="clearfix"></div>
</div>
  • css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
.container{
background: #cacaca;
}

.item{
float: left;
width: 33%;
height: 300px;
border: 1px solid black;
}

.clearfix{
clear: left;
}

ipad呈現

這邊唯一的問題就是如果有邊框或是底色,第二欄就沒辦法滿版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.container{
background: #cacaca;
}

.item{
border: 1px solid black;
box-sizing: border-box;
}

.item1{
height: 100px;
width: 30%;
float: left;
}

.item2{
height: 200px;
width: 30%;
float: left;
clear: left;
}

.item3{
display: inline-block;
width: 70%;
}

.clearfix{
clear: left;
}

mobile

這邊就都把float拉掉就行,因為block預設就是一個row的行為

小技巧

我有一個算是潔癖?或是怪癖?希望不要出現多餘的html,像是clearfix的element,但是float一旦沒有被清除,parent的空間呈現上是有問題的,這時候有沒有比較好的作法呢?

有兩個方法可以解決這問題

  1. pseudo element

    1
    2
    3
    4
    5
    .container::after{
    content: '';
    display: block;
    clear: left;
    }
  2. overflow,這是一個奇淫技巧,可以發現有一樣的效果

    1
    2
    3
    .container{
    overflow: hidden;
    }

結論

其實不管用哪個來實作都可以,都可以做出目的的效果,但在寫css的時候還是可以看一下應用的情境,也許剛好那個情境會比較適合,那何必要用更麻煩的方式來完成呢

最後來推廣一下Amos的youtube頻道FB粉絲團,最近在暴力班收穫滿滿阿