你不知道的 CSS 文檔流技巧,讓佈局更簡單

看文章以前,先來看兩個例子。這是咱們在項目中最多見的項目佈局方式。css

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

案例二:常見的菜單導航微信

看到這兩個案例時,你能夠先短暫的想一想平時都是如何實現的,不少同窗的答案應該是這樣的。佈局

// 案例一
<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 佈局的狀況下,你想讓三個元素自適應屏幕寬度有什麼好辦法?flex

或者你想把三個元素擴展成四個,這個時候你就須要手動計算每一個元素的寬度。這樣好像非常麻煩。spa

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

在剛開始學習 CSS 時咱們都會常常聽到這麼一個概念叫「文檔流」,不少人並無深究文檔流是爲什麼物。cdn

那什麼是「文檔流」呢?blog

文檔流

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

而「流」具備最大的一個特色就是自適應性。你能夠把它想象成像水流同樣,當水流倒入一個容器時,它會自動充滿整個容器。而 CSS 中的文檔流,其表現是一致的,有殊途同歸之妙。

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

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

塊級元素默認會充滿整個屏幕,具備自適應性,而內聯元素默認則是水平排列。

你能夠想象爲塊級元素就想是水流同樣充滿容器,而內聯元素就是漂浮在水裏按照從左到右排列的物體。

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

失去流動性

到這裏你應該明確了流的特性,其實不少人都知道「文檔流」這個概念,但卻沒有好好的去利用,從而給本身增長了一些沒必要要的麻煩。

好比之前我會寫出這樣的 CSS:

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

若是明白流的特性的話,其實 width: 100%; 這個屬性是多餘的,由於塊級元素在流佈局中默認是自動充滿容器的。

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

但若是僅僅只是多了一條屬性,其實也就是增長了一行代碼顯得不那麼簡潔而已,可事情老是沒有那麼簡單。

一旦你給元素添加了寬度(width)屬性,它就會失去流動性,即使是它的值爲 100%,也是會失去。

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

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

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

而若是咱們把寬度屬性去掉,就會獲得完美的展現效果。

.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 的,水平排列能夠很容易實現,可是想要有相同間距,就比較難以實現。

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

寬度分離

這時候咱們能夠利用流的特性,進行寬度分離。

<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世界》

相關文章
相關標籤/搜索