學會 CSS 文件流技巧,讓佈局更簡單

六小登登發表於2019-04-23

看文章之前,先來看兩個例子。這是我們在專案中最常見的專案佈局方式。

案例一:多個容器按照相同間距水平排列。

學會 CSS 文件流技巧,讓佈局更簡單

案例二:常見的選單導航

學會 CSS 文件流技巧,讓佈局更簡單

看到這兩個案例時,你可以先短暫的想想平時都是如何實現的,很多同學的答案應該是這樣的。

// 案例一
<div class="demo">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>

.demo {
  padding: 1em 0;
  width: 470px;
  background-color: #e5e5e5;
  overflow: hidden;
}
.item {
  float: left;
  margin-left: 10px;
  width: 150px;
  height: 100px;
  background-color: #fff;
  border: 1px solid #999999;
  box-sizing: border-box;
}
.item:first-child {
  margin-left: 0;
}

//案例二
<div class="demo2">
    <a href="" class="nav">導航1</a>
    <a href="" class="nav">導航2</a>
    <a href="" class="nav">導航3</a>
</div>

.demo2 {
  width: 200px;
  background-color: cadetblue;
}
.nav {
  display: block;
  width: 100%;
  border-bottom: 1px solid #000;
  color: #fff;
}
複製程式碼

效果我們是做到了,但是這裡所有畫素都是你自己固定計算的。

比如第一個例子中,父容器的寬度為 470 = 3*150 + 20。如果在不使用 flex 佈局的情況下,你想讓三個元素自適應螢幕寬度有什麼好辦法?

或者你想把三個元素擴充套件成四個,這個時候你就需要手動計算每個元素的寬度。這樣好像很是麻煩。

那今天就來說說,如何利用「流」的特性,解決平時在專案中遇到的一些佈局問題。

在剛開始學習 CSS 時我們都會經常聽到這麼一個概念叫「文件流」,很多人並沒有深究文件流是為何物。

那什麼是「文件流」呢?

文件流

文件流:是引導網頁中的元素排列和佈局的,它預設的方向是從左向右,從上而下。

而「流」具有最大的一個特點就是自適應性。你可以把它想象成像水流一樣,當水流倒入一個容器時,它會自動充滿整個容器。而 CSS 中的文件流,其表現是一致的,有異曲同工之妙。

不僅如此,你也經常會聽到「脫離文件流」,比如浮動,絕對定位等都可以脫離文件流,而脫離文件流不是本文要說的重點,所以就不展開多說,今天主要是聊一聊「流的自適應性」。

文件流中有兩個比較重要的概念:塊級元素(block)、內聯元素(inline),對應到最具代表性的元素就是<div><span>

塊級元素預設會充滿整個螢幕,具有自適應性,而內聯元素預設則是水平排列。

你可以想象為塊級元素就想是水流一樣充滿容器,而內聯元素就是漂浮在水裡按照從左到右排列的物體。

在專案中會經常碰到 display:block 這個屬性。但注意,它與塊級元素不是同一個東西。display:table,也屬於塊級元素。

失去流動性

到這裡你應該明確了流的特性,其實很多人都知道「文件流」這個概念,但卻沒有好好的去利用,從而給自己增加了一些不必要的麻煩。

比如以前我會寫出這樣的 CSS:

span {
    display: block;
    width: 100%;
}
複製程式碼

如果明白流的特性的話,其實 width: 100%; 這個屬性是多餘的,因為塊級元素在流佈局中預設是自動充滿容器的。

你是否也中槍寫過這種 CSS ?歡迎在評論區說出你的問題。

但如果僅僅只是多了一條屬性,其實也就是增加了一行程式碼顯得不那麼簡潔而已,可事情總是沒有那麼簡單。

一旦你給元素新增了寬度(width)屬性,它就會失去流動性,即便是它的值為 100%,也是會失去。

對,你沒有看錯,只要有了寬度屬性,它就會失去了它最牛逼的流動性。這樣就變的毫無價值。

比如開頭中導航案例,如果給導航加入一些邊距。就會出現不好的效果。

學會 CSS 文件流技巧,讓佈局更簡單

.nav {
  display: block;
  padding: 10px; //新增的邊距
  width: 100%;
  border-bottom: 1px solid #000;
  color: #fff;
}
複製程式碼

而如果我們把寬度屬性去掉,就會得到完美的展示效果。

學會 CSS 文件流技巧,讓佈局更簡單

.nav {
  display: block;
  padding: 10px;
  border-bottom: 1px solid #000;
  color: #fff;
}
複製程式碼

可能你之前並沒有意識到,加入寬度屬性帶來的危害。

但當你看到這篇文章之後,你應該警惕寬度給流動性帶來的危害,儘量少用寬度,甚至是「無寬度」。

在此之前我相信很多夥伴在專案彙總遇到過超出寬度的情況,但很少有人去探究,所以很多人都會發揮他特有的計算能力,然後寫出如下程式碼。

.nav {
  display: block;
  padding: 10px;
  width: 180px; // 200px - 10px*2
  border-bottom: 1px solid #000;
  color: #fff;
}
複製程式碼

貌似也實現了該有的功能,不過這種缺點我們顯而易見,就是太過固定,任何一點的改動都需要你重新計算。

可能有人會說,兄die,我的計算能力很驚人,你管的著嗎,好吧這,波算我輸。

那為什麼加了寬度屬性會超出,而不加寬度屬性就可以了呢?

原來是因為,當元素不設定寬度屬性時或者是 width:auto ,元素的margin、border、padding 可以自動分配空間。

一旦,我們設定了固定的寬度屬性,就算是100%,它就會根據 CSS 的盒模型進行計算。從而失去了自動分配空間的流動性。

至於如何計算的細節,因為盒模型的不同,所以寬度的作用就不同,它包含的東西也就不一樣。具體不在多說。

兄die,這時候知道「無寬度」有多牛逼了吧。

因為這裡我提到了盒模型,你會想到把上面的案例,改變下盒模型不就行了嗎?比如我們這麼做:

.nav {
  display: block;
  padding: 10px;
  width: 100%;
  border-bottom: 1px solid #000;
  box-sizing: border-box; //改變盒模型
  color: #fff;
}
複製程式碼

確實在這個案例中是可以這麼用的,但是如果想實現案例一的水平有間距排列問題,就有點力不從心了。

由於 CSS 盒模型,是不計算 margin 的,水平排列可以很容易實現,但是想要有相同間距,就比較難以實現。

這個時候你就可以嘗試利用流的特性,來很好的實現這個方案。

寬度分離

這時候我們可以利用流的特性,進行寬度分離。

學會 CSS 文件流技巧,讓佈局更簡單

<div class="demo">
    <div class="item">
        <div class="child">內容</div>
    </div>
    <div class="item">
        <div class="child">內容</div>
    </div>
    <div class="item">
        <div class="child">內容</div>
    </div>
    <div class="item">
        <div class="child">內容</div>
    </div>
</div>
.demo {
  padding: 1em;
  background-color: #e9e9e9;
  overflow: hidden;
}
.item {
  float: left;
  width: 25%;
}
.child {
  margin: 0 10px;
  padding: 10px;
  border: 1px solid #ccc;
}
複製程式碼

你會發現,無論你如何改變它的 margin、padding、border 它都會自動填充分配空間,再也不會出現佈局錯亂,超出等等一系列的情況。

以上就是利用流的特性,讓佈局變得簡單、靈活。當然,流的特性不僅僅限於這兩種佈局。

還比如表單的佈局,通常表單的佈局都是比較難處理的一點,這時候你不妨試試利用「無寬度」、「寬度分離」原則嘗試一下,也許會有新的發現。小夥伴們趕緊放飛下自己的想象力吧。

最後,如果覺得文章不錯,對你有所啟發,點贊是一種態度也是一種認可。

微信公眾號:六小登登,更多幹貨文章,這裡有我的很多故事,歡迎一起交流。

學會 CSS 文件流技巧,讓佈局更簡單

本文參考:《CSS世界》

相關文章