margin系列之內秀篇
原文地址:margin系列之內秀篇 by @doyoe
最Cool的利器
一樣東西在不同的場景,不同的人手裡,所能做的事會有很大不同。我深切的以為 margin
絕對是 CSS 中最有能力的利器之一,不知大家以為然否?
前面幾篇文章大概的講了一些關於 margin
的特性,所以本篇會聊聊 margin
的實際應用場景,也算讓自己休息一下,不用再講知識點。
有個很典型的需求
相信接下來這個需求,你十有八九實現過,甚至實現過多次,來看 圖一
:
我們看到這個圖中,有個列表,每個列表項下面都有一條線,但最後一項沒有。我們預期的程式碼是:
<div id="demo">
<h3>標題列表</h3>
<ul>
<li>» 有點累想歇一下好長一個標題</li>
<li>» 有點累想歇一下好長一個標題</li>
<li>» 有點累想歇一下好長一個標題</li>
<li>» 有點累想歇一下好長一個標題</li>
<li>» 有點累想歇一下好長一個標題</li>
</ul>
</div>
如果每項都有條底線,我們可以很簡單的做到,如下:
#demo li{
border-bottom: 1px solid #ccc;
}
然而為了處理最後一項,事情就變得有點糾結了。我知道肯定有人要說,我們有 :first-child
, :nth-last-child(n)
, :nth-last-of-type(n)
之類的CSS3選擇符,要處理這個,太easy了。恩,我也不得不承認,CSS3確認讓事情變得簡單多了。但我們可能需要面對一些國情,因為需要照顧一些弱小者,比如IE6-8,它們離CSS3的世界太遠。
傳說中的first/last解決方案
所以我們需要找別的方法,於是這樣的程式碼,相信你見過無數遍了:
<div id="demo">
<h3>標題列表</h3>
<ul>
<li>» 有點累想歇一下好長一個標題</li>
<li>» 有點累想歇一下好長一個標題</li>
<li>» 有點累想歇一下好長一個標題</li>
<li>» 有點累想歇一下好長一個標題</li>
<li class="last">» 有點累想歇一下好長一個標題</li>
</ul>
</div>
我沒亂說,你肯定見到類似的程式碼千百遍了?是的,它確實能夠解決我們的問題,請看 DEMO1
傳說中的first/last解決方案,程式碼如下:
#demo .last{
border-bottom: 0 none;
}
使用特殊的class來單獨處理這項,但我不是很喜歡這樣的code,原因大致有:
- 需單獨定義一個差異化的class;
- 不利於資料迴圈輸出,因為還得判斷是否最後一項;
margin的神來之筆
基於以上的原因,肯定會有其它的解決方案出現,這時margin無疑是非常不錯的選擇,來看程式碼:
#demo{
overflow:hidden;
}
#demo ul{
margin-bottom: -1px;
}
CSS程式碼如上,HTML程式碼當時使用開篇時的那段,結果請看:DEMO2
margin解決方案
是不是很Cool,完全避免了上述的問題,並且程式碼量很小。至於為什麼可以這樣實現,前幾篇文章裡有說過,margin是互動的,能影響其上下文的佈局。本例中,當 ul margin-bottom:-1px
,其本身的高並不會被改變,但其相鄰的元素則會往上 1px
,這時相鄰的元素即其包含塊 #demo,所以給 #demo overflow:hidden
,就直接將那 1px 的邊框給裁剪掉了。
再來個相似的需求
看看下述的 圖二
,這應該也是一種非常常見的圖片列表需求:
只關注圖片之間的間隙,我們發現3張圖片,卻只有2個間隙。不論你是用 margin-left
或者說是 margin-right
,都無法直接達成這個需求。
當然,可以像 DEMO1
那樣給第一個或者最後一個新增一個特殊類 first/last 來解決。但這種方式剛被說不喜歡,所以想想用 margin
方式吧,思路應該說是和 DEMO2
毫無二致。來看程式碼:
CSS
#demo{
overflow:hidden;
}
#demo ul{
margin-right:-10px;
}
HTML
<div id="demo">
<h3>圖片列表</h3>
<ul>
<li><img src="images/1.jpg" alt="" /></li>
<li><img src="images/2.jpg" alt="" /></li>
<li><img src="images/1.jpg" alt="" /></li>
</ul>
</div>
恩,就這麼簡單,很美妙。效果可移步 DEMO3
margin處理圖片列表間隙解決方案
我知道不少人還會使用給圖片列表容器加寬度的方式來進行處理,當然,它很OK,不過不夠靈活,因為在不同場景下,寬度可能不一樣,這樣的code無法被提取為公用樣式,複用性不強。
而 margin
的方式完全不care幾乎任何場景,都可以使用,因為在大多數情況,我們這樣一個圖片模組都是自適應寬度的,因為它會處於某個layout下,寬度完全取決於layout,所以其實在真實場景下 #demo 的 overflow
並不是必須的,也就是說 margin-right
的負值理論上可以預設成一個很大的值。
CSS
#demo ul{
margin-right:-100px; /* 這個可以設定得比li的間隙更大,所以理論上可以寫一次而適用於真實場景的任何情況 */
}
看我們簡單還原的真實場景使用方式:DEMO3
模擬真實場景:margin處理圖片列表間隙解決方案。恩,就這樣,靈活性和可擴充套件性爆棚,不是麼?
縮排例項
依然先貼個圖,以下是 圖三
:
貌似是個好常見的需求場景,當然,要實現這樣的效果,對於大家來說都不過是信手拈來,再容易不過。
HTML
<div>
<strong>簡介:</strong>
<p>該寫點什麼好呢?好頭痛,一個能把value念成“哇柳”的中老年人,猛然覺得沒文化好可怕。</p>
</div>
你可能隨手就會寫下 float + margin/padding
,float + bfc
,absolute + margin/padding
,flex
等方案中的隨意一個,恩,都很Cool,我也常這麼幹。
只是有的時候在一個小場景下,希望能比較輕量的出來這樣的縮排,可能不想有浮動,絕對定位,清除浮動之類的,怎麼破?
margin依然是你很好的選擇
你想到了嗎?是的,用margin。
HTML
<p><strong>簡介:</strong>該寫點什麼好呢?好頭痛,一個能把value念成“哇柳”的中老年人,猛然覺得沒文化好可怕。</p>
CSS
p{
padding-left:45px;
}
strong{
margin-left:-45px;
}
看起來很簡單,沒有浮動,沒有絕對定位,沒有其它重佈局,很清涼有木有?
甚至 HTML
也可以更簡單,因為無需對後面那長段做任何處理,所以不需要再加包裹。來看看具體例子吧。DEMO4
margin縮排例項。我想這樣的輕量方式,在一定時候還是有使用價值的,不是麼?
視覺欺騙偽等高
等高佈局在一段時間內好似挺火,方案也湧現過不少,如 圖四
:
該圖要求,不論是主欄還是側欄,總是以最高的那列為基準高度。核心程式碼:
CSS
#doc{
overflow:hidden;
}
#main,#aside{
margin-bottom:-999px;
padding-bottom:999px;
}
HTML
<div id="doc">
<div id="main">主內容欄<br />佔位內容</div>
<div id="aside">側邊欄</div>
</div>
先看看結果:DEMO5
margin偽等高佈局
效果和我們的要求一致,達到了等高佈局。需要提醒的是,這其實只是視覺欺騙,做到的了偽高等高。主欄和側欄的實際高度其實並不相等,之所以可以達成這樣的效果,其原因在於負 margin
值。我們前文中有提到過,margin
會影響其上下文佈局,當我們將 margin-bottom
設定為負值時,其相鄰的包含塊元素,底部會自動上去其負值的高度,直到最高的那列底部邊緣為止,然後裁剪。但該列本身的高度並不會發生變化,同時因為有 padding-bottom
向下擴充套件,顏色被填充滿padding區域,於是達到視覺上的等高。
描述的貌似有點複雜,沒文化好可怕。差不多就這樣,不能接著往下寫了,要不收不住。
作為 CSS 的重要屬性 margin
有很多可被挖掘的潛力,需要更多的是想法。enjoy it.
margin系列文章:
相關文章
- margin系列之內秀篇(二)
- margin系列之佈局篇
- margin系列之bug巡演
- margin系列之bug巡演(二)
- margin系列之bug巡演(三)
- margin系列之keyword auto
- margin系列之百分比
- margin系列之與相對偏移的異同
- margin系列之外邊距摺疊
- webpack系列之-原理篇Web
- Margin 的特異之處
- SpringCloud系列之Nacos應用篇SpringGCCloud
- css之margin && padding講解CSSpadding
- dart系列之:dart優秀的祕訣-隔離機制Dart
- iOS動畫系列之四:基礎動畫之平移篇iOS動畫
- 行內元素的padding和margin屬性padding
- 行內元素的padding和margin是否有效padding
- 密碼學系列之:內容嗅探密碼學
- netty系列之:內建的Frame detectionNetty
- iOS動畫系列之五:基礎動畫之縮放篇&旋轉篇Swift+OCiOS動畫Swift
- 持續輸出面試題系列之ZooKeeper篇面試題
- 死磕 java同步系列之AQS終篇(面試)JavaAQS面試
- SpringCloud系列之Nacos+Dubbo應用篇SpringGCCloud
- WebSocket系列之基礎知識入門篇Web
- Backbone系列篇之Backbone.Events原始碼解析原始碼
- Asp.Net MVC 系列--進階篇之FilterASP.NETMVCFilter
- 解決margin塌陷和margin合併
- underscore 系列之內部函式 cb 和 optimizeCb函式
- 【學習筆記】CSS深入理解之margin筆記CSS
- css marginCSS
- margin 塌陷
- SpringCloud系列之閘道器(Gateway)應用篇SpringGCCloudGateway
- Docker系列開篇之Virtual Machine VS Container(一)DockerMacAI
- SpringCloud系列之Nacos+Dubbo+Seata應用篇SpringGCCloud
- 快速Android開發系列網路篇之RetrofitAndroid
- 快速Android開發系列通訊篇之EventBusAndroid
- dart系列之:dart語言中的內建型別Dart型別
- 國內優秀MES開源框架框架