理解並運用CSS的負margin值

2020-12-14 TechWeb

推廣 | 令人窒息的獎品等你―2016最權威的全球開發者調研

本文樣式代碼採用 SCSS。

瀏覽器兼容性為 IE6+。

你的網頁中,不可能沒有使用過 margin。大多數情況下,我們採用的都是正數的 margin 值,可能有時候會用到負的 margin 值。在我們的印象中,負的 margin 值就類似於瀏覽器的 hack 一樣,不被人接受。但是,本文要說明的就是,負的 margin 值並不是 hack,這是正常範圍內的寫法。

Negative values for margin properties are allowed, but there may be implementation-specific limits. —— W3C

根據 W3C,margin 是能夠接受負值的,只是在具體實現上有一些區別。

那麼,設置 margin 為負值究竟會是什麼樣的效果呢?

與設置正值不同,margin 設置負值需要根據設置的方向以及元素是否浮動以及其定位方式來判斷最終的行為。

所以,具體行為按照以下幾種情況說明。

第一種情況:元素沒有設置浮動且沒有設置定位或者 position 為 static

如果元素沒有設置浮動並且沒有設置定位或者 position 屬性為 static 的情況下,對元素的 margin 設置負值會有以下的效果:

設置的 margin 的方向為 top 或者 left

當設置負值的 margin 的方向為 top 或者 left 的時候,元素會按照設置的方向移動相應的距離。

比如,設置 margin-left: -100px;。 那麼,元素會往左移動 100px。對於設置 margin-top 也是一樣的道理。

設置的 margin 的方向為 bottom 或者 right

當設置負值的 margin 的方向為 bottom 或者 right 的時候,元素本身並不會移動,元素後面的其他元素會往該元素的方向移動相應的距離,並且覆蓋在該元素上面。

比如,設置 margin-right: -100px;。那麼,元素本身並不會移動,後面的元素會向左移動 100px 到該元素上。對於設置 margin-bottom 也是同樣的道理。

同時,在元素不指定寬度的情況下,如果設置 margin-left 或者 margin-right 為負值的話,會在元素對應的方向上增加其寬度。效果就和設置 padding-left 或者 padding-right 一樣。

第二種情況:元素沒有設置浮動且 position 為 relative

如果元素沒有設置浮動,但是設置了相對定位,設置 margin 為負值的時候,表現如下:

設置的 margin 的方向為 top 或者 left

當設置負值的 margin 的方向為 top 或者 left 的時候,元素也會按照設置的方向移動相應的距離。

設置的 margin 的方向為 bottom 或者 right

當設置 margin-bottom/left 的時候,元素本身也不會移動,元素後面的其他元素也會往該元素的方向移動相應的距離,但是,該元素會覆蓋在後面的元素上面 (當然,此處說的情況肯定是後面的元素沒有設置定位以及 z-index 的情況)。

第三種情況:元素沒有設置浮動且 position 為 absolute

如果元素沒有設置浮動,但是設置了絕對定位,設置 margin 為負值的時候,表現如下:

設置的 margin 的方向為 top 或者 left

當設置負值的 margin 的方向為 top 或者 left 的時候,元素也會按照設置的方向移動相應的距離。

設置的 margin 的方向為 bottom 或者 right

由於設置絕對定位的元素已經脫離了標準文檔流,所以,設置 margin-right/bottom 對後面的元素並沒有影響。

第四種情況:元素設置了浮動

肯定沒有既設置了浮動又設置絕對定位的情況,那樣太荒唐了。

設置了浮動的元素,再設置 postion: relative; 的話,元素的行為和單獨設置 float 是一樣的。

對於設置了浮動的元素,設置 margin 為負值的時候,表現如下:

如果設置的 margin 的方向與浮動的方向相同,那麼,元素會往對應的方向移動對應的距離。

比如:

.elem {    float: right;    margin-right: -100px;  }  

該元素則會向右移動 100px。

如果設置 margin 的方向與浮動的方向相反,則元素本身不動,元素之前或者之後的元素會向鈣元素的方向移動相應的距離。

比如:

.elem {    float: right;    margin-left: -100px;  }  

位於該元素左邊的元素則會向右移動 100px,同時覆蓋在該元素上。

如果後面的元素也設置了浮動的話,我們以一個具體的例子來說明。

<div class="container">     <div class="left"></div>     <div class="right"></div> </div>   .container {     min-height: 300px;     margin: 30px auto;     overflow: hidden;     border: 1px solid #000000;         .left {         float: left;         width: 400px;         height: 200px;         margin-right: -300px;         background: purple;     }          .right {         float: left;         width: 300px;         height: 200px;         background: #cccccc;     } }  

.left 和 .right 都設置了浮動,在 .left 上設置了 margin-right: -300px;,那麼,.right 會向左移動 300px,從而覆蓋在.left 上。這種行為與沒有既沒有設置浮動也沒有設置定位的表現類似。

到此,我們把設置負 margin 的各種情況以及在各種情況下的表現都大概了解了一遍。那麼,我們真正運用到實際中會是什麼樣子呢。

半遮擋的標題

原諒我措辭不好,大概就是下圖的效果:

按照一般的思想,肯定是直接給 title 設置絕對定位,然後再將其調整過去。

但是,按照我們現在所說的,其實很簡單就能實現這個效果。

這裡只寫了主要部分的代碼。

<div class="title">Hey This is title!</div>  <div class="content">Hah! This is content.</div>   .title {     position: relative;     width: 200px;     height: 60px;     margin-bottom: -30px;     margin-left: -20px;     background: #000000; }  .content {     max-width: 800px;     height: 400px;     padding: 0 50px;     background: yellow; }  

我們為 title 設置了兩個 margin 的負值,分別是 margin-bottom: -30px;,以及 margin-left: -20px;。

設置 margin-bottom 是為了讓 content 向上移動,設置 margin-left 是為了讓 title 向左移動一小段距離。

還有個需要注意的地方就是,需要給 title 設置 position: relative;,根據我們的第二種情況所說的,這樣,才能保證 title 覆蓋在 content 之上。

簡單的一列定寬的兩列流式布局

根據我們的最後一種情況,通過設置 margin 為負值,我們可以很容易的實現一列定寬的兩列流式布局。

<div class="container">  <div class="left"></div>  <div class="right"></div>  </div>   .left {     float: left;     width: 100%;     height: 200px;     margin-right: -300px;     background: purple; } .right {     float: left;     width: 300px;     height: 200px;     background: #cccccc; }  

唯一需要注意的地方就是設置了 100% 寬度的元素上的 margin 負值的絕對值一定要和定寬的元素的寬度相同。

兩邊固定,中間自適應的三列布局

這是一個很老的話題了,以前也有各種實現的方式,比如雙飛翼布局,或者聖杯布局。

我們此處就以雙飛翼布局來作示例。

先設置頁面結構:

<div class="container">  <div class="center"></div>  <div class="left"></div>  <div class="right"></div>  </div>  

此處我們沒有把 center 放在中間,具體原因後面會解釋。

然後,我們設置這三列都浮動:

.left, .right, .center {     float: left;     height: 500px; }  

同時為他們指定寬度:

.left {     width: 300px;     background: #000000; }  .right {     width: 400px;     background: #00FFFF; }  .center {     width: 100%;     background: #93c759; }  

現在我們要讓 left 在左邊,相當於就是讓它覆蓋在 center 的上面,所以,只需要這樣一句:

margin-left: -100%; 

同時,要讓 right 在右邊,同理,這樣設置:

margin-left: -400px; 

注意,此處的 margin 值的絕對值與 right 的寬度值相同。

其實,這樣設置,我們的三列布局就基本完成了。

那麼,我們為什麼要把 center 放在 left 和 right 之前呢?

這個其實涉及到元素的堆疊順序的知識 (這裡就不詳細講解了,後面有時間的話專門拿一篇文章來講解吧),此處簡單說明一下。

由於我們的三列都設置了浮動,所以,從某種意義上說,它們三個是在同一個平面的 (相當於 z-index 相同),那麼,這裡就不能根據 CSS 來判斷堆疊順序了。所以,此處的 HTML 結構就決定了它們的堆疊順序:所謂後來居上。

我們要讓 left 在 center 之上,所以,肯定需要讓 left 元素放在 center 之前。

所以,三列布局完整的 SCSS 代碼如下:

.container {     overflow: hidden;          .left,     .right,     .center {         float: left;         height: 500px;     }          .left {         width: 300px;         margin-left: -100%;         background: #000000;     }          .right {         width: 400px;         margin-left: -400px;         background: #00FFFF;     }          .center {         width: 100%;         background: #93c759;     } }  

References

margin-properties | W3C

The Definitive Guide to Using Negative Margins

雙飛翼布局和聖杯布局的對比

點讚 0

相關焦點

  • CSS margin屬性與用法教程
    margin 屬性是css用於在一個聲明中設置所有 margin 屬性的簡寫屬性,margin是css控制塊級元素之間的距離
  • DIV+CSS中padding和margin屬性用法
    理解Box model的關鍵便是margin和padding屬性,,而正確理解這兩個屬性也是學習用css布局的關鍵。以下說明margin和padding屬性:1.Margin:包括margin-top,margin-right,margin-bottom,margin-left,控制塊級元素之間的距離,它們是透明不可見的,對於Fig.2所示的上右下左margin值均為40px,因此代碼為:margin-top:40px
  • 【面試題】CSS知識點整理(附答案)
    因為,當margin/padding取形式為百分比的值時,無論是left/right,還是top/bottom,都是以父元素的width為參照物的!css實現寬高比[2]3.父級添加overflow屬性:包含浮動元素的父標籤添加樣式overflow為hidden或auto,通過觸發BFC方式,實現清除浮動清除浮動的四種方式及其原理理解[14]10. postcss我們都知道」babel「的存在,可以讓我們使用比較新的js語法,postcss則可以理解為CSS的」babel「,可以讓我們使用比較新的CSS語法
  • 不要告訴我你懂margin
    你真的了解margin嗎?你知道margin有什麼特性嗎?你知道什麼是垂直外邊距合併?margin在塊元素、內聯元素中的區別?什麼時候該用 padding而不是margin?你知道負margin嗎?你知道負margin在實際工作中的用途嗎?常見的瀏覽器下margin出現的bug有哪些?
  • 前端進階:css必知的幾個底層知識和技巧
    在介紹完問題學習法之後,進入我們今天的主題,接下來我會介紹css的一些底層的知識的現象,藉此來讓大家對css有更深入的理解。>「正正取大值」,」正負值相加」,」負負最負值」4.深入理解margin:auto如果一側定值,一側auto,則auto為剩餘空間大小如果兩側均是auto,則平分剩餘空間觸發margin
  • 理解CSS3 max/min-content及fit-content等width值
    也就是我們平常所說的盒模型的margin,border,padding的尺寸填充。四、理解width:max-contentmax-content的行為表現可以這麼理解,假設我們的容器有足夠的寬度,足夠的空間,此時,所佔據的寬度是就是max-content所表示的尺寸。不懂沒關係,我們看一個對比示例,保證立馬就知道!
  • 【專欄試讀】(07)CSS 基本視覺格式化:① 「塊盒子」格式化 | CSS
    在這 7 個屬性中只有 3 個屬性的值可以設置為 auto:width、margin-left、margin-right。其餘的要不必須是確定的值,要不就是默認值 0。同理,在這 7 個屬性中只有 3 個的值可以設置為 auto:height、margin-top、margin-bottom。其餘的要不必須是確定的值,要不就是默認值 0。❗️不過,margin-top 和 margin-bottom 設置為 auto 也沒有什麼用,因為會被重置為 0。所以,想利用上下 margin 都是 auto 來垂直居中是不可能的。
  • 面試必備 css面試必考點
    6 居中布局行內元素: text-align:center塊級元素: margin:0 auto絕對定位和移動: absolute + transform絕對定位和負邊距: absolute + marginflex布局: flex + justify-content:center
  • 前端進階: css必知的幾個底層知識和技巧
    在介紹完問題學習法之後,進入我們今天的主題,接下來我會介紹css的一些底層的知識和比較詭異的現象,藉此來讓大家對css有更深入的理解。一.css尺寸1.首選最小寬度–實現複雜圖形效果在css中,圖片和文字的權重遠大於布局,因此當width:0時表現出來的寬度就是「首選最小寬度」。中文的最小寬度為每個漢字的寬度,西方文字取決於連續的英文字符單元。
  • 10個關於css高頻面試題
    CSS3中新增的選擇器以及屬性這裡只是列出來, 具體的使用,請查看我的關於css3新增選擇器與屬性文章屬性選擇器含義描述E[att^="val"]屬性att的值以"val"開頭的元素E[att$="val"]屬性att的值以"val"結尾的元素E[att*="val"]屬性att的值包含
  • CSS布局奇技淫巧:各種居中
    居中是我們使用css來布局時常遇到的情況。使用css來進行居中時,有時一個屬性就能搞定,有時則需要一定的技巧才能兼容到所有瀏覽器,本文就居中的一些常用方法做個簡單的介紹。把margin設為auto 具體來說就是把要居中的元素的margin-left和margin-right都設為auto,此方法只能進行水平的居中,且對浮動元素或絕對定位元素無效。 2、使用 text-align:center 這個沒什麼好說的,只能對圖片,按鈕,文字等行內元素(display為inline或inline-block等)進行水平居中。
  • 前端基礎篇之CSS世界
    我想你每天寫css代碼有時候也會覺得很痛苦:這個布局的css怎麼這麼難實現!我也經常會有這種感覺,一個看似簡單的布局總是要琢磨半天才能實現,偶爾還會出現一些怪異的超出理解的現象。這是因為我們對css只是大概知道個形,並沒有看透css的本質。在同事的推薦下我閱讀了張鑫旭老師的《css世界》,才發現css跟想像中的不太一樣。
  • 10 個 CSS 高頻面試題,你都會嗎?
    CSS3中新增的選擇器以及屬性這裡只是列出來, 具體的使用,請查看我的關於css3新增選擇器與屬性文章屬性選擇器含義描述E[att^="val"]屬性att的值以"val"開頭的元素E[att$="val"]屬性att的值以"val"結尾的元素E[att*="val"]屬性att的值包含
  • css3必須了解的知識 css中常見的樣式屬性和值
    繼續上一篇文章的繼續了解css的基礎知識 全棧學習筆記,不同平臺不同的我!css中常見的樣式屬性和值字體與顏色背景屬性文本屬性邊框屬性,padding是向內擴展的*/ margin-top: 2px; margin-right: 3px; margin-bottom: 4px; margin-left: 6px; /*上面四句和下面一句也是等效的*
  • CSS中Padding簡寫用法介紹
    作者:admin來源:div-css.net|2010-08-24 16:35 本文向大家描述一下CSS
  • css常見問題:塊級元素和行內元素在水平和垂直方向怎樣居中呢?
    利用margin:0 auto進行水平方向居中css部分代碼示例:利用絕對定位+margin : auto進行水平方向居中css部分代碼示例:利用絕對定位+margin : auto進行垂直方向居中css部分代碼示例:
  • 弄懂css盒子模型從這幾點入手,新手建議收藏!
    怎麼理解盒子模型?盒子模型是樣式表(css)控制頁面的很重要的概念。如果理解了盒子模型和其中每個元素的用法,才能熟練使用css的定位方法和技巧。所有的頁面的元素都可以看成是一個盒子,佔據一定的頁面空間。佔據的空間要比實際使用的空間要大得多。
  • CSS margin-bottom屬性使用秘訣
    CSS margin-bottom屬性使用秘訣 本文向大家描述一下CSS margin-bottom屬性的用法,margin-bottom屬性設置元素的下外邊距,並且允許使用負值,希望本文介紹對你有所幫助。
  • 巧用margin/padding的百分比值實現高度自適應
    一個基礎卻又容易混淆的css知識點本文依賴於一個基礎卻又容易混淆的css知識點:當margin/padding取形式為百分比的值時,無論是left/right,還是top/bottom,都是以父元素的width為參照物的!
  • 104道 CSS 面試題,助你查漏補缺(上)
    譬如外邊距(margin)的重疊,浮動清除,觸發ie的haslayout屬性等。來龍去脈大概如下:當設置了zoom的值之後,所設置的元素就會就會擴大或者縮小,高度寬度就會重新計算了,這裡一旦改變zoom值時其實也會發生重新渲染,運用這個原理,也就解決了ie下子元素浮動時候父元素不隨著自動擴大的問題。