响应式开发的本质是针对多种屏幕做适配,首先需要掌握几个基本概念:
- 物理像素:设备的屏幕实际像素点,如常说的
iPhone 6 Plus
的分辨率是 1920 * 1080 像素。 - 设备独立像素:逻辑像素,用于定义应用的UI。
- 屏幕像素比(devicePixeRatio):物理像素与设备独立像素的比值。
使用 rem 实现响应式布局
rem
(font size of the root element)是 CSS
的计量单位,表示相对于根(即 html
)元素的字体大小。其主要用于移动 Web
开发,以适配不同尺寸的屏幕。
rem
的兼容可以通过 caniuse 查询
由于 rem
单位是相对于网页根元素的字号大小而定,所以实现 rem
布局开发时,首先要做的就是对根元素的字号赋值。
html{ font-size:12px; }
我们将网页根元素的字号设置为 12px
,此时 rem
相对于网页根元素字号为 1rem = 12px
。故此转换 rem
的公式则为
rem值 = 元素实际 px 值 / 网页根元素的字号
下面通过 rem
实现一个简单的布局 【预览】
<!DOCTYPE html>
<html>
<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>Rem Case</title>
<style>
body {
font-size: 12px;
margin: auto;
}
.btns {
width: 10rem;
margin: 0 auto;
}
.btns > a {
float: left;
width: 2.5rem;
text-align: center;
padding-top: 0.2rem;
}
.btns > a > i {
display: inline-block;
width: 1.2rem;
height: 1.2rem;
background: gray;
border-radius: 50%;
}
.btns>a>span {
display: block;
line-height: 0.8rem;
font-size: 14px;
}
</style>
</head>
<body>
<div class="btns">
<a>
<i></i>
<span>英语</span>
</a>
<a>
<i></i>
<span>日语</span>
</a>
<a>
<i></i>
<span>德语</span>
</a>
<a>
<i></i>
<span>法语</span>
</a>
<a>
<i></i>
<span>韩语</span>
</a>
<a>
<i></i>
<span>小语种</span>
</a>
<a>
<i></i>
<span>教学</span>
</a>
<a>
<i></i>
<span>职场</span>
</a>
</div>
</body>
</html>
最后加上最关键的重置元素字号脚本
(function (window, document) {
'use strict';
// 获取网页根元素
var html = document.documentElement || document.querySelector('html');
// 重置根元素字号
function resetFontSize() {
// 获取根元素的宽度
var width = html.getBoundingClientRect().width;
// 设置一个最大宽度值
if (width > 640) width = 640;
html.style.fontSize = (width / 10) + 'px';
}
resetFontSize();
window.addEventListener('resize', resetFontSize, false);
})(window, document);
rem
确实有效的解决了响应式布局,但却并非完美:
- 对于脚本的依赖,需要使用
js
脚本对其根元素的字号动态计算与赋值。 - 只能针对一个基准值去动态计算根元素字号大小,面对于宽高自适应且不出现滚动条这种布局,
rem
则显得无能为力,因为它基准值只能是一个,高度或宽度。
使用 vw、vh、vmin、vmax 实现响应式布局
vw
、vh
、vmin
、vmax
与 rem
相同都是 CSS3
中新引入的一种计量单位。不同于 rem
它们所表达的含义如下:
单位 | 含义 |
---|---|
vw | 等于视口宽度的 1% |
vh | 等于视口高度的 1% |
vmin | 相视的宽度或高度,取决于哪个更小 |
vmax | 相对于视的宽度或高度,取决于哪个更大 |
vw
、vh
、vmin
、vmax
的兼容可以通过 caniuse 查询
在使用 vw
、vh
、vmin
、vmax
之前我们需要认识一下视口。
以 PPK大神 在其文章 A tale of two viewports (一)、A tale of two viewports (二) 以及 Meta viewport 三篇文章 中提出关于视口的解释:
- 在桌面端:
The function of the viewport is to constrain the <html> element,which is the uppermost containing block of your site.译:视口的功能是约束 html 元素,它是网站上的包含区块。
The viewport, in turn, is exactly equal to the browser window: it’s been defined as such. The viewport is not an HTML construct, so you cannot influence it by CSS. It just has the width and height of the browser window — on desktop.
译:视口与浏览器窗口完全相同,但它并不是 HTML 结构,因此你不能通过 CSS 来影响它。在桌面端,视口只是具有浏览器窗口的高度与宽度。
以上是我在原文中截取的两段关于桌面端的视口概念,从中总结得知:在桌面端,视口就是浏览器的可视化区域,其只是具有浏览器窗口的高度和宽度,使用 document.documentElement.clientWidth/Height
获取视口宽高。
- 在移动端:
Imagine the layout viewport as being a large image which does not change size or shape. Now image you have a smaller frame through which you look at the large image. The small frame is surrounded by opaque material which obscures your view of all but a portion of the large image. The portion of the large image that you can see through the frame is the visual viewport. You can back away from the large image while holding your frame (zoom out) to see the entire image at once, or you can move closer (zoom in) to see only a portion. You can also change the orientation of the frame, but the size and shape of the large image (layout viewport) never changes.译:设想布局视口是一个不改变形状和大小的大图像,现在你有一个更小的框架通过它你可以看到大的图像。这个框架被不透明的材料包围,遮挡了除大图像的一部分之外的其他部分。你可以通过框架看到的大图像的部分就是视觉视口( visual viewport)。你可以缩小大图像直至看到整个大图像,或者你可以放大到只看其一部分。你可以去改变框架的方向,但是这个大图像(布局视口)的大小和形状永远不会改变.
The visual viewport is the part of the page that’s currently shown on-screen.The user may scroll to change the part of the page he sees, or zoom to change the size of the visual viewport.
译:视觉视口就是当前显示在屏幕上页面的一部分。用户可以通过滚动改变看到的页面的一部分,或者缩放以更改视觉视口的大小。
However, the CSS layout, especially percentual widths, are calculated relative to the layout viewport, which is considerably wider than the visual viewport.
译:然而,CSS 布局,特别是百分比的宽度,是相对于布局视口计算的,它要比视觉视口宽的多。
How wide is the layout viewport? That differs per browser. Safari iPhone uses 980px, Opera 850px, Android WebKit 800px, and IE 974px.
译:布局视口有多宽呢?每个浏览器是不同的,Safari 使用 980px,Opera 850px, Android WebKit 800px, IE 974px。
The <meta name="viewport" content="width=320">; originally an Apple extension but meanwhile copied by many more browsers. It is meant to resize the layout viewport.
译:<meta name="viewport" content="width=320">,最初是苹果的扩展,但同时被多个浏览器采纳,它是用于调整布局视口端口的大小。
以上是我在原文中对移动端视口概念的截取,从中总结可得知:
移动端的视口分为三部分:
-
视觉视口(visual viewport)
:就是设备的屏幕区域,但是它所对应的并不是指屏幕区域里的物理像素,而是CSS
像素。当用户缩小或放大时,测量会发生变化,因为更多或更少的CSS
像素会融入屏幕。使用window.innerWidth/Height
获取视觉视口的宽高。 -
布局视口(layout viewport)
:与视觉视口不一样,它是为了解决PC 端网站在移动端显示不佳的一个解决方案,它宽高不会改变,使用document.documentElement.clientWidth/Height
来获取布局视口的宽高。 -
理想视口(ideal viewport)
:它是基于布局视口的,用于调整布局视口端口的大小。
既然提到了 理想视口(ideal viewport)
,那么就不得不普及一下 <meta name="viewport">
。
viewport 属性
viewport
是指屏幕上能用来显示网页的区域,默认情况下大多数设备的 viewport
的宽度都是 980
像素,可以通过在 heade
元素中增加 meta
标签来设置 viewport
属性:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body></body>
</html>
viewport
下包含以下属性:
-
width
:设置viewport
的宽度,为正整数,或者字符串 “device-width”。 -
initial-scale
:设置viewport
的初始缩放值,为数字,可以带小数。 -
minimum-scale
:设置viewport
的最小缩放值,为数字,可以带小数。 -
maximum-scale
:设置viewport
的最大缩放值,为数字,可以带小数。 -
height
:设置viewport
的高度。 -
user-scalable
:是否允许用户缩放,值为 "yes" 或 "no"。
通过设置 viewport
属性,可以调整用户界面的逻辑大小,页面 CSS
中的大小均以 viewport
为基准。
vw、vh、vmin、vmax 的使用
基础的东西说完了,接着回到 vw
、vh
、vmin
、vmax
的使用,它们相对于 PC 端浏览器的视口就是浏览器的可视化区域 ,而在移动端则为布局视口,还是以第一个案例为例,使用 vw
实现布局【预览】:。
<!DOCTYPE html>
<html>
<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>VW Case</title>
<link rel="shortcut icon" href="../../assets/images/icon/favicon.ico" type="image/x-icon">
<style>
body {
font-size: 12px;
margin: auto;
}
.btns {
width: 80vw;
margin: 0 auto;
}
.btns>a {
float: left;
width: 20vw;
text-align: center;
padding-top: 10px;
}
.btns>a>i {
display: inline-block;
width: 10vw;
height: 10vw;
background: gray;
border-radius: 50%;
}
.btns>a>span {
display: block;
line-height: 3vw;
font-size: 14px;
}
</style>
</head>
<body>
<div class="btns">
<a>
<i></i>
<span>英语</span>
</a>
<a>
<i></i>
<span>日语</span>
</a>
<a>
<i></i>
<span>德语</span>
</a>
<a>
<i></i>
<span>法语</span>
</a>
<a>
<i></i>
<span>韩语</span>
</a>
<a>
<i></i>
<span>小语种</span>
</a>
<a>
<i></i>
<span>教学</span>
</a>
<a>
<i></i>
<span>职场</span>
</a>
</div>
</body>
</html>
vw
、vh
、vmin
、vmax
的出现给我的感觉显得有些鸡肋,有点像 %
,但与百分比最大的不同则是 %
是相对于父元素的大小设定的比率,vw
、vh
是视口大小决定的。在使用它的过程中,个人认为它并不适合去做布局,而是去做一些元素大小的限制。当然,也是因为个人能力有限,并没有悟透,希望能够得到大神的指点。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。