你知道我們平時在CSS中寫的%都是相對於誰嗎?
本文作者:IMWeb jerryOnlyZRJ
原文出處:你知道我們平時在CSS中寫的%都是相對於誰嗎? - 騰訊Web前端 IMWeb 團隊社區
0.引言
在我們編寫CSS的時候,經常會用到百分比賦值(%)實現自適應。像我們最常使用的流式布局設計模式,基本所有的column的寬度都是通過%來取值的。或者比如經常會遇到的元素水平垂直居中問題,我們常常會使用下面這樣的CSS代碼加以實現(absolute+transform思路):
.wrap { position:absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);}
大家因為經常使用,肯定都知道前面兩個50%指的是wrap的定位參照物的寬、高的50%,而translate()里的50%指的是wrap自身,這應該不會有什麼疑問,但在這簡單的三行代碼中,就出現了兩類不同的%值,一種是相對於參照物盒子的,一種是相對自身的。不過你以為CSS世界裡就只有這兩類百分比值嗎?一切可沒這麼簡單,下面我會列舉出不同的情況下%值的參照對象,且聽我娓娓道來。
1.第一類——定位類
熟悉的小夥伴都知道CSS中的定位分為四種,默認值static,相對定位relative,絕對定位absolute還有固定定位fixed。雖然說每一類定位的%值的參照物都各不相同,但因為都具有定位的特殊性質,所以我把它們歸為一類,現在對四種不同的定位分類討論:
- static:這個就不用說了吧,position的默認值,並沒有對元素起到定位的作用,所以left、right等位置屬性並不能被有效賦值,所以不存在在定位功能上的%值。
- absolute:作為一個最為常用的定位屬性,absolute不知道給多少前端小白挖了數不清的坑,相信大家早年在這上面學習的過程都是艱辛的。不扯遠了,給一個元素absolute定位後就可以賦予left等位置值,參照物就是祖先元素中存在定位的元素,那麼自然而然,位置值如果取得是%,那麼這個%相對的元素便是這個參照物。left、right是相對於width,top和bottom是相對於height,這我就不必多說了吧。
- relative:小夥伴們肯定都聽說過子絕父相,而且肯定經常用,那麼relative它是相對與自身定位的,那麼位置值自然就是相對於自身的寬高嘍。
- fixed:這是一個很特殊的定位值,因為我們知道它是相對於視窗定位的,那麼自然%的參照物便是視窗了。
2.第二類——盒子模型
在一個盒子模型內有很多特別常見的屬性值,大家天天用也天天看,就是這些:width,height,margin,border,padding,width和height就不用說了,是相對於父盒子的,重點講下margin和padding
- margin&padding:這兩個小夥子很特別,如果設置了%值,那麼他們參照的是父元素的寬度!!父元素的寬度!!!父元素!!!寬度!!!重要的事情說三遍,不信的話我們可以親手試試。的確很奇葩,不過你還真得記住,別開發的時候糗了你還以為是BUG。我們可以使用padding的這一特殊性質實現16:9或4:3等各比例響應式圖片、視頻盒子的構建。
- border:border的話我一般是沒見過有人用%的值,如果你在開發的時候用的是%,請收下我的膝蓋。這邊要講的實際上是border-width,因為border實際上是個簡寫屬性。其實是騙你們的啦,border-width目前還不允許輸入%值,未來會不會允許並且參照的是誰都還是未知,如果你寫了%的值瀏覽器是不會渲染的哦,所以border不存在%值。
- border-radius:既然說到了border,就順帶提一下border-radius,圓角。平時我們用這個屬性的時候基本都是給他賦4個參數,代表四個角,分別是左上、右上、右下、左下,以順時針的順序排序。但實際上,border-radius最多可以取八個值,前四個值和後四個值用 / 隔開,斜杠前表示各角水平方向上的圓角半徑,斜杠後表示各角豎直方向上的圓角半徑。範例如下:
border-radius:top-left|top-right|bottom-right|border-left / top-left|top-right|bottom-right|border-left
3.第三類——背景值
- background-size:設置背景時常用的屬性,雖然我們平時常用contain或者cover代替,但是當我們想要讓背景充滿整個盒子的時候,也會這樣子寫:
background-size:100% 100%;
因此,background-size的參照物和border-radius一樣,都是盒子自身的寬高。
- background-position:這個屬性和relative類似,起到的也是定位的效果,因此它的參照對象就是原盒子。但是這個屬性比較特殊,他不是參照原盒子的寬高值,而是原盒子的寬高值減去背景圖片的寬高值所得到的剩餘值,更為形象的說,下面這兩個屬性值是等價的:"center center"和"50% 50%",如果你設置了後者,背景圖片會自動居中,不用像定位那樣還需要transform偏移了。這應該是優秀的前人在設計這個屬性的時候就考慮到它將來的應用了吧。
4.第四類——transform
- translate():在第一個模塊中,我們講到了這樣一個屬性:translate(),在CSS3中還有還有translate3d(),這個屬性的含義想必大家都知道,就是在指定方向上進行2d偏移,它的參照物是自身的寬高。而transform3d()的第三個屬性,指的是在z軸上的偏移,因為z-index的默認值是auto,所以%值並不能起作用,也就是說對translateZ()賦予百分比的值是無意義的。
- transform-origin:這個屬性是改變元素變形的原點,它和width還有height的特點一模一樣,這裡就不作過多詳述了。
- scale():控制元素的縮放比例,傳入的參數是一般是浮點數,指的是相對於元素本身放大或縮小的比例。
- zoom:zoom並不是transform的屬性值,它是一個獨立的CSS屬性,之所以把他放在transform這一個模塊討論,是因為恰好它與scale()有共同的特徵,它的取值既可以是浮點數,也可以是%,包括參照物,都與scale()等價。
5.第五類——字體
- font-size:這個屬性和我們的height一樣,是參照父盒子的字體大小的。
- line-height:我們所說的行高也是很特別的一個屬性,如果給它賦予不同類型的值,會有不同的特性。如果它的屬性值是一個無單位的數字,那麼最後的結果便是這個數字與該元素字體大小的乘積。這是我們設置line-height的首選方法,因為字體大小font-size是繼承自祖代元素的,通過這個方法設置的值基本不會出現異常情況。但如果我們的值是%,最後的結果是給定的百分比值乘以元素最後計算出的字體大小。
- text-indent:這個屬性是用來設置首行縮進的,我們最長用的是2em,首行縮進兩個字元,這邊的2em指的就是兩倍的font-size,按道理來說如果它取%應該也是要相對於本身的font-size的,但是偏偏就那麼特別,和padding和margin一樣,如果設置的是%,則參照的是父元素的width。這應該算是一個特例吧。
6.結語
大家可能大概看一遍下來還是一臉懵逼,為了給大家加強記憶,我就以參照物的不同類別為主線做個總結:
- 相對於父盒子:
最常見的應該就算是參照父盒子(containing box)的屬性,但是還有一些特例參照的是父盒子的width,只有這個類別還需要分兩類討論:
- 相對於盒子自身:
以盒子自身為參照的屬性就比較多了,參照的屬性一般也是與自身有關聯的屬性,屬於這一類的屬性值有:定位中的relative;盒子模型中的border-radius;背景中的background-size;背景中的background-position比較特殊,還記得嗎,它需要減去你的背景圖片的寬高,你可以聯想到flex布局中的flex屬性值;在transform變換中,translate()、transform-origin、scale()還有我們拓展的與transform相似的zoom屬性,他們都是參照自身的;line-height行高與它的字體大小有關,所以參照的就是自身的font-size。
- 相對於定位元素:
因為定位的性質比較特殊,所以將他單獨分出一類,定位元素參照的是他的定位對象,因為relative是相對於自身定位,所以我把他歸為相對盒子自身一類中去了,其他的屬性值我們都可以看作是參照他們的定位元素。
文章列出的所有屬性具體的一些屬性值的特性可以參考MDN官網,其實像上文列出的屬性,我們並不需要全部去記憶,也很難做到把所有的都記下來,很多時候,我們只需要自己在瀏覽器中測試一下就知道這些CSS是參照誰的啦。
最後留下一個小問題,如果不用px,只用%,如何實現一個寬高相等的正方形div?
成文不易,希望大家能多多支持,如果您有補充,歡迎在評論區里提出,謝謝。
原文作者Github:https://github.com/jerryOnlyZRJ
原文作者個人網站:http://jerryonlyzrj.com/
作者簡介: 騰訊NEXT學位課程 第三期學員,目前在開發一款基於Koa2的前端項目腳手架,以幫助前端開發者更為便捷、系統地構建一款Web項目,其進度會實時更新在Github上,大家能多多支持哦!
前端NEXT學位課程第六期招生正在火熱進行中!(點擊了解詳情)
感興趣的點擊下方鏈接聯繫我們的助教小姐姐哦~
http://qm.qq.com/cgi-bin/qm/qr?k=o7XWu49t6YAb6Vd0lW74oGE_xJzzKuN3 (二維碼自動識別)
推薦閱讀:
※如何批量恢復下載的日文網頁亂碼的文件名?
※Razor 生成的html格式可以調整嗎?
※知乎上很多前端大佬說,要做好前端的話html和css基礎必須夯實。那麼,達到什麼水平才能叫基礎夯實呢?
※CSS究竟是怎麼工作的?