可愛的rem

call_me_R發表於2018-09-16

frontend/css/rem/banner

前端開發中,移動端的開發可以說是舉足輕重了,可是又面臨著不同裝置尺寸和解析度的尷尬點。今天[2018-09-16]颱風山竹登陸廣東,來勢洶洶,外出是不可能的了,那就宅著寫寫這篇小文章吧...原文請戳這裡-談談rem單位

超長的前奏

說到移動端的響應佈局,你也許會想到:

1. 使用CSS3媒體查詢的方法

body {
	background: yellow;
}
@media screen and (max-width: 400px) {
	body {
		background: red;
	}
}
複製程式碼

frontend/css/rem/media_demo

嗯,這種的樣式的工作量超級大,因為要對圖片和文字等資源針對不同的尺寸進行設定。一種涼涼的感覺從心底飄過~~~

2. 直接使用百分比

這種方法比較適合移動端上,頁面圖片鋪滿寬度螢幕的運營推廣活動的情況。因為在設計的時候會有一個750px的寬等等設計規範,能夠很好的適配到不同手機啦。然後工作就是切圖了...

#percent{
	width: 100%;
	display: flex;
	flex-direction: row;
	justify-content: center;
	align-items: center;
}
#percent .item{
	flex: 1;
}
#percent .item img{
	display: block;
	width: 100%;
	height: auto;
}
複製程式碼

frontend/css/rem/percent_demo

這種切圖比較費力,如果認真看上面的gif圖的話會發現是三張同等寬高的圖片,在chrome上的偵錯程式上看是有白條的,不過不影響。因為在真機上是不存在的。如果不是切圖寬度等分的情況下,那就不建議這種百分比的適配方法了。

3. 固定寬度

這種方法比較適合PC端開發,在移動端是必須不能才去的。因為移動端的寬度足夠,能夠帶來足夠好的體驗,並且最重要的一點是其畫素比是1啊。在縮放的時候不會帶來內容變形的體驗。如果到移動端上面,那就呵呵了~

#container{
	width: 680px;
	background: yellow;
	margin: 0 auto;
}
h1{
	text-align: center;
}
複製程式碼

frontend/css/rem/fixed_width_demo

4. 使用viewport

移動裝置上的viewport是裝置螢幕上用來顯示網頁的那部分割槽域,再具體一點就是瀏覽器上用來顯示網頁的那部分割槽域,但viewport又不侷限於瀏覽器可視區域的大小,它可能比瀏覽器的可視區域大,也可能比瀏覽器的可視區域小。

這得要在網頁的head標籤上面設定meta,比如:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
複製程式碼

嗯,這個知識點還是一丟丟的,詳細的內容參考菜鳥教程:響應式 Web 設計 - Viewport。 本博文的重點不是這個~

是的,我們可以使用REM來進行適配啊:可以說是目前最強的移動端適配方案...

frontend/talk-about-gobang-game/qiaoba

rem是什麼

rem和em單位一樣,都是一個相對單位,不同的是em是相對於父元素的font-size進行計算,rem是相對於根元素htmlfont-size進行計算的,這樣一來rem就完美的繞開了複雜的層級關係,實現了類似em單位的功能。預設情況下,瀏覽器給的字型大小是16px,按照轉化關係16px = 1rem

咦,都是固定了根元素是預設16px了,如何裝置不同的移動裝置呢?

問題提出也是答案所在,我們動態改變根元素html的字型預設大小不就行了嘛!見下:

rem自適應處理方案

使用rem佈局的時候,為了相容不同的解析度,我們應該要動態的修正根字型的大小,讓所有的用rem單位的子元素跟著一起縮放,從而達到自適應的效果。

嗯,下面就是動態改變根字型的大小了,採取的當然是javascript來進行控制啦,不然怎麼知道畫素比哦。

一種是獲取畫素比【畫素比=物理畫素/邏輯畫素】通過devicePixelRatio,其相容性在ie上要在11及11+,相容性良好。罷了,不討論IE瀏覽器了,看者慎用IE...

(function(){
	var devicePixelRatio = window.devicePixelRatio || 1;
})();
複製程式碼

嗯,在移動端上面適配,rem和viewport搭配效果更佳哦!完整程式碼片段如下:

<head>
	<meta name="viewport" />
</head>
複製程式碼
(function(){
	var fontSizeMatchDeviceWidth = function(){
		var deviceWidth = document.documentElement.clientWidth || window.screen.width || 320,
			devicePixelRatio = window.devicePixelRatio || 1,
			fontSize = (Math.ceil(deviceWidth * 16 / 320)),
			scale = 1 / devicePixelRatio; // 預設的縮放
			
		document.documentElement.style.fontSize = fontSize + 'px';
		document.querySelector('meta[name="viewport"]').setAttribute('content','width=device-width,initial-scale='+'scale'+',maximum-scale='+scale+',minimum-scale='+scale+',user-scalable=no,viewport-fit=cover'); // 增加viewport-fit=cover適配iphone x
	};
	
	(function(){
		var ua = navigator.userAgent;
		if(/android/i.test(ua) || /ipad|itouch|iphone/i.test(ua)|| /tianqi/i.test(ua)){
			fontSizeMatchDeviceWidth();
		} else { // pc端優雅降級
			document.documentElement.style.fontSize = '24px';
		}
	})();
})();
複製程式碼

在上面的基礎上,新增點點樣式,完整的一個demo走一下:

#container{
	background: yellow;
	margin: 0 auto;
}
h1{
	text-align: center;
}
複製程式碼

frontend/css/rem/rem_demo

如有紕漏,歡迎看到的各位小哥哥小姐姐指正 @~@! 更多內容請前往我的github

frontend/css/rem/qiaoba2

相關文章