PS:轉(zhuǎn)載請注明出處
作者: TigerChain
地址: http://www.reibang.com/p/443c6704d8d8
本文出自 TigerChain 簡書 手把手教 Vue 系列
教程簡介
- 1啤誊、閱讀對象
本篇教程適合新手閱讀岳瞭,老手直接略過 - 2、教程難度
初級蚊锹,本人水平有限瞳筏,文章內(nèi)容難免會出現(xiàn)問題,如果有問題歡迎指出牡昆,謝謝 - 3姚炕、Demo 地址:https://github.com/tigerchain/vue-lesson 請看 05、移動webapp適配--rem 這一節(jié)
正文
一丢烘、media query「媒體查詢」
在聊 rem 之前柱宦,我們先看看什么是 media query?
為了適配多種屏幕大到電腦,小到手機等播瞳, css3 中有了多媒體查詢這個功能「是繼承 css2 多媒體類型的思想」掸刊,通過 media query 就可以做響應(yīng)式的開發(fā)
1、media query 的作用
- 可以檢測 viewport(視窗) 的寬度與高度
- 可以檢測設(shè)備的寬度與高度
- 可以檢測設(shè)備的分辨率
2赢乓、media query 的語法
@media not|only mediatype and (expressions) {
CSS 代碼...;
}
我們可以看到 media query 由四部分組成
- 1忧侧、關(guān)鍵字:@media
- 2石窑、操作符:not|only|all 「默認不寫就是 all」
- 3、媒體類型:mediatype
- 4蚓炬、表達式:expressions
這里的媒體類型有以下幾種:
值 | 描述 |
---|---|
all | 用于所有多媒體類型設(shè)備 |
用于打印機 | |
screen | 用于電腦屏幕松逊,平板,智能手機等肯夏。 |
speech | 用于屏幕閱讀器 |
一般情況下我們使用 screen 的媒體類型是最多的
舉個例子
我們想讓在屏幕尺寸大于 375px 的設(shè)備上讓 class 為 div1 的背景顯示成紅色经宏,media query 哪下定義
@media screen and (min-device-width : 375px){
.div1 {
background-color:red;
}
}
我們可以針對不同的設(shè)備寬度來設(shè)置不同的樣式 ,這樣就達到了響應(yīng)式布局的效果驯击,現(xiàn)在我們來一個例子說明吧
3烁兰、demo 驗證 media query
效果如下
從上面的效果圖我們可以看到,我們針對不同屏幕寬度就會顯示不同的效果余耽,這就是響應(yīng)式布局缚柏,下面我們使用 media query 來實現(xiàn)這一效果
擼碼實現(xiàn)上述效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>media-query</title>
<!-- 重置默認的 css 樣式 ,類似于 reset.css -->
<link rel="stylesheet" href="../css/normalize.css">
<!-- https://necolas.github.io/normalize.css/7.0.0/normalize.css -->
<style>
.box {
width:100% ;
height:80px;
background-color: red;
}
/* 屏幕小于 375 px 則是下面的樣式 */
@media screen and (max-device-width : 375px){
.div1 {
width:25%;
background-color: green;
height:80px;
}
}
/* 屏幕大于 376 小于 414 px 則使用下面的樣式 */
@media screen and (min-device-width : 376px) and (max-device-width:414px){
.div1 {
width:50%;
background-color: blue;
height:80px;
}
}
/* 小于等于 375px 使用以下樣式 */
@media screen and (max-device-width: 375px) {
.menuitem1 {
height: 100px;
width: 100%;
background-color: yellow;
}
.menuitem2 {
height: 100px;
width: 100%;
background-color: blue;
}
.menuitem3 {
height: 100px;
width: 100%;
background-color: #cceedd;
}
.menuitem4 {
height: 100px;
width: 100%;
background-color: black;
}
}
/* 大于等于 376px 使用以下樣式 */
@media screen and (min-device-width: 376px) {
.menu {
display: flex;
}
.menuitem1 {
height: 100px;
width: 100%;
background-color: yellow;
}
.menuitem2 {
height: 100px;
width: 100%;
background-color: blue;
}
.menuitem3 {
height: 100px;
width: 100%;
background-color: #cceedd;
}
.menuitem4 {
height: 100px;
width: 100%;
background-color: black;
}
}
</style>
</head>
<body>
<div id="contnainer" class="box">
<div class="div1"></div>
</div>
<!-- mediaquery 實現(xiàn)響應(yīng)式布局 -->
<div class="menu">
<div class="menuitem1"></div>
<div class="menuitem2"></div>
<div class="menuitem3"></div>
<div class="menuitem4"></div>
</div>
</body>
</html>
以上代碼就實現(xiàn)了上述效果圖碟贾,代碼注釋清楚币喧,這里也不多說了
二、rem「font size of the root element」
1袱耽、什么是 rem
rem 就是根據(jù)網(wǎng)頁根元素「html」來設(shè)置字體大小,這有什么用呢杀餐?這是移動 webapp 的最佳的適配方案「目前來說」,既然說是最佳的適配方案朱巨,那肯定還有別的適配方案史翘,先看看都有那些適配方案吧
- 1、viewport縮放「被廢棄了」
- 2冀续、寬度固定兩邊留白「體驗很差」
- 3琼讽、響應(yīng)式布局「工作量太大,針對不同的分辨率寫一套 android 下估計開發(fā)者就瘋了」
2洪唐、如何適配
我們先來看一個簡單的例子吧钻蹬,然后就能得到一些啟發(fā)和感悟
- 1、新建一個 rem.html 然后輸入以下內(nèi)容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- 重置默認的 css 樣式 凭需,類似于 reset.css -->
<link rel="stylesheet" href="../css/normalize.css">
<title>rem demo</title>
<style>
.box {
width: 100px;
height: 100px;
background-color: red;
text-align: center;
}
.test {
font-size: 16px;
line-height: 100px;
}
</style>
</head>
<body>
<div class='box'>
<span class="test">測試</span>
</div>
</body>
</html>
很簡單就是一個寬高為 100px 的 div 并且里面有一個居中的文字大小為 16px
- 2问欠、運行查看結(jié)果
從圖中我們可以看到,不管我們是什么分辨率的機型下粒蜈,div 寬高都為 100px顺献,這是不合理的,根本就沒有適配「就是寫死的呀」
- 3枯怖、由于 2 中的效果是寫死的注整,我們來看看 rem 是如何適配的,稍微把代碼改一下
我們知道 rem 和 html 下的 font-size 有關(guān),我們來改代碼吧
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- 重置默認的 css 樣式 肿轨,類似于 reset.css -->
<link rel="stylesheet" href="../css/normalize.css">
<title>rem demo</title>
<style>
html {
font-size: 16px;
}
.box {
width: 10rem;
height: 10rem;
background-color: red;
text-align: center;
}
.test {
font-size: 1rem;
line-height: 10rem;
}
</style>
</head>
<body>
<div class='box'>
<span class="test">測試</span>
</div>
</body>
</html>
ps: 這里說明幾點
為什么這里 font-size 要寫成 16px ,因為大部分瀏覽的默認字體都是顯示 16px,我們從 chrome 調(diào)試工具中可以看到
html 默認的 font-size 大小就 = 1rem , 從上面代碼我們可以看到 box 的寬高都為 10rem 即 160px ,我們來驗證一下,運行看結(jié)果
果然是 160px「肯定在別的分辨率上也是 160px」借浊,這有個毛用呀,不就是把 100px 轉(zhuǎn)化成 160px 了嗎萝招?還不是沒有適配呀「大家是不是有這個疑問」,別急馬上揭曉答案
我們可以想一下存捺,rem 和 font-size 有關(guān)槐沼,那么如果我們能動態(tài)的修改 font-size 的大小,那么以 rem 為單位的寬高等不就自動適配了嗎捌治。我們來一下修改 font-size 的效果
看到了吧岗钩,我們手動修改 font-size 的值 div 的寬高就會動態(tài)改變「如果在不同分辨率的手機上設(shè)置不同和 font-size 那不就達到適配的效果了」
三、適配手段
我們知道只要動態(tài)的修改 font-size 使用 rem 就可以適配多種手機了
- 1肖油、通過 media query 來設(shè)置 font-size,比如:
html {
font-size : 20px;
}
@media only screen and (min-width: 401px){
html {
font-size: 25px !important;
}
}
@media only screen and (min-width: 450px){
html {
font-size: 26.75px !important;
}
}
@media only screen and (min-width: 481px){
html {
font-size: 30px !important;
}
}
- 2兼吓、通過 js 來設(shè)置
估計上面的方法能把人寫瘋,特別對于 android 這個多樣機型來說「一般只適配常用的分辨率」森枪,那就有了下面的方法视搏,使用 js 來動態(tài)設(shè)置 font-size
再說 js 動態(tài)修改 font-size 之前,先推導(dǎo)下 px 轉(zhuǎn)化成 rem 的公式:
比如:1rem = 16px「rem 的基準值」 ; 48px = 48/16 = 3rem,
所以得出:
rem = 需要轉(zhuǎn)化的px/rem基準值
rem 基準值「和 html 的 font-size 有關(guān)」如何算县袱,這里給出一個比較常見的做法浑娜,就是用設(shè)計稿的屏幕寬度/10 ,原則上除以多少都可以,除以 10 是為了好除「業(yè)界基本上也是這樣做的」式散,比如以 iPhone 6p「414*736」 為例子筋遭,那么 rem 的基準值就是 414/10 = 41.4px,然后我們就是要不停的改變這個頁面基準值的值即可,我們只要記住一點,rem 的基準值是根據(jù)設(shè)計稿來決定的
我們也知道了暴拄,如果把一個 px 轉(zhuǎn)化成 rem 那么就是使用 px/rem基準值漓滔,這樣界面中的 css 中有太多的 px ,如果一個個除下來人頭發(fā)都白了「也不一定能除完乖篷,當然網(wǎng)上也有在線轉(zhuǎn)換網(wǎng)站响驴,就是這樣也累呀」,我們可以使用 sass「css 擴展語言」 來解決這個問題
1那伐、sass 的安裝
- 1踏施、安裝 ruby 地址:http://rubyinstaller.org/downloads/ 建議安裝 2.4.3 版本
- 2、安裝 sass 和 compass
gem install sass
gem install compass
以上安裝速度如果慢的話罕邀,可以切換成淘寶的 gem「安裝基于ruby的軟件」源
- 3畅形、查看是否安裝成功
如果看到這個,就證明 sass 安裝成功了
- 4诉探、具體的安裝過程請看:https://www.sass.hk/install/
2日熬、寫個 demo 感受一下
- 1、新建一個 usesass.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="../css/normalize.css">
<link rel="stylesheet" href="../css/usesass.css">
<title>使用 sass </title>
</head>
<body>
<div class="box">
<div class="item"><span>1</span></div>
</div>
</body>
</html>
細心的朋友會發(fā)現(xiàn)肾胯,我們這里引入了一個 usesass.css 樣式文件竖席,哪來的耘纱?目前這個文件是不存在的,完后我們使用 sass 直接轉(zhuǎn)換成普通的 css 文件即可
- 2毕荐、在 css 目錄下新建 usesass.scss 文件
scss 和 sass 文件區(qū)別束析,前者對格式?jīng)]有嚴格要求,后者對格式有嚴格的要求「沒有大括號等憎亚,這里我們使用 scss」
.box{
background-color: red;
width: 100px;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.item {
background-color: yellow;
width:50px;
height:50px;
}
- 3员寇、scss 肯定是直接不能使用的,我們要轉(zhuǎn)化一下第美,使用 sass 命令
我們進入到 css 目錄下使用如下命令
sass usesass.scss usesass.css
這樣就會在 css 目錄下創(chuàng)建一個 usesass.css 文件并且把 sass 轉(zhuǎn)化成 css 了,我們看看這個 css 文件
.box {
background-color: red;
width: 100px;
height: 100px;
display: flex;
justify-content: center;
align-items: center; }
.item {
background-color: yellow;
width: 50px;
height: 50px; }
看起來和上面的 sass 文件是一毛一樣的「原因是我們沒有使用 sass 的擴展語法蝶锋,sass 是兼容所有的版本的 css 的」
- 4、運行一下看結(jié)果
沒有什么毛病什往,sass 成功轉(zhuǎn)化成 css 并且顯示出結(jié)果了
3扳缕、使用 sass 來轉(zhuǎn)化 px--rem 梯刚,并且使用 js 動態(tài)設(shè)置 font-size
- 1逗威、提供 px2rem() 函數(shù)
在 sass 中我們可以使用函數(shù)挽放,我們定義一個函數(shù)用來轉(zhuǎn)化 px 到 rem纤虽,這里以視覺稿為 iphone 6p「414*736」 為例子京革,那么 rem 的基準值就是 41.4px 绳泉,我們在 usesass.sass 中添加如下代碼,并且修改 box 的寬高 px 為 rem「調(diào)用 px2rem()方法」
@function px2rem($px){
// rem基準值
$rem : 41.4px;
@return ($px/$rem) + rem;
}
.box{
background-color: red;
width: px2rem(100px);
height: px2rem(100px);
display: flex;
justify-content: center;
align-items: center;
}
.item {
background-color: yellow;
width:px2rem(50px);
height:px2rem(50px);
}
- 2冠跷、使用 js 動態(tài)的修改 font-size 的值
在 usesass.html 添加以下動態(tài)修改 font-size 的代碼
<script>
// 取得屏幕寬度
var devicewidth = document.documentElement.clientWidth || document.body.clientWidth
//動態(tài)設(shè)置 html font-size 值
document.getElementsByTagName('html')[0].style.fontSize = devicewidth / 10 + 'px';
</script>
- 3合是、記得一定要把 sass 轉(zhuǎn)化成 css
sass usesass.scss usesass.css
我們再看看 usesass.css 文件
.box {
background-color: red;
width: 2.4154589372rem;
height: 2.4154589372rem;
display: flex;
justify-content: center;
align-items: center; }
.item {
background-color: yellow;
width: 1.2077294686rem;
height: 1.2077294686rem; }
我們看 px 成功的轉(zhuǎn)化成 rem 了衫樊,這樣我們就可以動態(tài)的修改 rem 了
- 4飒赃、看看效果吧
先看效果之前,我們?yōu)榱朔奖銣y試科侈,來給動態(tài)修改 rem 添加一個事件吧载佳,否則每次修改分辨率都要重新刷新一下瀏覽器「這里是為了演示添加的代碼」
// 窗口大小改變時的回調(diào)
window.onresize = function(){
// 取得屏幕寬度
var devicewidth = document.documentElement.clientWidth || document.body.clientWidth
//動態(tài)設(shè)置 html font-size 值
document.getElementsByTagName('html')[0].style.fontSize = devicewidth / 10 + 'px';
}
依據(jù)前面我們知道,我們是以設(shè)計稿為 iphone 6p 基準來設(shè)置的「在此手機上寬高就是 100 px」臀栈,從上圖可以看到確實在不同的分辨率手機下 box 的寬高等比縮放蔫慧,這就達到了適配的目的,基本上 rem 適配手機 webapp 方法就說完了
四权薯、參考資料
騰訊全端AlloyTeam團隊--移動web適配利器--rem:http://www.alloyteam.com/2016/03/mobile-web-adaptation-tool-rem/
點贊富一生姑躲,轉(zhuǎn)發(fā)富五代,更多文章請關(guān)注我的微信公號來查閱
公眾號:TigerChain