移动端响应式

356 阅读8分钟

移动端响应式

移动篇

​ 允许在移动设备上的产品

​ 移动设备:手机 平板 ipad

​ 我们以后做的产品大部分都只需要适配ios系统和安卓系统即可

响应式介绍

​ 采用响应式设计,在不同设备中,网站会重新排列,展现出不同的设计风格,以完美的适配任何尺寸的屏幕。

设计原则

渐进增强(progressive enhancement)和优雅降级(graceful degradation)

移动优先的响应式布局采用的是渐进增强原则,制作响应式网站时,先搞定手机版,然后再去为更大设备去设计和开发更复杂的功能。特征是使用min-width匹配页面宽度。从上到下书写样式时,首先考虑的是移动设备的使用场景,默认查询的是最窄的情况,再依次考虑设备屏幕逐渐变宽的情况

知道几个概念

​ 1.App

​ 手机应用:目前在市面上流行的app产品大部分都是原生app开发者开发:ios:ac swift

​ 安卓:java-native

​ 原生js开发原生app:phoneGap react-native flutter

​ 2.H5页面

​ 都是运行在浏览器中或者移动端的浏览器中,在ios和安卓系统大部分浏览器都是webkit引擎

​ 移动端不用关系浏览器兼容性的问题

响应式布局如何实现

实现响应式布局的三个要素:

  1. viewport视口设置
  2. @media媒体查询
  3. 不要写死的尺寸
    • 多用百分比宽度来确定布局尺寸
    • 多用rem、em来确定布局尺寸
    • 多用vh、vw来确定布局尺寸

viewport视口设置

一、viewport的概念

移动设备上的viewport就是设备的屏幕上能用来显示我们的网页的那一块区域,,在具体一点,就是浏览器上(也可能是一个app中的webview)用来显示网页的那部分区域,默认的viewport设为980px或1024px。

二、css中的1px并不等于设备的1px

iphone3,它的分辨率为320x480,一个css像素确实是等于一个屏幕物理像素的。

iphone4(Retina屏),它的分辨率为640x960,但是屏幕尺寸没变化,一个css像素是等于两个物理像素的。

屏幕像素密度分为:ldpi、mdpi、hdpi、xhdpi等

用户缩放屏幕,会引起css中px的变化,放大1倍,css中1px所代表的物理像素也会增加一倍,反之亦然。

window对象有一个devicePixelRatio属性(设备物理像素/设备独立像素)

devicePixelRatio = 物理像素 / 独立像素

devicePixelRatio在不同的浏览器中还存在些许的兼容性问题参考:www.quirksmode.org/blog/archiv…

三、PPK的关于三个viewport的理论

ppk大神对于移动设备上的viewport有着非常多的研究(第一篇第二篇第三篇

​ 1.layout viewport :document.documentElement.clientWidth 来获取。

​ 2.visual viewport :浏览器可视区域的大小 window.innerWidth

​ 3.ideal viewport :理想的视口 移动端响应式

但是安卓设备就比较复杂了,有320px的,有360px的,有384px的等等,关于不同的设备ideal viewport的宽度都为多少,可以到viewportsizes.com去查看一下,里面收集了众多设备的理想宽度。

四、利用meta标签对viewport进行控制
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">

viewport的宽度等于设备的宽度

五、把当前的viewport宽度设置为 ideal viewport 的宽度

<meta name="viewport" content="width=device-width">

或者

<meta name="viewport" content="initial-scale=1">

把当前的的viewport变为 ideal viewport

@media 的使用方式

【1】第一种 直接嵌入

@media (max-with: 480px){
    body{
        background-color: red;
    }
}

【2】第二种 外接方式

<link rel="stylesheet" media="max-width: 480px" href="css/viewport.css">

媒体类型

media属性用于为不同的媒介类型规定不同的样式

screen         计算机屏幕(默认值)    
tty            电传打字机以及使用等宽字符网格的类似媒介
tv             电视类型设备(低分辨率、有限的屏幕翻滚能力)
projection     放映机
handheld       手持设备(小屏幕、有限的带宽)
print          打印预览模式 / 打印页
braille        盲人用点字法反馈设备
aural          语音合成器
all            适合所有设备
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<title>P5_媒体类型快速介绍</title>
		<link rel="stylesheet" type="text/css" media="screen" href="css/style.css"/>
		<link rel="stylesheet" type="text/css" href="css/print.css" media="print">
	</head>
	<body>
		<h2>Media Type</h2>
	</body>
</html>

style.css

body{
	background-color: #000000;
	color: #fff;
}

print.css

body{
	background-color: #B8860B;
	color: #fff;
}

<!DOCTYPE html>
<html lang="zh">
<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>P4_@media的引入方式</title>
	<style type="text/css">
			
		body{
			background-color: #000000;
		}
		/* 直接引入 */
		@media screen and (max-width: 960px) and (min-width: 700px){
			body{
				background-color: red;
			}
		}
		/* @media screen and (max-width: 700px){
			body{
				background-color: blue;
			}
		} */
	</style>
	<!-- 外接式 -->
    <link rel="stylesheet" type="text/css" media="all and (max-width: 700px)" href="css/index_max_700.css"/>
    <!-- all:代表所有设备 -->
	<!-- <link rel="stylesheet" type="text/css" media="screen and (max-width: 700px)" href="css/index_min_900.css"/> -->
	
</head>
<body>
	
	
</body>
</html>

媒体特性

在设置媒体查询的时候,我们通过一些表达式来判断媒体特性,比如说分辨率 、高度、宽度、宽高的比例、设备宽高比、设备宽度和高度、屏幕显示的方向(横屏还是竖屏)。

现在就以横竖屏为例来演示个效果

/*横屏*/
@media (orientation: landscape) {
    body{
        background-color: #008B8B;
    }
}
/*竖屏*/
@media (orientation: portrait) {
    body{
        background-color: #4169E1;
}

响应式图片

【1】使用img标签来设置图片的显示

/* 简单的解决方法可以使用百分比,但这样不友好,会放大或者缩小图片,那么可以尝试给图片指定的最大宽度为百分比。假如图片超过了,就缩小。假如图片小了,就原尺寸输出 */
img{
    width: 100%;
    max-width: 100%;
}

【2】使用background属性设置背景图

将background-size属性设置为cover,则会把背景图像扩展至足够大,使背景图像完全覆盖背景区域。

.bg_img{
    background: url(../images/01.jpg) no-repeat center center;
    background-size: cover;
    height: 500px;
}
响应式网页布局搭建
<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="utf-8">
		<title>P7_响应式网页布局搭建</title>
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<link rel="stylesheet" type="text/css" href="css/layout.css"/>
	</head>
	<body>
		<div class="container">
			<header id="header">
				<h3>页头</h3>
			</header>
			<nav id="navigation">
				<h3>导航</h3>
			</nav>
			<section id="mainbody">
				<h3>主体</h3>
				<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sem erat, egestas quis luctus ut, rhoncus vitae
					risus. Integer venenatis libero sit amet sapien dictum, quis bibendum mi volutpat. Cras pretium quam quis magna
					facilisis, eget feugiat nisi lacinia.</p>
			</section>
			<aside id="sidebar">
				<h3>边栏</h3>
				<p>Donec dolor arcu, interdum sed turpis faucibus, placerat ultricies felis. Donec pulvinar gravida rhoncus.
					Suspendisse vestibulum est eget dolor lobortis.</p>
			</aside>
			<footer id="footer">
				<h3>页脚</h3>
			</footer>
		</div><!-- end .container -->
	</body>
</html>

layout.css

![ydj_01](D:\web\Typora\移动端响应式\static\images\ydj_01.png)body{
	margin-top: 35px;
	text-align: center;
}
.container{
	width: 960px;
	margin: 0 auto;
}
#header,#navigation,#mainbody,#sidebar,#footer{
	height: 100px;
	line-height: 25px;
	background-color: #eee;
	margin-bottom: 20px;
}
#mainbody,#sidebar{
	float: left;
	height: 300px;
}
#mainbody{
	width: 620px;
	margin-right: 20px;
	background-color: darkseagreen;
}
#sidebar{
	width: 320px;
	background-color: darkcyan;
}
#footer{
	clear: both;
}

@media screen and (min-width: 1200px) {
	.container{
		width: 1170px;
	}
	#mainbody{
		width: 770px;
		margin-right: 30px;
	}
	#sidebar{
		width: 370px;
	}
}
/* 流动布局 */
@media all and (max-width:959px) {
		
	.container{
		width: 100%;
	}
	#mainbody{
		width: 67%;
	}
	#sidebar{
		width: 30%;
		float: right;
	}
}
@media all and (max-width: 767px) {
	#mainbody,#sidebar{
		float: none;
		width: 100%;
	}
}

展示图如下:

bootstrap响应式导航栏
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.bootcss.com/font-awesome/5.10.0-11/css/all.css" rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="css/bt.css" />
    <title>P9_案例_响应式导航栏</title>
</head>
<body style="height:2000px;">
    <nav class="nav nav-fix">
        <div class="container clearfix">
            <div class="nav-header clearfix">
                <h2>Bootstrap中文网</h2>
                <a href="javascript:void(0);">
                    <i class="fa fa-bars toggle-btn"></i>
                </a>
            </div>
            <div class="nav-list">
                <ul>
                    <li class="hidden">
                        <a href="">Bootstrap2中文文档</a>
                    </li>
                    <li>
                        <a href="#">Bootstrap3中文文档</a>
                    </li>
                    <li>
                        <a href="#">Bootstrap4中文文档</a>
                    </li>
                    <li>
                        <a href="#">less教程</a>
                    </li>
                    <li>
                        <a href="#">jQuery Api</a>
                    </li>
                    <li>
                        <a href="#">网站实例</a>
                    </li>
                </ul>
                <ul class="navbar-right">
                    <li>
                        <a href="#">关于</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
    <div class="container">
        <!-- img{width:100%;}
        <img src="./images/01.jpg" alt=""> -->
        <div class="bg_img"></div>
    </div>
</body>
</html>

bt.css

/* .container .bg-img{
	background:url('../images/01.jpg') no-repeat center center;
	background-size:cover;
	height:500px;
} */
*{
	padding: 0;
	margin: 0;
}
a{
	text-decoration: none;
}
ul{
	list-style: none;
}
body{
	color: #eee;
	padding-top: 70px;
}
.nav{
	width: 100%;
	height: 50px;
	line-height: 50px;
	background-color: #222;
}
.container{
	margin: 0 auto;
	padding: 0 15px;
}
.nav-fix{
	position: fixed;
	top:0;
	left: 0;
	z-index: 1000;
}
.clearfix:after{
	content: '';
	clear: both;
	display: block;
}
.nav-header h2{
	float: left;
}
.nav-header a{
	float: right;
	color: #eee;
	border: 1px solid #777;
	font-size: 26px;
	height: 30px;
	line-height: 30px;
	margin-top: 10px;
	padding: 0px 12px;
}
.nav-list{
	background-color: #222;
	margin: 0 -15px;
	border-top: 1px solid #999;
	display: none;
}
.nav-list ul li a{
	color: #eee;
	padding: 10px 15px;
}

.box{
	color: #222;
}

img{
	/* width: 100%; */
}
.container .bg_img{
	background: url(../images/01.jpg) no-repeat center center;
	background-size: cover;
	height: 500px;
}

/* 超小屏幕 手机 < 768px */
/* 小屏幕  平板 > 768px */
/* 中等屏幕 桌面显示器 >992px */
/* 大屏幕   超大桌面显示器>1200px */

/* 媒体查询 */
@media (min-width: 768px) {
	.container{
		width: 750px;
	}
	.nav-header h2,.nav-header a{
		display: none;
	}
	.nav-list {
		display: block;
	}
	.nav-list ul{
		float: left;
	}
	.nav-list ul.navbar-right{
		float: right;
	}
	.nav-list ul li{
		float: left;
	}
	.nav-list ul li a{
		font-size: 14px;
	}
	.nav-list ul li.hidden{
		display: none;
	}
}

@media (min-width:992px) {
	.container{
		width: 970px;
		
	}
	.nav-header h2{
		display: block;
	}
	.clearfix:after{
		clear: none;
	}
}
@media (min-width: 1200px) {
	.container{
		width: 1170px;
	}
	.nav-list ul li.hidden{
		/* Bootstrap2中文文档显示 */
		display: block;		
	}
}

font-awesome字体图标库的使用
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.bootcss.com/font-awesome/5.10.0-11/css/all.css" rel="stylesheet">
    <title>P10_font-awesome字体图标库的使用</title>
    <style type="text/css">
        .box{
            color:red;
        }
    </style>
</head>
<body>
    <div class="box">
        <i class="fa fa-camera-retro fa-lg"></i>
        <i class="fa fa-spinner fa-spin"></i>
    </div>
    <a href="https://www.bootcdn.cn/font-awesome/5.1.0-11/">font-awesome</a>
</body>
</html>

rem自适应布局

绝对单位

px:像素单位是绝对单位,你设置了多少,不管什么屏幕下,都会保持不变。
缺点:任何情况下都是固定值

相对单位

%:相对单位,它是相对于父级(自身)大小进行定位
缺点:能确定范围的还是比较好计算,对于不太好确定值的地方不好使用百分比,并且会导致变形,高度一般不好控制
em:相对于当前容器的字体大小进行变化
比如当前容器内字体大小为20px,那么1em = 20px
缺点:会根据当前容器字体大小发生变化,假设每个容器字体大小不一致,那么计算会非常繁琐
rem:font size of the root element。相对于当前根(html)元素的字体大小进行变化
比如当前设置html的字体大小为20px,那么1rem = 20px; 浏览器默认的1rem = 16px
动态修改font-size
!(function(doc,win){
    var docHtml = doc.documentElement;
    var recalc = function(){
        var clientW = docHtml.clientWidth;
        if(!clientW)return;
        // 修改成50px  设置html中font-size:50px;
        docHtml.style.fontSize = 100*(clientW/750) + 'px'; 
    }

    window.addEventListener('resize',recalc,false);

})(document,window)

resize.js代码

!(function(doc, win) {
    var docEl = doc.documentElement,
        resizeEvt = 'onorientationchange' in window ? 'onorientationchange' : 'resize',
        recalc = function() {
            var clientWidth = docEl.clientWidth;
            if (!clientWidth) return;
            if (clientWidth >= 750) {
                docEl.style.fontSize = '100px';
            } else {
                docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
            }
            docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
        };
    if (!doc.addEventListener) return;
    win.addEventListener(resizeEvt, recalc, false);
    doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
flexiable.js

flexiable.js是由淘宝官方提出来的最佳的h5移动适配解决方案。官网

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
    <!-- <meta name="flexible" content="initial-dpr=2" /> -->
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <!-- <script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script> -->
    <script src="js/lib-flexible-2.0/index.js"></script>
    <script src="js/lib-flexible-2.0/index.min.js"></script>
    <!-- <script type="text/javascript" src="js/resize.js"></script> -->
    <title>P13_案例_rem响应式布局的使用</title>
    <style type="text/css">
        *{
            padding:0px;
            margin:0px;
        }
        html,body{
            width:100%;
            height:100%;
        }
        html{
            font-size:100px;
        }
        .header{
            width:100%;
            height:70px;
            line-height:70px;
            text-align:center;
            background-color:#000;
            color:#fff;
            font-size:30px;
        }
        ul{
            list-style:none;
            display:flex;
            flex-wrap:wrap;
            justify-content: space-around;
            margin-top:0.2rem;
        }
        ul li{
            font-size:0.4rem;
        }
        ul li.item{
            width: 2.666666rem;
            height:2.666666rem;
            border:1px solid darkcyan;
            margin-bottom: 0.2666666rem;
        }

    </style>
</head>
<body>
    <header class="header">
        <div class="header_top">
            <h3>首页</h3>
        </div>
    </header>
    <ul>
        <li class="item" id="item1">1</li>
        <li class="item">2</li>
        <li class="item">3</li>
        <li class="item">4</li>
        <li class="item">5</li>
        <li class="item">6</li>
        <li class="item">7</li>
        <li class="item">8</li>
        <li class="item">9</li>
    </ul>

</body>
</html>