物理像素(physical pixel)
:又被稱爲設備像素,它是顯示設備中一個最微小的物理部件,每一個像素可根據操做系統設置本身的顏色和亮度,正是這些設備像素的微小距離欺騙了肉眼看到的圖像效果設備獨立像素(density-independent pixel)
:設備獨立像素也稱爲密度無關像素,能夠認爲是計算機座標系統中的一個點,這個點表明一個能夠由程序使用的虛擬像素(如 CSS 像素),而後由相關係統轉換爲物理像素CSS 像素
:CSS 像素是一個抽像單位,主要使用在瀏覽器上,用來精確度量 Web 頁面上的內容,通常狀況下 CSS 像素被稱爲與設備無關的像素(device-independent pixel),簡稱 DIPs屏幕密度(PPI)
:屏幕密度是指一個設備表面上存在的像素數量,它一般以每英寸有多少像素來計算設備像素比(device pixel ratio)
:簡稱爲 dpr,其定義了物理像素和設備獨立像素的對應關係
位圖像素
縮放比 scale
:scale = 1/dpr視窗 viewport
:簡單理解 viewport 是嚴格等於瀏覽器窗口,在桌面瀏覽器中 viewport 就是瀏覽器窗口的寬高,但在移動端設備上有點複雜。閱讀推薦:解讀 viewport—網頁自適應移動 app 神器媒體查詢 @media
<!-- link 元素中的 CSS 媒體查詢 -->
<link rel="stylesheet" media="(max-width: 800px)" href="example.css" />
<!-- 樣式表中的CSS媒體查詢 -->
<style> @media (max-width: 767px) { ...css代碼... } @media (min-width: 768px) and (max-width: 991px) { ...css代碼... } </style>
複製代碼
閱讀推薦:隨方逐圓 -- 全面理解 CSS 媒體查詢css
靜態佈局(static layout)
html
流式佈局(Liquid Layout)
前端
自適應佈局(Adaptive Layout)
android
響應式佈局(Responsive Layout)
css3
彈性佈局(rem/em 佈局)
git
這是最基本的佈局方式,按照文檔的順序一個一個顯示出來,塊元素獨佔一行,行內元素共享一行github
浮動方式佈局就是使用 float 屬性,使元素脫離文檔流浮動起來web
經過 position 屬性來進行定位瀏覽器
div + css 的佈局較 table 佈局有什麼優勢?
改版時更方便,只要改css文件
頁面加載速度更快、結構化清晰、頁面顯示簡潔,表現與結構相分離
易於優化(seo)搜索引擎更友好sass
2009 年對前端來講是不平凡的一年,HTML5 定稿、ES5.1 發佈、flex 應運而生。flex 是 flexible box 的縮寫,意爲"彈性佈局",天生響應式,生而爲佈局,使用及其簡單,能夠簡便、完整、響應式地實現各類頁面佈局
根據規範中的描述可知道,flexbox 模塊提供了一個有效的佈局方式,即便不知道視窗大小或未知元素狀況之下均可以智能的、靈活的調整和分配元素和空間二者之間的關係。簡單的理解就是能夠自動調整,計算元素在容器空間中的大小
注意 : 這裏所指的 flexbox 是指設置了 display: flex; 或 display: inline-flex; 的盒子,不是指單單設置了 display: flex; 的盒子
在 flex 容器中默認存在兩條軸,水平主軸(main axis) 和垂直的交叉側軸(cross axis),這是默認的設置,固然可經過修改使垂直方向變爲主軸,水平方向變爲交叉軸
容器中的每一個單元塊被稱爲 flex item,每一個項目佔據的主軸空間爲 (main size), 佔據的交叉軸的空間爲 (cross size)
注意不能先入爲主認爲寬度就是 main size,高度就是 cross size,這個還要取決於主軸方向,若垂直方向是主軸,那項目的高度就是 main size
writing-mode 屬性可改變文檔流方向,此時主軸是垂直方向,但實際開發不多遇到這樣場景,所以初學時直接使用水平方向和垂直方向理解不會有任何問題,反而易於理解
實現 flex 佈局需先指定一個容器,任何一個容器只要被指定爲 flex 佈局,該容器內部元素就可以使用 flex 進行佈局
display: flex
或給 span 這類內聯元素設置 display: inline-flex
,Flex佈局即建立!其中,直接設置 display: flex 或 display: inline-flex 的元素稱爲 flex 容器,裏面的子元素稱爲 flex 子項注意:當時設置 flex 佈局後子元素的 float、clear、vertical-align 的屬性將會失效
flex 佈局相關屬性分爲兩撥:一撥做用在 flex 容器上(此處以「父容器」代替),還有一撥做用在 flex 子項(此處以「子容器」代替)上,具體參見下表,不管做用在父容器上,仍是做用在子容器,都是控制子容器的呈現,只是前者控制的是總體,後者控制的是個體
做用在父容器 | 做用子容器 |
---|---|
flex-direction | order |
flex-wrap | flex-grow |
flex-flow | flex-shrink |
justify-content | flex-basis |
align-items | flex |
align-content | align-self |
做用在父容器上的屬性
flex-direction
// row:默認值,顯示爲行,方向爲當前文檔水平流方向(主軸),默認狀況下是從左往右。若是當前水平文檔流方向是 rtl(如設置 direction: rtl),則從右往左
// row-reverse:顯示爲行,但方向和 row 屬性值是反的
// column:顯示爲列,垂直方向,起點在上沿
// column-reverse:顯示爲列,垂直方向,但方向和 column 屬性值是反的
flex-direction: row | row-reverse | column | column-reverse;
複製代碼
flex-wrap
// nowrap:默認值,表示單行顯示不換行,即當主軸尺寸固定、空間不足時,項目尺寸會隨之調整而並不會擠到下一行
// wrap:子容器主軸總尺寸超出父容器時換行,第一行在上方
// wrap-reverse:寬度不足換行顯示,可是從下往上開始,即本來換行在下面的子項跑到上面
flex-wrap: nowrap | wrap | wrap-reverse;
複製代碼
flex-flow
flex-flow: <flex-direction> || <flex-wrap>;
複製代碼
justify-content
// flex-start:默認值,邏輯 CSS 屬性值,與文檔流方向相關,默認表現爲左對齊
// flex-end:邏輯CSS屬性值,與文檔流方向相關,默認表現爲右對齊
// center:表現爲居中對齊
// space-between:表現爲兩端對齊,between 是中間的意思,意思是多餘的空白間距只在元素中間區域分配
// space-around:around 是環繞的意思,意思是每一個子容器兩側都環繞互不干擾的等寬的空白間距,最終視覺上邊緣兩側的空白只有中間空白寬度一半
// space-evenly:evenly 是勻稱、平等的意思,即視覺上每一個子容器兩側空白間距徹底相等
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
複製代碼
align-items
// stretch:默認值,子容器拉伸,即若子容器未設置高度或設爲 auto,將佔滿整個父容器的高度,若子容器設置了高度,則按照設置的高度值渲染,而非拉伸
// flex-start:邏輯 CSS 屬性值,與文檔流方向相關,默認表現爲容器頂部對齊
// flex-end:邏輯 CSS 屬性值,與文檔流方向相關,默認表現爲容器底部對齊
// center:表現爲垂直居中對齊
// baseline:表現爲全部 =子容器都相對於父容器的基線(字母 x 的下邊緣)對齊
align-items: stretch | flex-start | flex-end | center | baseline;
複製代碼
align-content
// stretch:默認值,每行子容器都等比例拉伸,如若共兩行子容器,則每一行拉伸高度是 50%
// flex-start:邏輯CSS屬性值,與文檔流方向相關,默認表現爲頂部堆砌
// flex-end:邏輯CSS屬性值,與文檔流方向相關,默認表現爲底部堆放
// center:表現爲總體垂直居中對齊
// space-between:表現爲上下兩行兩端對齊。剩下每一行元素等分剩餘空間
// space-around:每一行元素上下都享有獨立不重疊的空白空間
// space-evenly:每一行元素都徹底上下等分
align-content: stretch | flex-start | flex-end | center | space-between | space-around | space-evenly;
複製代碼
做用在子容器上的屬性
order
order: <integer>; /* 整數值,默認值是 0 */
複製代碼
flex-grow
flex-grow: <number>; /* 數值,能夠是小數,默認值是 0 */
複製代碼
flex-shrink
flex-shrink: <number>; /* 數值,默認值是 1 */
複製代碼
flex-basis
flex-basis: <length> | auto; /* default auto */
複製代碼
flex
flex: none | auto | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
// 當 flex 取值爲一個非負數字,則該數字爲 flex-grow 值,flex-shrink 取 1,flex-basis 取 0%
// 以下同等
.item {flex: 1;}
.item {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
}
// 當 flex 取值爲 0 時,對應的三個值分別爲 0 1 0%
item {flex: 0;}
.item {
flex-grow: 0;
flex-shrink: 1;
flex-basis: 0%;
}
// 當 flex 取值爲一個長度或百分比,則視爲 flex-basis 值,flex-grow 取 1,flex-shrink 取 1
// 有以下等同狀況(注意 0% 是一個百分比而不是一個非負數字)
.item-1 {flex: 0%;}
.item-1 {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
}
.item-2 {flex: 24px;}
.item-2 {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 24px;
}
// 當 flex 取值爲兩個非負數字,則分別視爲 flex-grow 和 flex-shrink 的值,flex-basis 取 0%,以下是等同的:
.item {flex: 2 3;}
.item {
flex-grow: 2;
flex-shrink: 3;
flex-basis: 0%;
}
// 當 flex 取值爲一個非負數字和一個長度或百分比,則分別視爲 flex-grow 和 flex-basis 的值,flex-shrink 取 1,以下是等同的:
.item {flex: 11 32px;}
.item {
flex-grow: 11;
flex-shrink: 1;
flex-basis: 32px;
}
複製代碼
align-self
補充說明父容器的 flex-wrap 與子容器的 flex-shrink、flex-grow 之間的關係
flexbox 佈局最適合應用程序的組件和小規模佈局(一維佈局),而 Grid 佈局則適用於更大規模的佈局(二維佈局)
沒有 HTML 結構的網格佈局有助於使用流體、調整順序等技術管理或更改佈局。經過結合 CSS 的媒體查詢屬性,能夠控制網格佈局容器和它們的子元素,使用頁面的佈局根據不一樣的設備和可用空間調整元素的顯示風格與定位,而不須要去改變文檔結構的本質內容
具體可查閱:Can I use
具體請看 CSS Grid佈局:什麼是網格佈局
網格線(Grid Lines)
網格軌道(Grid Track)
網格單元格(Grid Cell)
網格區域(Grid Area)
<div class="grid-container">
<div class="item item1">1</div>
<div class="item item2">2</div>
<div class="item item3">3</div>
<div class="item item4">4</div>
<div class="item item5">5</div>
<div class="item item6">6</div>
</div>
// 不設置 grid-template-columns,只設置 grid-template-row
.grid-container{
display: grid;
grid-template-rows: 50px 80px 100px;
background: pink;
}
.item{
border: 2px solid palegoldenrod;
color: #fff;
text-align: center;
font-size: 20px;
}
複製代碼
注:當元素設置了網格佈局,column、float、clear、vertical-align 屬性無效
.grid-container {
padding: 20px;
display: grid;
grid-template-rows: 50px 100px 60px 80px;
grid-template-columns: 50px 40px 100px 80px;
background: pink;
}
.item {
border: 2px solid palegoldenrod;
color: #fff;
}
複製代碼
CSS fr 單位是一個自適應單位,fr 單位被用於在一系列長度值中分配剩餘空間,若已指定了多個部分,則剩下的空間根據各自的數字按比例分配
fr 是基於網格容器可用空間來計算的(flex 也是同樣),因此若是須要的話能夠和其餘單位混合使用
grid-template-columns: 1fr 1fr 2fr;
複製代碼
.grid-container {
padding: 20px;
display: grid;
grid-template-rows: minmax(100px,200px) minmax(50px,200px);
grid-template-columns: 1fr 1fr 2fr;
background: pink;
height: 300px;
}
複製代碼
.grid-container{
padding: 20px;
display: grid;
grid-template-columns: repeat(2,100px);
grid-template-rows: repeat(3,100px);
background: pink;
}
複製代碼
.grid-container{
padding: 20px;
display: grid;
grid-template-columns: repeat(2,100px);
grid-template-rows: repeat(3,100px);
grid-column-gap: 50px;
grid-row-gap: 15px;
background: pink;
}
複製代碼
grid-row: 2;
grid-column: 3 / 4;
複製代碼
grid-area: 2 / 2 / 3 / 3;
複製代碼
.grid-container {
padding: 20px;
display: grid;
grid-template-columns: repeat(2,100px);
grid-template-rows: repeat(3,100px);
grid-column-gap: 50px;
grid-row-gap: 15px;
background: pink;
}
.item {
border: 2px solid palegoldenrod;
color: #fff;
text-align: center;
font-size: 20px;
}
.item1 {
grid-row-start: 2;
grid-row-end: 3;
grid-column-start: 2;
grid-column-end: 3;
background: #fffa90;
color: #000;
}
複製代碼
.grid-container {
padding: 20px;
display: grid;
grid-template-columns: repeat(4,100px);
grid-template-rows: repeat(3,100px);
grid-column-gap: 50px;
grid-row-gap: 15px;
background: pink;
}
.item {
border: 2px solid palegoldenrod;
color: #fff;
text-align: center;
font-size: 20px;
}
.item1 {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 2;
grid-row-end: 4;
}
// 或
// .item1 {
// grid-row: 2 / span 3;
// grid-column: span 2;
//}
複製代碼
[col1-start]
網格線名稱必定要使用 []
括住grid-area: row-start/ column-start / row-end / column-end
<div class="grid-container">
<div class="header ">header</div>
<div class="content ">content</div>
<div class="sidebar ">sidebar</div>
<div class="footer ">footer</div>
</div>
.grid-container {
text-align: center;
padding: 20px;
display: grid;
grid-column-gap: 5px;
grid-row-gap: 5px;
background: pink;
grid-template-areas: "header header header header header"
"sidebar content content content content"
"footer footer footer footer footer";
grid-template-rows: 50px 150px 50px;
grid-template-columns: 200px 200px 200px;
}
.header { grid-area:header; background: #fff}
.content { grid-area: content; background: #fffa90}
.sidebar { grid-area: sidebar; background: #5bc0de}
.footer { grid-area: footer; background: #ffff00}
複製代碼
em 做爲 font-size 的單位時,其表明父元素的字體大小,em 做爲其餘屬性單位時,表明自身字體大小 —— MDN
rem 做用於非根元素時,相對於根元素字體大小;rem 做用於根元素字體大小時,相對於其出初始字體大小 —— MDN
/* 做用於根元素,相對於原始大小(16px),因此 html 的 font-size 爲 32px*/
html {font-size: 2rem}
/* 做用於非根元素,相對於根元素字體大小,因此爲 64px */
p {font-size: 2rem}
複製代碼
rem 佈局的核心是設置好根 html 元素的 font-size,rem 佈局的本質在我看來是等比縮放,通常是基於寬度
假設將屏幕寬度平均分紅 100 份,每一份的寬度用 x 表示,x = 屏幕寬度 / 100,若將 x 做爲單位,x 前面的數值就表明屏幕寬度的百分比。若想要頁面元素隨着屏幕寬度等比變化,須要上面的 x 單位,不幸的是 CSS 中並無這樣的單位,幸運的是在 CSS 中有 rem,經過 rem 這個橋樑能夠實現神奇的 x
div { width: 50x } /* 屏幕寬度的50% */
複製代碼
若子元素設置 rem 單位的屬性,經過更改 html 元素的字體大小就可以讓子元素實際大小發生變化
html { font-size: 16px }
div { width: 2rem } /* 32px*/
html { font-size: 32px }
div { width: 2rem } /*64px*/
複製代碼
若讓 html 元素字體的大小恆等於屏幕寬度的 1/100,那 1rem 和 1x 就等價
html { fons-size: width / 100 }
div { width: 50rem } /* 50rem = 50x = 屏幕寬度的50% */
複製代碼
如何讓 html 字體大小一直等於屏幕寬度的百分之一呢?能夠經過 js 來設置,通常須要在頁面 dom ready、resize 和屏幕旋轉中設置
document.documentElement.style.fontSize = document.documentElement.clientWidth / 100 + 'px';
複製代碼
如何把 UE(UE 是用戶體驗(User Experience)的縮寫,指用戶界面功能圖) 圖中的獲取的像素單位的值,轉換爲以 rem 爲單位的值呢?公式元素寬度 / UE 圖寬度 * 100
,假設 UE 圖尺寸是 640px,UE 圖中的一個元素寬度是 100px,根據公式則是 100 / 640 * 100 = 15.625
div { width: 15.625rem }
複製代碼
下面的表格是 UE 圖等比縮放下元素的寬度 下面的表格是經過元素在不一樣屏幕寬度下的計算值
上圖能夠看出 UE 圖寬度和屏幕寬度相同時兩邊得出的元素寬度是一致的
上面的計算過程有些繁瑣,能夠經過預處理的 function 來簡化過程,下面是 sass 的例子,less 相似
$ue-width: 640; /* ue圖的寬度 */
@function px2rem($px) {
@return #{$px/$ue-width*100}rem;
}
div {
width: px2rem(100);
}
複製代碼
其實有了 postcss 後,這個過程應該放到 postcss 中,源代碼以下
div { width: 100px2rem }
// postcss 會對 px2rem 這個單位進行處理,處理後的結果以下
p { width: 15.625rem }
複製代碼
在移動端中,通常爲了防止在高清屏幕下像素不夠用致使模糊,拿到的設計稿是 640px(iphone5 設備寬爲320 px)或 750px 的兩倍稿(iphone6 設備寬爲375 px),按照設備寬度作了兩倍的大小,那開發時在 CSS 中要設置什麼尺寸呢?如何作到一份設計稿適配到不一樣機型中?
width: px2rem(200);
/* 移動端頁面設計稿寬度 */
$design-width: 750;
/* 移動端頁面設計稿 dpr 基準值 */
$design-dpr: 2;
/* 將移動端頁面分爲 10 塊 */
$blocks: 10;
/* 縮放所支持的設備最小寬度 */
$min-device-width: 320px;
/* 縮放所支持的設備最大寬度 */
$max-device-width: 540px;
/* rem與px對應關係,1rem表明在JS中設置的html font-size值(爲一塊的寬度),$rem即爲$px對應占多少塊 $px $rem ------------- === ------------ $design-width $blocks */
/* 單位px轉化爲rem */
@function px2rem($px) {
@return #{$px / $design-width * $blocks}rem;
}
/* 單位 rem 轉化爲 px,可用於根據rem單位快速計算原px */
@function rem2px($rem) {
@return #{$rem / $blocks * $design-width}px;
}
// 在對應的JS文件中
// 在對應的JS文件中
var docElem = document.documentElement,
metaElem = document.querySelector('meta[name="viewport"]'),
dpr = window.devicePixelRatio || 1,
// 將頁面分爲 10 塊
blocks = 10,
// 須要限制的最小寬度
defaultMinWidth = 320,
// 須要限制的最大寬度
defaultMaxWidth = 540,
// 計算的基準值
calcMaxWidth = 9999999;
// 設置docElem字體大小
function setFontSize() {
var clientWidth = docElem.clientWidth;
clientWidth = Math.max(clientWidth, defaultMinWidth * dpr)
// 調整計算基準值
if (calcMaxWidth === defaultMaxWidth) {
clientWidth = Math.min(clientWidth, defaultMaxWidth * dpr);
}
docElem.style.fontSize = clientWidth / blocks + 'px';
}
setFontSize();
window.addEventListener(window.orientationchange ? 'orientationchange' : 'resize', setFontSize, false);
複製代碼
在 rem 佈局中廣泛採用 viewport scale 視窗縮放的方式,視窗縮放很簡單,直接將 meta 標籤中的 scale 進行更改,如 dpr 爲 3 則 scale 以下。但縮放在某些安卓設備中支持度不太好,還須要作其餘檢測(檢測了現用的一些機型,應該還不完整哈),同時將最終計算的 dpr 放到 html 中,供 css 作一些特殊適配
// 大部分dpr爲2如下的安卓機型不識別scale,需設置不縮放
if (navigator.appVersion.match(/android/gi) && dpr <= 2) {
dpr = 1;
}
setScale(dpr);
// 企業QQ設置了 scale 後,不能徹底識別 scale(此時 clientWidth 未收到縮放的影響而翻倍),需設置不縮放
if (navigator.appVersion.match(/qq\//gi) && docElem.clientWidth <= 360) {
dpr = 1;
setScale(dpr);
}
docElem.setAttribute('data-dpr', dpr);
// 設置縮放
function setScale(dpr) {
metaElem.setAttribute('content', 'initial-scale=' + 1 / dpr + ',maximum-scale=' + 1 / dpr + ',minimum-scale=' + 1 / dpr + ',user-scalable=no');
}
複製代碼
設置容器的最大最小寬度
<!DOCTYPE html>
<html>
<head>
<title>REM佈局</title>
<meta charset="utf-8">
<meta lang="zh-CN">
<meta name="viewport" data-content-max content="width=device-width,initial-scale=1,user-scalable=no">
<link rel="stylesheet" href="./rem.css">
<script src="./rem.js"></script>
</head>
<body data-content-max>
<section class="container">
// js
// 須要限制的最小寬度
var defaultMinWidth = 320,
// 須要限制的最大寬度
defaultMaxWidth = 540,
// 計算的基準值
calcMaxWidth = 9999999;
if (metaElem.getAttribute('data-content-max') !== null) {
calcMaxWidth = defaultMaxWidth;
}
...
// 設置docElem字體大小
function setFontSize() {
var clientWidth = docElem.clientWidth;
clientWidth = Math.max(clientWidth, defaultMinWidth * dpr)
// 調整計算基準值
if (calcMaxWidth === defaultMaxWidth) {
clientWidth = Math.min(clientWidth, defaultMaxWidth * dpr);
}
docElem.style.fontSize = clientWidth / blocks + 'px';
}
// 在CSS中,簡單地調用一下,核心方法已經抽離
html {
@include root-width();
}
/* html根的寬度定義 */
@mixin root-width() {
body {
@include container-min-width();
&[data-content-max] {
@include container-max-width();
}
}
/* 某些機型雖然設備dpr大於1,但識別不了scale縮放,這裏須要從新設置最小寬度防止出現橫向滾動條 */
&[data-dpr="1"] body {
min-width: $min-device-width;
}
}
/* 設置容器拉伸的最小寬度 */
@mixin container-min-width() {
margin-right: auto;
margin-left: auto;
min-width: $min-device-width;
@media (-webkit-device-pixel-ratio: 2) {
min-width: $min-device-width * 2;
}
@media (-webkit-device-pixel-ratio: 3) {
min-width: $min-device-width * 3;
}
}
/* 設置容器拉伸的最大寬度 */
// 要注意的是,這裏的max-width也要配上dpr係數
@mixin container-max-width() {
margin-right: auto;
margin-left: auto;
max-width: $max-device-width;
@media (-webkit-device-pixel-ratio: 2) {
max-width: $max-device-width * 2;
}
@media (-webkit-device-pixel-ratio: 3) {
max-width: $max-device-width * 3;
}
}
複製代碼
文本大小是否用 rem 單位
/* 設置字體大小,不使用rem單位, 根據dpr值分段調整 */
@mixin font-size($fontSize) {
font-size: $fontSize / $design-dpr;
[data-dpr="2"] & {
font-size: $fontSize / $design-dpr * 2;
}
[data-dpr="3"] & {
font-size: $fontSize / $design-dpr * 3;
}
}
@include font-size(30px);
複製代碼
html { fons-size: width / 100 }
body { font-size: 16px }
複製代碼
@media screen and (min-width: 320px) {
body {font-size: 16px}
}
@media screen and (min-width: 481px) and (max-width:640px) {
body {font-size: 18px}
}
@media screen and (min-width: 641px) {
body {font-size: 20px}
}
div {font-size: 1.2em}
div a {font-size: 1.2em}
複製代碼
var clientWidth = document.documentElement.clientWidth;
clientWidth = clientWidth < 780 ? clientWidth : 780;
document.documentElement.style.fontSize = clientWidth / 100 + 'px';
body {
margin: auto;
width: 100rem
}
複製代碼
// 首先能夠添加noscript標籤提示用戶
<noscript>開啓JavaScript,得到更好的體驗</noscript>
// 給html添加一個320時的默認字體大小,保證頁面能夠顯示
html {fons-size: 3.2px}
// 若是想要更好的體驗,不如添加媒體查詢吧
@media screen and (min-width: 320px) {
html {font-size: 3.2px}
}
@media screen and (min-width: 481px) and (max-width:640px) {
html {font-size: 4.8px}
}
@media screen and (min-width: 641px) {
html {font-size: 6.4px}
}
複製代碼
vw:視口寬度的 1/100;vh:視口高度的 1/100 —— MDN
/* rem 方案 */
html { fons-size: width / 100 }
div { width: 15.625rem }
/* vw方案 */
div { width: 15.625vw }
複製代碼
html {
@include root-font-size();
}
line-height: px2rem(300);
複製代碼
html {
@include root-font-size();
}
line-height: px2rem(300);
/* 移動端頁面設計稿寬度 */
$design-width: 750;
/* 移動端頁面設計稿dpr基準值 */
$design-dpr: 2;
/* 將移動端頁面分爲10塊 */
$blocks: 10;
/* 縮放所支持的設備最小寬度 */
$min-device-width: 320px;
/* 縮放所支持的設備最大寬度 */
$max-device-width: 540px;
/* rem與px對應關係,1rem表明html font-size值(爲一塊的寬度),$rem即爲$px對應占多少塊 $px $rem ------------- === ------------ $design-width $blocks */
/* html 根元素的 font-size 定義,簡單地將頁面分爲 $blocks 塊,方便計算 */
@mixin root-font-size() {
font-size: 100vw / $blocks;
body {
@include container-min-width();
}
/* 最小寬度定義 */
@media screen and (max-width: $min-device-width) {
font-size: $min-device-width / $blocks;
}
/* 最大寬度定義 */
&[data-content-max] {
body[data-content-max] {
@include container-max-width();
}
@media screen and (min-width: $max-device-width) {
font-size: $max-device-width / $blocks;
}
}
}
/* 設置容器拉伸的最小寬度 */
@mixin container-min-width() {
margin-right: auto;
margin-left: auto;
min-width: $min-device-width;
}
/* 設置容器拉伸的最大寬度 */
@mixin container-max-width() {
margin-right: auto;
margin-left: auto;
max-width: $max-device-width;
}
<!DOCTYPE html>
<html data-content-max>
<head>
<title>VW-REM佈局</title>
<meta charset="utf-8">
<meta lang="zh-CN">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<link rel="stylesheet" href="./vw-rem.css">
</head>
複製代碼
rem | vm | rem + vm | |
---|---|---|---|
容器最小寬度 | 支持 | 不支持 | 支持 |
容器最大寬度 | 支持 | 不支持 | 支持 |
高清設備 1px 邊框 | 支持 | 支持 | 支持 |
容器固定縱橫比 | 支持 | 支持 | 支持 |
優勢 | 一、rem 單位兼容性好 二、支持高清設備 1px 邊框時可按以往方式直接寫 1px |
一、無需引入 js 二、vw 的用法比較規範 |
同 vm |
缺點 | 一、使用 js 設置 html 的 font-size 二、使用 scale 來設置 viewport 縮放,以支持高清設備中的 1px,但 scale 在安卓機中的兼容性不太好 三、rem 的用法不太標準,帶有一些 hack 的特變 |
一、vw 單位在老舊機型上不兼容 二、爲了支持高清設備的 1px,使用比較複雜的 scss mixin,佔用 :after 僞類,會產生較多的代碼 |
同 vm |
/* 移動端頁面設計稿寬度 */
$design-width: 750;
/* 移動端頁面設計稿dpr基準值 */
$design-dpr: 2;
/* 將移動端頁面分爲10塊 */
$blocks: 10;
/* 縮放所支持的設備最小寬度 */
$min-device-width: 320px;
/* 縮放所支持的設備最大寬度 */
$max-device-width: 540px;
複製代碼