看文章以前,先來看兩個例子。這是咱們在項目中最多見的項目佈局方式。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世界》