移动端页面(一): 响应式
移动端交互注意点
既然我们是要做移动端的页面, 那么我们肯定首先要知道移动端的一些特点, 下面这四点我觉得是在做移动端页面的时候我们需要注意的
- 移动端没有hover
- 移动端一般我们用touch相关事件而不是click相关事件
- 移动端没有resize
- 移动端的滚动是没有滚动条的
meta viewport
不知道大家有没有这么一种经验, 在写html时, 如果页面不加下面这句
<meta name="viewport" content="width=device-width, initial-scale=1.0">
我们用手机访问这个页面的时候, 手机浏览器会按照PC页面的样式等比缩放到手机上, 然后字体图片都会缩的很小, 就像是把PC的页面强行缩放到手机那么大小来显示一样
其实这是一个历史遗留问题, iPhone兴起之初, 那时候手机还是诺基亚一统天下, 经历过那个时代的人一定还记得, 我们当时用手机浏览网页都是浏览的wap站点, 并非html页面, wap站点一般都很简陋, 没有什么用户体验, 后来iPhone为了让用户有更好的用户体验, 想到了一个方案, 通过多方研究, 苹果决定在手机上显示页面时, 模拟PC上宽度为980px的页面显示, 并等比例缩放到手机屏幕上, 用户就可以在手机上看到跟PC端一样的页面了, 用户可以通过放大页面来观看页面的内容, 这就是为什么我们在不加viewport时, 手机页面会按照PC页面等比缩放的原因
所以, 一般我们在做移动端布局的时候,都要加下面这句话
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
媒体查询
这个名字听起来很奇怪, 其实我也不知道为什么叫这个名字, 但是其实这个东西很简单, 我个人理解这其实就是html和css中的if语句
在css中直接使用媒体查询
下面我们举个栗子
@media (max-width: 500px) {
body {
background: red;
}
}
这个例子就代表当页面宽度小于等于500px时, body显示红色, 大于500px时则不生效, 是不是跟js里的if很像呢?
下面我们扩充一下上面的例子, 通过媒体查询, 在不同的屏幕尺寸下显示不同的背景颜色
@media (min-width: 769px) {
body {
background: #000;
}
}
@media (max-width: 768px) {
body {
background: blue;
}
}
@media (max-width: 425px) {
body {
background: green;
}
}
@media (max-width: 375px) {
body {
background: yellow;
}
}
@media (max-width: 320px) {
body {
background: red;
}
}
可能有人注意到了, 我的宽度是由宽到窄写的, 这是为什么呢?
我们可不要忘了, 后写的CSS属性会覆盖先写的, 所以假设我们这样写
@media (max-width: 320px) {
body {
background: red;
}
}
@media (max-width: 768px) {
body {
background: blue;
}
}
我们屏幕尺寸为320px时, 我们的本意是想让背景为红色, 但是背景却是蓝色, 因为尺寸为320px时, 既满足max-width: 320px
又满足max-width: 768px
, 后写的覆盖先写的属性, 所以蓝色会覆盖红色,
@media (max-width: 768px) {
body {
background: blue;
}
}
@media (max-width: 320px) {
body {
background: red;
}
}
如果max-width:320px
写后面, 那么由于后面的属性会覆盖前面的, 那么红色就会覆盖蓝色, 这样才符合我们的要求
我们还可以设置同时满足多个条件的媒体查询
@media (min-width: 300px) and (max-width: 320px) {
body {
background: red;
}
}
这个表示宽度在300到320之间的时候, 背景为红色
所以上面的那个适应各种屏幕栗子, 如果非要从小到大写的话, 我们可以这样写
@media (max-width: 320px) {
body {
background: red;
}
}
@media (min-width: 321px) and (max-width: 375px) {
body {
background: yellow;
}
}
@media (min-width: 376px) and (max-width: 425px) {
body {
background: green;
}
}
@media (min-width: 426px) and (max-width: 768px) {
body {
background: blue;
}
}
@media (min-width: 769px) {
body {
background: #000;
}
}
在引入css文件时使用媒体查询
我们也可以在引入css文件时使用媒体查询
<link rel="stylesheet" href="./style.css" media="only on screen and (max-width: 320px)">
上面这段代码表示, 当宽度小于等于320px的时候, 我们的link标签才生效, 但是需要注意, 无论生效与否, css文件都会先加载
来个简单实例吧
我们这里做一个导航栏, 在手机界面下和pc界面下能自动切换导航样式, 来满足不同屏幕尺寸要求
这里推荐使用mobile-first方案, 就是先做手机界面, 再做pc界面
<!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>移动页面demo</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<header>
<div class="logo"></div>
<button id="menu">菜单</button>
<nav id="nav">
<ul class="clearfix">
<li><a href="#">导航1</a></li>
<li><a href="#">导航2</a></li>
<li><a href="#">导航3</a></li>
<li><a href="#">导航4</a></li>
<li><a href="#">导航5</a></li>
</ul>
</nav>
<nav id="nav2">
<ul class="clearfix">
<li><a href="#">导航1</a></li>
<li><a href="#">导航2</a></li>
<li><a href="#">导航3</a></li>
<li><a href="#">导航4</a></li>
<li><a href="#">导航5</a></li>
</ul>
</nav>
</header>
<script>
menu.onclick = () => {
nav.classList.toggle('active')
}
</script>
</body>
</html>
* {
margin: 0;
padding: 0;
list-style: none;
text-decoration: none;
color :black;
}
.logo {
width: 60px;
height: 60px;
background: #666;
border-radius: 50%;
}
button {
position: absolute;
right: 20px;
top: 20px;
border: 1px solid #666;
}
#nav2 {
display: none;
}
@media (min-width: 451px) {
header {
display: flex;
justify-content: space-between;
align-items: center;
}
button {
display: none;
}
#nav.active {
display: none !important;
}
#nav2 {
display: block;
background: #666;
}
#nav2 ul {
display: flex;
justify-content: space-between;
}
#nav2 ul li {
margin: 0 40px;
}
}
#nav {
display: none;
margin: 10px 0;
}
#nav.active {
display: block;
}
#nav.active ul{
display: flex;
justify-content: space-between;
background: #666;
}
#nav li {
float: left;
}
.clearfix::after {
content: '';
display: block;
clear: both;
}
另一种方案
因为媒体查询写起来很麻烦, 现在又出现了另一种比较流行的方案
- 首先做两套页面方案, 一套PC, 一套移动端
- 两套方案对应两个不同的URL地址
- 检查用户代理, 如果检测出来的是移动设备, 则登陆到移动端页面, 如果检测出来是PC, 则到PC页面
这个方案在这里就不展开了, 毕竟我们今天主要讨论的是响应式, 各位如果对这种方案有兴趣, 请自行google, 或者等我以后专门写一篇关于这种方案的文章吧