物理像素(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;
复制代码