『前端開發』- 相容IE8的響應式開發

Sakura同志發表於2019-03-14

相容IE8的響應式開發

全文概要:

1. 常用解決方案

2. 使IE8相容媒體查詢 @media

3. px和em和rem的霸主位置

4. 使IE8相容rem


常用解決方案

所謂響應式開發,就是指在不同的系統,裝置環境,不同的解析度下,介面進行不同的響應和調整適配

我們簡單理解為,在不同的瀏覽器上,不同解析度的顯示器上,我們的網頁能進行自適應響應調整,使得最後的介面還是能達到設計師高保真圖的效果。 在PC端開發中,經常會出現系統得相容IE8的要求,此次我們討論的是在這種需求下,如何達到所謂的響應式開發的要求。 常用的響應式開發解決方案(針對相容IE8的大前提下)有

  • 定寬法 天貓登入頁採用的方法是定寬法,即設定一個最小寬度min-width:1190px,瀏覽器小於這個寬度則出現橫向滾動條,如果大於這個寬度,則設定margin:auto使其自動左右居中。 這樣的好處是省事,相容性也好,但是缺陷就是在小螢幕解析度時,某些元素會變得比較大,有些突兀。即可能會出現不滿足於設計圖的比例的情況。元素在螢幕中Y軸的位置也會變化。 1920 * 1080下的天貓登入頁截圖
    1920*1080下的天貓登入頁.png

1600 * 900下的天貓登入頁截圖

1600*900下的天貓登入頁.png

  • 媒體查詢 + 引用多CSS法 讓IE8相容媒體查詢,即@media的方法在這先賣個關子,稍後我們會一一道來。 此方法的思路就是首先判斷當前的螢幕解析度或螢幕寬度,然後對於需求所要適配的解析度分別載入不同的CSS。 在這些不同的CSS中,我們可以按比例實現設計圖的需求,可以完美實現不同的解析度下都達到設計圖中的比例效果,元素在螢幕中的X軸和Y軸的位置也不會變化。但是缺陷也有,因為這裡的網頁的解析流程是先解析一些公共的CSS樣式,在執行指令碼判斷螢幕解析度,再進行載入相對應的CSS檔案,與此同時,解析樹可能已經開始解析DOM結構了,就可能會造成閃屏的結果(當然,也不一定會出現,我就沒有出現0.0)。所以問題就是會影響頁面的響應時間,但是這也有相應的解決方案,那就是服務端渲染,服務端判定傳送請求的系統環境和螢幕解析度等,來載入不同的CSS樣式表和JS指令碼。但這不是本文的重點,有興趣的同學可以自行探索哈!
// 此方法相容IE8
// 解析度大於等於1680,大部分為1920的情況下,呼叫此css
<script>
    if(window.screen.width >= 1680) {
        document.write('<link rel="stylesheet" href="../../css/oc_login_1920.css">');
    }
    // 解析度小於等於1600的情況下,呼叫此css
    else {
        document.write('<link rel="stylesheet" href="../../css/oc_login_1600.css">');
    }
</script>
複製程式碼

1920 * 1080下的登陸頁截圖

1920*1080下的登陸頁.png
1600 * 900下的登陸頁截圖
1600*900下的登陸頁.png

  • 媒體查詢 + em/rem法 此方法的奧義有些與上面的多CSS法類似,不過用了此方法的同學就會鄙視多CSS法的重複勞動的愚蠢了,因為這個方法用一個CSS就可以了,只不過寬度、高度等屬性單位得從px改為em或rem。 咦,你可能已經意識到了W3C不是從小教我們rem不相容IE8的嗎!那我們怎麼用rem啊! 答曰:照用,用點hack科技就好啦 0.0如果你好像都不知道em和rem是啥,emmmmm,往下滑滑,看了 px和em和rem的霸主位置 你就知道啦!
@media screen and (max-width: 1600px) {
	html {
		color: brown;
		font-size: 100%;
	}
}

@media screen and (min-width: 1601px) {
	html {
		color: blueviolet;
		font-size: 200%;
	}
}

//rem
.box {
	margin: 2rem;
}

//em
.box {
	margin: 2em;
}

複製程式碼

1920 * 1080下的巨醜Demo頁截圖

1920*1080下的巨醜Demo.png
1600 * 900下的巨醜Demo頁截圖
1600*900下的巨醜Demo.png


使IE8相容媒體查詢 @media

所謂媒體查詢,就是針對不同的螢幕尺寸設定不同的樣式,在響應式設計中,是非常有用的。

使用@media,在重置瀏覽器大小的過程中,頁面會根據瀏覽器的寬度和高度重新渲染頁面。 通常,我們只用到它的min-width和max-width屬性,這裡,我們也是。 但是可惜的是IE9才開始支援@media,其他主流瀏覽器早已支援,如何在IE8中也能使用@media呢?

  • hack科技之respond.js 下載地址:github.com/scottjehl/R… respond.js使IE6-8能夠支援@media的min-width和max-width屬性 使用需知:

    • 該指令碼不依賴於任何庫或框架,壓縮後大小為1kb左右
    • 該指令碼不解析@import匯入的CSS和內聯寫在style裡的CSS,所以建議使用link引入CSS
    • 該指令碼可能會不支援file:// url,該HTML得執行在web 伺服器上 什麼意思呢,同一個檔案在IE8中開啟,在http://127.0.0.1:8020/HelloHBuilder/Demo.html這種執行在web伺服器上的 就能夠正常使用該指令碼,但是直接本地開啟HTML,D:\HBuilderProject\HelloHBuilder\Demo.html類似這樣的檔案地址,該指令碼就會報錯,拒絕訪問。
    • CSS指令碼建議不要設成UTF-8,否則在IE7/8中可能會出現錯誤(我測試了一下,我這沒有出現),並且數量不要超過32個,否則IE會報Invalid procedure call or argument錯誤。
    • 該指令碼不支援Sass的source maps(生成檔案到原始檔的對映)
    • 不支援巢狀的媒體查詢

    工作原理:

    • 該指令碼首先通過Ajax請求遍歷所有外部連結的CSS檔案,並解析文字響應,在其內容上通過正規表示式來找到與媒體查詢相關聯的CSS塊,並根據他們的min-width和max-width與當前瀏覽器寬度進行比較,啟用和禁用相關的樣式程式碼,接著按順序將這些包含@media的CSS塊附加到頭部

    測試Demo:

    <!doctype html>
    <html>
    	<head>
    		<meta charset="UTF-8">
    		<title>HTML5-響應式佈局--respond.js-Sakura</title>
    		<link rel="stylesheet" href="test.css" charset="utf-8">
    		<script src="js/respond.min.js"></script>
    	</head>
    	<body>
    		<div>
    			使IE6~8支援響應式佈局——Sakura
    		</div>
    	</body>
    </html>
    複製程式碼

    CSS檔案:

    html,
    body {
       height: 100%;
    }
    
    @media only screen and (min-width: 480px) {
      body {
    	  background: blanchedalmond;
      }
    }
    
    @media only screen and (min-width: 640px) and (max-width: 1024px) {
       body {
    	   background: gray;
       }
    }
    
    @media screen and (min-width: 1024px) {
       body {
    	   background: coral;
       }
    }
    複製程式碼
  • 舊瓶新酒的window.screen.width 直接通過判斷window.screen.width的大小,來執行不同的樣式程式碼。此方法也相容IE8

    //此方法相容IE8
    // 解析度大於等於1680,大部分為1920的情況下,呼叫此css
    if(window.screen.width >= 1680) {
        document.write('<link rel="stylesheet" href="../../css/oc_login_1920.css">');
    }
    // 解析度小於等於1600的情況下,呼叫此css
    else {
     document.write('<link rel="stylesheet" href="../../css/oc_login_1600.css">');
    }
    複製程式碼

px和em和rem的霸主位置

在前端開發中,我們常用的長度單位有px,em,rem等,雖然都是相對單位,但由於參照物不同,各自特性也不同。

  • px是一個相對於螢幕解析度的畫素長度單位。比較穩定和精確,但是缺點也是此,在不同解析度下的響應式效果不好。但元素字型大小還是推薦使用px,因為點陣顯示緣故,某些數字17px等可能會出現讓字型出現鋸齒等顯示不友好的情況。但是不得不說,這是目前國內前端開發使用最多的長度單位,相容性完美
  • em是一個相對於父元素的字型大小(font-size)單位。特點是不是一成不變的,而是相對於父元素的font-size值變化而變化,如果父元素沒有設定font-size的值,則向上繼續尋找父元素的父元素的font-size,直到跟元素為止。**瀏覽器預設的font-size都為16px,通常別人會建議你設為font-size: 62.5%,如此一來基礎值font-size就變為10px,即10px = 1em,但是!你得chrome不能設定小於12px的font-size,當你設定小於12px時,chrome都以font-size: 12px呈現。**所以使用起來會存在一些煩惱,解決方案是,首先我們一般都會在body{}下設定font-size的值,但是如果我們要使用的em單位的元素已經被父級元素或者爺爺輩的人設定font-size大小汙染,那我們就在父元素重新設定font-size值為基礎值,實在不行,只有按照父元素的font-size比例重新算一次。
  • rem是一個相對於根元素的字型大小(font-size)單位。這是一個集於px精神和em優點於一身的單位,因為它是相對於根元素裡的font-size而變的單位,不會像em因為複雜的倫理關係而被干擾,所以在不同的解析度上的裝置中也可以體現穩定性,然後又具備響應性。聽起來真美好,但是但是!這哥們相容性還不夠啊,從IE9開始部分相容,直到IE11才開始完全相容,這與我們相容IE8的出發點差了一點點啊。通常大家使用rem的時候,如果需要提高相容性,就會同時使用px和rem兩個單位,先寫px再寫rem,如果瀏覽器支援rem,則rem會將先前的px給覆蓋,不支援也有預設的px可以支援,但是這樣子IE8的響應性也泡湯了。但是腦洞大一些,如果我不是使用px和rem而是同時使用em和rem,世界會不會有什麼不一樣?

使IE8相容rem

既然rem這麼美好,IE8卻不能使用,這很難受啊!別慌,接下來我們就來讓IE8也能相容rem。

  • hack科技之rem.js rem.js是一款讓IE8以下的瀏覽器都相容rem屬性的指令碼,其原理是一旦判斷當前瀏覽器不支援rem,該指令碼就讀取所有的外部連結CSS,並使用正則來查詢使用了rem的元素,然後將這些使用了rem的地方重新計算為px,並將其寫入head中,在內聯中重寫覆蓋。
  • 使用需知:
    1. 在所有CSS檔案引用之後引用rem.js,並在標籤的末尾引入rem.js
    2. 當你想rem.js跳過一些樣式表,只需將data-norem作為屬性新增到要忽略的CSS檔案的link引入上。值得一提的是,這個忽略效果只會在IE8上有效果, 為什麼呢?因為之後的瀏覽器都開始相容rem了啊哈哈哈哈。
  • demo
<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>

		<link rel="stylesheet" href="remDemo.css">
		<!--以下的css檔案在IE8瀏覽器中會被rem.js忽略-->
		<!--其他瀏覽器中依舊會顯示,因為其他瀏覽器支援rem!-->
		<link rel="stylesheet" type="text/css" href="test.css" data-norem />

		<script src="js/html5shiv.min.js"></script>
		<script src="js/respond.min.js"></script>
		<!--		<script src="js/jquery-1.8.3.min.js"></script>-->
	</head>

	<body>
		<div class="box">
			<p class="title">歡迎來到主介面
				<p class="content">這裡是叮叮咚咚</p>
			</p>
			<ul>
				<li>
					<label>姓名</label>
					<input type="text" class="name" />
				</li>
				<li>
					<label>姓名</label>
					<input type="text" class="password" />
				</li>
			</ul>
		</div>

		<script src="js/rem.min.js" type="text/javascript"></script>
	</body>

</html>
複製程式碼

test.css檔案

html,
body {
	height: 100%;
}

@media only screen and (min-width: 480px) {
	body {
		background: blanchedalmond;
	}
}

@media only screen and (min-width: 640px) and (max-width: 1024px) {
	body {
		background: gray;
	}
}

@media screen and (min-width: 1024px) {
	body {
		background: coral;
	}
}

li label {
	font-size: 2rem;
	margin-left: 4rem;
}
複製程式碼

remDemo.css檔案

@media screen and (max-width: 1600px) {
	html {
		color: brown;
		font-size: 200%;
	}
}

@media screen and (min-width: 1601px) {
	html {
		color: blueviolet;
		font-size: 400%;
	}
}

.box {
	margin: 2rem;
}

.title {
	margin: 2rem;
	font-size: 4rem;
}

.content {
	//margin-top: 8rem;
	font-size: 2rem;
}

input {
	margin-top: 1rem;
}
複製程式碼

19201080&&IE8下截圖

1920*1080&&IE8下
19201080&&chrome下截圖
1920*1080&&chrome下.png


至此,關於相容IE8的響應式開發已經全部結束了!撒花撒花撒花~

如圖小夥伴有疑問或者不知道那些js檔案去哪裡下載(去github上!!!按名字搜尋!),emmmm,實在沒辦法可以留言或郵箱M我,(應該)第一時間將這些檔案發回給小夥伴的!

【我的郵箱->】sakura_p@qq.com

技術開源,碼文不易,請尊重原創

相關文章