为什么响应式设计需要媒体查询
如何构造CSS3媒体查询
能够检测哪些设备特性
编写第一个CSS3媒体查询
为特定视口设定CSS样式
如何在iOS和Android设备上使用媒体查询
一 为什么响应式设计需要媒体查询
1.没有CSS3的媒体查询模块,就不能针对设备特性(如视口宽度)设置特定的CSS样式。
2.screen和print是两种已定义的媒体类型。媒体查询让样式有更强的针对性,扩展媒体类型的功能
媒体查询由媒体类型和一个或多个检测媒体特性的条件表达式组成,媒体查询可检测width,height,color等
3.媒体查询语法:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
body{
background: grey;
}
@media screen and (max-width: 960px){
body{
background: red;
}
}
@media screen and (max-width: 768px){
body{
background: orange;
}
}
@media screen and (max-width: 550px){
body{
background: yellow;
}
}
@media screen and (max-width: 320px){
body{
background: green;
}
}
</style>
</head>
<body>
<a href="#">Box Title</a>
</body>
</html>
演示效果:
4.link标签的media属性为样式表指定设备类型(如显示屏 /打印机),媒体查询则使我们根据设备的各种功能特性来设定相应的样式,而不仅仅只针对设备类型。及在HTML页面的head标签中插入link标签,例:
<link rel="stylesheet" href="screen-styles.css" type="text/css" media="screen">
当媒体查询问(可以问详细一些)如:“你是一块纵向放置的显示屏吗?”
<link rel="stylesheet" href="portraitscreen.css" media="screen and (orientation:portrait)">
①首先,媒体查询表达式询问了媒体类型(你是一块显示屏吗?),然后询问媒体特性(显示屏是纵向放置的吗?)
任何纵向放置的显示屏设备都会加载portrait-screen.css样式表,在媒体查询的开头追加not则会颠倒前例的效果,显示非纵向放置的显示屏设备加载样式:
<link rel="stylesheet" href="portatraitscreen.css" media="not screen and (orientation:portrait)">
②可以多个表达式组合一起,增加一个 限制只有视口宽度大于800像素的显示屏设备才能加载文件。
<link rel="stylesheet" href="800wide-portrait-screen.css" media="screen and (orientation:portrait) and (min-width:800px)">
<link rel="stylesheet" media="screen and (orientation:portrait) and (min-width:800px), projection" href="800wide-portrait-screen.css">
注意:1.媒体查询之间使用逗号分隔。2.projection之后没有按and没有任何特性/值得组合。没有后续表达式,以为只要是projection就满足条件
向页面的<head></head>标签中链接css文件时使用媒体查询,还可以在css样式表中使用媒体查询
在屏幕宽度小于等于400像素的设备上,h1元素的文字颜色会变为绿色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
@media screen and (max-device-width: 400px){
h1{
color: green;
}
}
</style>
</head>
<body>
<h1>hello world!</h1>
</body>
</html>
————————————————————————————————?????????????????
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
@media screen and (max-width: 400px){
h1{
color: green;
}
}
</style>
</head>
<body>
<h1>hello world!</h1>
</body>
</html>
还可以使用css的@import指令在当前样式表中按条件引入其他样式表
如:给视口最大宽度为360像素的显示屏设备加载一个名为phone.css的样式表
@import url("phone.css") screen and (max-width: 360px);
注意:使用css的@import方式会增加HTTP请求(影响加载速度),所以谨慎使用该方法
二.媒体查询能检测的特性
1.创建媒体查询,最常用的是设备的视口宽度(width)和屏幕宽度(device-width)
width :视口宽度。
height :视口高度。
device-width :渲染表面的宽度(对我们来说,就是设备屏幕的宽度)。
device-height :渲染表面的高度(对我们来说,就是设备屏幕的高度)。
orientation :检查设备处于横向还是纵向。
aspect-ratio :基于视口宽度和高度的宽高比。一个 16∶9 比例的显示屏可以这样定义 aspect-ratio: 16/9 。
device-aspect-ratio :和 aspect-ratio 类似,基于设备渲染平面宽度和高度的宽高比。
color :每种颜色的位数。例如 min-color: 16 会检测设备是否拥有 16位颜色。
color-index :设备的颜色索引表中的颜色数。值必须是非负整数。
monochrome :检测单色帧缓冲区中每像素所使用的位数。值必须是非负整数,如monochrome: 2 。
resolution :用来检测屏幕或打印机的分辨率,如 min-resolution: 300dpi 。还可以接受每厘米像素点数的度量值,如 min-resolution: 118dpcm 。
scan :电视机的扫描方式,值可设为 progressive (逐行扫描)或 interlace (隔行扫描)。如 720p HD电视(720p的 p即表明是逐行扫描)匹配 scan: progressive ,而 1080i HD 电视(1080i中的 i表明是隔行扫描)匹配 scan: interlace 。
grid :用来检测输出设备是网格设备还是位图设备。
在上述所有特性中,除 scan和 grid之外,都可使用 min和 max前缀来创建一个查询范围。
例如,分析如下所示的代码片段:
@import url("phone.css") screen and (min-width:200px) and (max-width:360px);
对 width 应用了 min 和 max 来设定查询范围。这样 phone.css 文件只会引入视口宽度介于 200像素至 360像素的显示屏设备。
2.用媒体查询改造设计
css代表层叠样式表(层叠)就是指样式表中后面的样式会覆盖前面相同的样式,因此我们可以在样式表的开头设置基本样式,以便适应所有设计,然后使用媒体查询来进一步重写相应的部分。
3.加载媒体查询的最佳方法
将不同媒体查询的样式保存到独立的文件中没有太大好处(个人喜好或为便于组织代码除外)。使用多个独立的文件会增加用于页面渲染的 HTTP请求数量,从而导致页面加载变慢
三.第一个响应式设计
1.例子:http://www.andthewinnerisnt.com/
2.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" http-equiv="Content-Type" content="text/html"> <title>Title</title> <link href="css/main.css" rel="stylesheet" type="text/css"> <style type="text/css"> #wrapper{ margin-right: auto; margin-left: auto; width: 960px; } #header{ margin-left: 10px; margin-right: 10px; width: 940px; background: #779307; } #navigation ul li{ display: inline-block; } #sidebar{ margin-left: 10px; margin-right: 10px; float: left; background: #fe9c00; width: 220px; } #content{ margin-right: 10px; margin-left: 10px; float: right; width: 700px; background: #dedede; } #footer{ margin-left: 10px; margin-right: 10px; clear: both; background: #663300; width: 940px; } </style> </head> <body> <div id="wrapper"> <div id="header"> <div id="navigation"> <ul> <li><a href="#">navigation1</a></li> <li><a href="#">navigation2</a></li> </ul> </div> </div> <div id="sidebar"> <p>here is the sidebar</p> </div> <div id="content"> <p>here is the content</p> </div> <div id="footer"> <p>here is the footer</p> </div> </div> </body> </html>
效果(常规导航栏+内容(侧栏和内容主题)+页脚)
3.重置样式是一组css声明,用来覆盖不同浏览器渲染HTML元素时的各种默认样式。
重置样式一般在主样式文件的开头用来将各个浏览器的自有默认样式重置成统一表现,确保样式表中后续追加的样式在不同浏览器中有相同的显示效果
4.响应式设计中要保证图片尽可能精简
5.小视口下的内容剪裁
在iOS上的Safari浏览器默认是在980px宽的画布上渲染页面,然后将画布缩小到与视口大小相匹配。虽然得放大页面才看得清,但是页面内容没有被切掉
四.阻止移动浏览器自动调整页面大小
1.viewport meta元素覆盖默认的画布缩放设置,只需在HTML的<head>标签中插入一个<meta>标签。在<meta>标签中设置具体的宽度(如像素值px)或缩放比例如2.0(设备实际尺寸的两倍)
例如:
① <meta name="viewport" content="initial-scale=2.0,width=device-width">
content="initial-scale=2.0是将页面放大两倍(同理0.5是缩小一半,3.0是放大3倍)
②width=device-width 浏览器页面的宽度应该等于设备宽度
③<meta>标签可以控制页面可缩放的范围,如下表示允许用户将页面最多放大至设备宽度的3倍,最小压缩至设备宽度的一半
<meta name="viewport" content="width=device-width,maximum-scale=3,minimum-scale=0.5">
④可以禁止用户缩放,只是辅助功能,很少禁用,如:
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
⑤缩放比例设置为1.0,为浏览器将按照其视口的实际大小来渲染页面
⑥宽度设为设备宽度,为支持该特性的浏览器都会按照设备宽度的实际大小来渲染页面
<meta name="viewport" content="width=device-width,initial-scale=1.0">
2.安装iOS和Android模拟器
下载Android软件开发工具包SDK,下载地址 http://developer.android.com/sdk/
iOS模拟器是Xcode开发包,安装Xcode 可以在~/Developer/Platforms/iPhoneSimulator.platform/Developer/Applications iOS Simulator.app路径下查到模拟器。
3.在css中编写,同样可以将浏览器视口宽度设置为320像素(Opera Mobile需要写@-o-viewport)
<style type="text/css"> @viewport { width: 320px; } </style>
五.针对不同视口宽度修正设计
1.设置 viewport meta标签后,任何浏览器都不再缩放页面了,现在我们可以针对不同视口
来修正设计效果
2.在 CSS中为平板设备(如 iPad)增加媒体查询,竖直 iPad的视口宽度是 768像素(横向视口宽度是 1024像素,此时页面渲染效果很理想)。
<style type="text/css"> @media screen and (max-width: 768px) { #wrapper { width: 768px; } #header,#footer,#navigation { width: 748px; } } </style>
为了解决导航区链接超出背景图和主内容区浮动在侧边栏之下(因为内容区太宽,在有限的空间内放不下)这两个问题,修改代码为:(侧边栏和内容区填满页面,且两边各留有适当的内边距)
<style type="text/css"> @media screen and (max-width: 768px) { #wrapper { width: 768px; } #header,#footer,#navigation { width: 748px; } #content,#sidebar { padding-right: 10px; padding-left: 10px; width: 728px; } } </style>
六.响应式设计中内容始终优先
1.设计在多平台多视口的情况下保留尽可能多的内容(而不是使用 display:none 或类似方法来隐藏部分内容),但也要意识到内容模块显示顺序的重要性。目前,页面中侧边栏和主内容区标签的顺序决定了侧边栏会显示在主内容区前面。显然,窄视
口设备的用户应该先看到主内容,而后再看到侧边栏。
2.还可以(或许应该)将内容区移到导航区域之上。这样那些使用小视口设备的用户就可以先看到主内容。这样无疑是坚决贯彻“内容优先”原则的合理做法。但是,多数情况下每个页面顶部还是应该有导航区,所以我乐得只将 HTML代码中的侧边栏和内容区位置互换一下,让内容区出现在侧边栏之前。当前代码结构如下:
<div id="sidebar"> <p>here is the sidebar</p> </div> <div id="content"> <p>here is the content</p> </div>
互换位置后的代码如下:
<div id="content"> <p>here is the content</p> </div> <div id="sidebar"> <p>here is the sidebar</p> </div>
虽然我们互换了标签位置,但页面在大视口中的显示效果没有变化,因为侧边栏和内容区分别使用了 float:left 和 float:right 属性。但是在 iPad上,则变成了首先显示内容区,下面才是侧边栏
使用调整好的HTML顺序,还为 768 像素宽的视口追加并替换了一些样式:
<style type="text/css"> @media screen and (max-width: 768px) { #wrapper, #header, #footer, #navigation { width: 768px; margin: 0px; } #logo { text-align: center; } #navigation { text-align: center; background-image: none; border-top-color: #bfbfbf; border-top-style: double; border-top-width: 4px; padding-top: 20px; } #navigation ul li a { background-color: #dedede; line-height: 60px; font-size: 40px; } #content, #sidebar { margin-top: 20px; padding-right: 10px; padding-left: 10px; width: 728px; } .oscarMain { margin-right: 30px; margin-top: 0px; width: 150px; height: 394px; } #sidebar { border-right: none; border-top: 2px solid #e8e8e8; padding-top: 20px; margin-bottom: 20px; } .sideBlock { width: 46%; float: left; } .overHyped { margin-top: 0px; margin-left: 50px; } } </style>
七.媒体查询只是必要条件之一
网站在 iPhone 的 320像素宽的小视口中显示得很糟糕。媒体查询尽其所能,根据设备特性应用了对应的样式。但问题是,现有的媒体查询只覆盖了小范围的视口。视口宽度小于 768 像素的设备都将看到内容被剪切,而视口介于 768 像素到 960 像素之间的设备,则会使用未受媒体查询样式影响的原有样式,结果我们已经知道了,一旦视口宽度小于 960 像素,页面就无法匹配
流动布局:
目前的情形是,页面捕捉到媒体查询设置的断点,然后布局发生变化。但在捕捉到下一个视口断点之前,页面静止不变
目前的效果更像是一个自适应设计,而不是我们想要的真正的响应式设计。我们的设计应该在突变之前保持灵动。要做到这点,需要将呆板的固定布局修改成灵活的流动布局。