做了一組移動端的頁面,在布局時遇到了一些問題,總結下以避免再次掉坑。
遇到的問題:
1.圖片及帶背景圖片的塊寬高等比縮放布局
2.margin,padding百分比布局
圖片及帶有背景圖片的塊的圖片寬高等比縮放
純圖片可以使用img標簽,將其寬度設置成百分比,高度會自動按比例縮放。控制起來很方便。
帶背景圖片的div就有點麻煩了,背景圖可以使用background-size設置寬度百分比值,高度默認auto會按比例縮放。塊寬度可以使用百分比,但高度如果不設置具體像素數,會按照內容大小自動布局,這個問題處理起來有點點小麻煩。
解決方案1是使用邊框圖片布局,可以對圖片進行拉伸,但是也需要注意就是這個方案也只適用於邊框圖片是可拉伸或平鋪形狀的布局。LZ的圖片剛好是一個不規則形狀的圖,拉伸之后就變形了,也沒有辦法平鋪,不能用這個方案的,555~
border-image對於現代瀏覽器及移動端瀏覽器支持良好,在移動端是可以使用的,但是要加前綴。
可以具體看下邊框圖片怎么用:
border-image常設置的屬性是圖片url,剪裁位置,重復性。
其中:
剪裁位置:沒有單位的時候默認像素,支持百分比,百分比值大小相對於邊框圖片而言,假設邊框圖片大小為400px*300px,則20%的實際效果就是剪裁了圖片的60px 80px 60px 80px的四邊大小。順序是頂部區域、右側區域、底部區域、左側區域,裁剪圖示如下所示。
重復性:可以填repeat(重復),round(平鋪)和stretch(拉伸)。其中,stretch是默認值。
拉伸效果(默認拉伸):
.border_image{ width:400px; height:100px; -moz-border-image:url(../image/border.png) 27; -webkit-border-image:url(../image/border.png) 27; border:double orange 1em; }
平鋪效果:
.border_image{ width:400px; height:100px; -moz-border-image:url(../image/border.png) 27 round; -webkit-border-image:url(../image/border.png) 27 round; border:double orange 1em; }
由於圖片剪裁可以使用百分比(相對於圖片尺寸的百分比),就可以做到按比例縮放,按照內容大小進行適應。
解決方案2使用圖片占位符,此圖片的大小是需要的比例。例如2:1就把占位符做成2px*1px,例如5:3就把占位符做成5px*3px。然后放入img標簽里,設置寬度 100%,這樣高度就自動撐開,進而撐開外層父div。img平級放個子div,相對父div絕對定位,寬高100%,這樣子div的大小就和img一樣 大,實現等比縮放了。很糾結的一個方法。但這個方法也有問題。img標簽的大小,得里面的圖片占位符解析出來,才可以撐開父div。這就導致網頁一打開時,父div高度為0,等到圖片占位符解析完畢后,父div才得以撐開,所以網頁會閃動,體驗不好,也會影響js的計算模塊高度等問題。而且還增加一個src,這個圖片是完全對用戶不可見的,除了固定尺寸沒有任何用處,網頁會多出一次請求。LZ不會去用這糾結的方法。
在流式布局中,高度通常設置固定px,但是這樣做,在小屏設備和大屏設備中,有較明顯的差異。
解決方案3是使用百分比padding將塊支撐起來,但具體的百分比padding如何計算,下一塊詳解。
margin,padding百分比布局
這個主題其實就一個關鍵問題:margin,padding的百分比是按照誰的百分比計算的。
可以先想一下一個相關的問題:一個具有寬高的塊,設置margin:auto;上下左右都可以居中嗎?像下面這樣:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>test</title> <style type="text/css"> #content{width:300px;height:200px;background:pink;margin:auto;} </style> </head> <body> <div id="content"></div> </body> </html>
沒錯,它只有左右居中了,上下並沒有居中。
另外一個問題,假設一個塊級包含容器,寬1000px,高600px,塊級子元素定義margin:10% 5%;那么margin的top,right,bottom,left各是多少?
也可能很多人給出的答案是100px 30px 100px 30px,可以看看實際的情況:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>test</title> <style type="text/css"> #wrap{width:1000px;height:600px;background:pink;margin:auto;} #wrap p{margin:10% 5%;} </style> </head> <body> <div id="wrap"> <p>Yes.It is me.</p> </div> </body> </html>
看下結果:
是的,結果是100px 50px 100px 50px,上下左右邊距都是按照父元素的width計算的!
沒錯,這是正確的實現,居然和我想象的不一樣.
規范中注明了margin的百分比值參照其包含塊的寬度進行計算。當然,這只發生在writing-mode: horizontal-tb和direction:ltr的情況下。書寫模式是縱向的情況下,它會按照塊的高度來計算,就像下面這樣設置:
#wrap{ -webkit-writing-mode: vertical-rl; writing-mode: tb-rl; /* for ie */ }
這樣的設置,使得在水平和豎直方向上可以有相同尺寸的留白。
這其實更多的要從CSS設計意圖上去想,因為CSS的基礎需求是排版,而通常我們所見的橫排文字,其水平寬度一定(仔細回想一下,如果沒有顯式的定義寬度 或者強制一行顯示,都會遇到換行,而不是水平延展),垂直方向可以無限延展。但當書寫模式為縱向時,其參照就變成了高度而不再是寬度了。
padding的計算也是類似的,默認情況按照寬度來的。
再回頭想想,為什么margin:auto;不能在垂直方向上居中?其實原因也是上面所說的,因為縱向是可以無限延展的,所以沒有一個一定的值可以被參照被用來計算。
另外在微信瀏覽器里面,有標題欄,所以設計的時候需要考慮這幾十像素的標題欄,這和用模擬器略微有差別。其他軟件瀏覽器也類似,需要考慮。
參考:
- http://dev.w3.org/csswg/css-box/#the-margin-properties
- http://dev.w3.org/csswg/css-box/#ltpercentagegt
- http://dev.w3.org/csswg/css-box/#Calculating