Every year when I watch the Oscars I'm annoyed...
that films like King Kong,Moulin Rouge and Munich get the statue whilst the real cinematic heros lose out. Not very Hollywood is it?
We're here to put things right.
these should have won »前段时间在微博上看到了几个在当今前端圈中的大牛的撕逼大战,作为一个前端小白来说就只是看热闹的,热闹中看到了两本书,《无懈可击的Web设计》和《响应式Web设计》,前者没有买到纸质版,后者刚好在快要缺货的时候买到了,所以这段时间一直在看这本书,所以可想而知,这篇博文的观点也都不是我的,只是把书中的内容理解化后形成了本文。不出意外的话,这是一篇需要历经一段时间的长文。
- 支持小屏幕设备的重要性
- 什么是移动网站设计
- 什么是响应式网页设计
- 优秀响应式网页实例欣赏
- 视口和屏幕的区别
- 使用HTML5编写更简洁的标记
- 使用CSS3解决常见的设计问题
响应式网页设计这个术语是将三种已有的开发技巧(弹性网格布局、弹性图片、媒体和媒体查询)整合起来并命名为响应式网页设计,这个术语还有一堆其他相同意思的叫法,如流式设计、弹性布局、塑料布局、流体设计、自适应布局、跨设备设计以及弹性设计。真正的响应式设计方法 不仅仅只是根据视口大小改变网页布局,相反,它是要从整体上颠覆当前设计网页的方法,以往我们先是针对桌面电脑进行固定宽度设计,然后将其缩小并针对小屏幕进行内容重排;现在我们应该首先针对小屏幕进行设计,然后逐步增强针对大屏幕的设计和内容。
一句话概括响应式网页设计
如果要用一句话概括响应式网页设计,我觉得它是针对任意设备对网页内容进行完美布局的一种显示机制。相反,如果需要根据不同设备提供特定的内容和功能,那就需要一个真正的“手机版”网站,这种情况下,手机版网站会提供与桌面版网站完全不同的用户体验。
启动你的浏览器打开这些网页之后逐步的缩小你的浏览器窗口,然后就可以看到网页在不同视口宽度的展示效果。顺带在这里介绍一下视口和屏幕尺寸的区别。
视口和屏幕尺寸
视口和屏幕尺寸不是同一个概念。视口是指浏览器窗口内的内容区域,不包含工具栏、标签栏等,也就是网页实际显示的区域。屏幕尺寸指的是设备的物理显示区域。需要注意的是有些浏览器调整工具显示的尺寸包含浏览器的其他元素,诸如地址栏、标签栏和搜索栏,而有些工具则不是这样。
在创建可以通过W3C标准验证的页面时,HTML5强调简化标签,仅链接那些我们必须的CSS、JavaScript和图片文件。智能手机用户只能使用有限的带宽访问页面,而响应式设计的一个主要目标就是:网页不仅要对用户有限的视口做出响应,还要以最快的时间加载页面,虽然移除冗余的标签元素只能节省一点字节,但积少成多。在此,只列举几个简单的实例,不做更多描述。
HTML4.01:
HTML5:
HTML4.01:
HTML5:
关于CSS3,最鼓舞人心的一点应该是在老版本浏览器使用它们无法解析的属性不会造成任何问题。它们(包括Internet Explorer 6、7、8)会欣然忽略那些无法解析的属性,这使我们能够为那些先进的浏览器进行渐进增强设计,同时为老版本浏览器提供合理的优雅降级处理。
圆角效果在CSS2.1中使用滑动门技术实现,而在CSS3中使用border-radius
则可以轻松实现。
鼠标悬停后的漂浮效果
CSS3动画效果
使用CSS3制作的炫酷效果
使用HTML5和CSS3的响应式网页设计不是解决所有设计和内容服务问题的灵丹妙药。
- 允许页面显示效果在老旧浏览器中有细微的差别,这样可以使代码更易维护,将来更新的成本也很低。
- 让页面元素在那些老旧浏览器(如Internet Explorer 8及更低版本)中表现一致会导致网站增加大量的图片。这会使网站变慢,制作成本更高,而且更难维护。
- 现代浏览器可以理解的简洁代码等同于更快速的网站。快速响应的网站在搜索引擎中的评级高于慢腾腾的网站。
- 使用老旧浏览器的用户越来越少,使用现代浏览器的用户越来越多————我们应该支持大多数。
- 为什么响应式设计需要媒体查询
- 如何构造CSS3媒体查询
- 媒体查询可以检测哪些设备特性
- 编写第一个CSS3媒体查询
- 为特定视口设定CSS样式
- 如何在iOS和Android设备上使用媒体查询
媒体查询由媒体类型和一个或多个检测媒体特性的条件表达式组成。媒体查询中可用于检测的媒体特性有width、height和color等。使用媒体查询,可以在不改变页面内容的情况下,为特定的一些输出设备定制显示效果。
媒体查询的语法:
body{
background-color:grey;
}
@media screen and (max-width:960px){
body{
background-color:red;
}
}
@media screen and (max-width:768px){
body{
background-color:orange;
}
}
@media screen and (max-width:550px){
body{
background-color:yellow;
}
}
@media screen and (max-width:320px){
body{
background-color:green;
}
}
媒体查询可以从两个角度充分利用其特性,即按条件加载样式文件和按条件加载样式规则。在CSS2中可以通过标签的
media
属性为样式表指定设备类型:
媒体查询不仅可以针对设备的类型进行设定特定的样式,还可以针对媒体特性来进行设定样式:
除此之外,还可以对媒体特性进行更具体的设置,比如限制视口宽度大小满足条件才可以加载文件:
另外则是基于媒体查询按条件加载样式规则,
@media screen and (max-device-width:400px){
h1{
color:green
}
}
还可以使用@import
指令在当前样式表中按条件引入其他样式表,例如下面的代码会给视口最大宽度为360像素的显示屏设备加载一个名为phone.css
的样式表。
@import url("phone.css") screen and (max-width:360px)
但是,使用CSS的@import
方法会增加HTTP请求,影响加载速度。
媒体查询能检测哪些特性
创建媒体查询时,最常用的设备的视口宽度(
width
)和屏幕宽度(device-width
),很少需要检测其他特性,但是为方便查阅,在此列出所有可供媒体查询检测的特性。
width
:视口宽度height
:视口高度device-width
:设备屏幕的宽度device-height
:设备屏幕的高度orientation
:检测设备处于横向还是纵向aspect-ratio
:基于视口宽度和高度的宽高比device-aspect-ratio
:基于设备屏幕宽度和高度的宽高比color
:每种颜色的位数color-index
:设备的颜色索引表中的颜色数monochrome
:检测单色帧缓冲区中每像素所使用的位数resolution
:用来检测屏幕或打印机的分辨率scan
:电视机的扫描方式,值可设为progressive
或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像素之间的显示屏设备。
首先基于960像素的固定宽度来制作一个标配的界面原型,即包含header
, navigation
, content
,footer
的标配界面,结果和代码如下:
HTML代码:
here is the content响应式网页设计响应式网页设计响应式网页设计
CSS代码:
#wrapper{
margin-right: auto;
margin-left: auto;
width: 960px;
}
#header{
margin-left: 10px;
margin-right: 10px;
width: 940px;
background-color: #779307;
}
#navigation ul li{
display: inline-block;
}
#content{
margin-right: 10px;
float: right;
margin-left: 10px;
width: 700px;
background-color: #dedede;
}
#sidebar{
margin-left: 10px;
margin-right: 10px;
float: left;
background-color: #fe9c00;
width: 220px;
}
#footer{
margin-left: 10px;
margin-right: 10px;
clear: both;
background-color: #663300;
width: 940px;
}
以上这组代码是在960像素的固定宽度下构建的,当视口宽度小于960像素或者当在iOS,Android设备上浏览时,结果如下两图:
从上边两张图片可以看出来两点:当视口宽度减小到小于960像素时候,右侧的内容区开始被截断;在iOS上的Safari浏览器默认是在980像素宽的画布上渲染页面,然后将画布缩小到视口大小匹配,虽然得放大页面才能看清楚,但页面内容没有被切掉。
阻止移动浏览器自动调整页面大小
iOS和Android浏览器都基于Webkit核心。这两种浏览器以及很多其他浏览器(如Opera),都支持用
viewport meta
元素覆盖默认的画布缩放设置。只需要在HTML的标签中插入一个
标签。
标签中可以设置具体的宽度或者缩放比例例如2.0(设备实际尺寸的两倍)。下面是一个将页面放大到设备实际尺寸两倍显示的
meta
标签的示例:
设置完了viewport meta
标签之后,任何浏览器都不再缩放页面了,其结果如下图:
现在就可以针对不同视口来修正设计效果了。首先在CSS中为平板设备增加媒体查询,竖直的iPad的视口宽度是768像素(横向视口宽度是1024像素,此时页面渲染效果已经很佳)。
横向视口宽度下的渲染效果:
追加媒体查询的代码之后纵向视口宽度下的渲染效果为:
媒体查询只是必要条件之一,我们需要流动布局
如果针对已知的特定访问设备,可以单独使用媒体查询来制作理想的设计效果,我们已经见过专门适配iPad有多简单。但是这种策略有严重的缺陷,换句话说,它不能适应未来的变化。目前的情形是,页面捕捉到媒体查询设置的断点,然后布局发生变化。但在捕捉到下一个视口断点之前,页面静止不变,因此需要更好的策略。针对各种视口的排列组合编写对应的CSS样式,无法兼容未来可能出现的设备;而一个完美的设计往往能在一定程度上适应未来的发展。在这点上我们目前的解决方案尚不完备,目前的效果更像是一个自适应设计,而不是我们想要的真正的响应式设计。我们的设计应该在突变之前保持灵动,要做到这点,就需要将呆板的固定布局修改成灵活的流动布局。
- 为什么响应式设计需要百分比布局
- 将元素的固定像素宽度转换为百分比宽度
- 将文字的固定像素大小转换为等量的相对尺寸
- 如何找到任意元素的上下文
- 让媒体查询与弹性图片及流式布局协同工作
在认识到媒体查询威力无比的同时,也要看到它的局限性。那些仅使用媒体查询来适应不同视口的固定宽度设计,只会从一组CSS媒体查询规则突变到另一组,两者之间没有任何平滑渐变。当某个视口处于媒体查询设置的固定宽度范围之外(可能是某种未知的未来设备及视口),网页就需要水平滚动才能完整浏览,因此我们需要将固定像素布局转换成灵活的百分比布局,这样才能让页面元素根据视口大小在一个又一个媒体查询之间灵活伸缩修正样式。
将固定像素宽度转换为对应的百分比宽度依照如下公式:
目标元素宽度/上下文元素宽度=百分比宽度
将固定像素宽度元素转换为百分比之后还需要将文字的固定像素大小转换为等量的相对尺寸,用em代替px。em的实际大小是相对于其上下文的字体大小而言的,所以上述公式同样适用文字固定像素宽度的转换,值得注意的是,现代浏览器的默认文字大小都是16像素。
处理完了元素和文字大小后,则是需要实现图片随视口的缩放。在现代浏览器(包括IE7+)中要实现图片随着流动布局相应缩放非常简单,只需要在CSS中作如下声明:
img{
max-width:100%;
}
在实现了以上三个处理之后,CSS代码即变为如下所示(其中HTML结构是不变的):
img{
max-width: 100%;
}
#wrapper{
margin-right: auto;
margin-left: auto;
width: 93.7%;
}
#header{
margin-left: 1.041%;
margin-right: 1.041%;
width: 97.9%;
}
#logo{
text-align: left;
font-family: Arial;
font-size: 2em;
text-transform: uppercase;
}
#navigation{
padding-bottom: 25px;
margin-top: 26px;
margin-left: -1.041%;
padding-right: 1.041%;
padding-left: 1.041%;
width: 97.9%;
background-repeat: repeat-x;
background-position: 0 -130px;
background-image: url(bg.jpg);
border-bottom-color: #bfbfbf;
border-bottom-style: double;
border-bottom-width: 4px;
}
#navigation ul li{
display: inline-block;
margin-right: 2.6595%;
}
#navigation ul li a{
height: 42px;
line-height: 42px;
text-decoration: none;
text-transform: uppercase;
font-size: 27px;
color: black;
font-family: Arial;
}
#sidebar{
border-right-color: #e8e8e8;
border-right-style: solid;
border-right-width: 2px;
margin-top: 58px;
margin-right: 1.041%;
margin-left: 1.041%;
float: left;
width: 22.7%;
font-family: Arial;
}
.sideBlock{
width: 92%;
float: left;
}
.sideBlock img{
max-width: 45%;
}
.unSung{
margin-top: 0;
margin-left: 15px;
}
.overHyped{
margin-top: 0;
margin-left: 15px;
}
#content{
margin-top: 58px;
margin-right: 1.041%;
padding-right: 1.041%;
float: right;
width: 72.7%;
font-family: Arial;
}
.oscarMain{
float: left;
margin-top: -28px;
width: 28.94%;
}
#content h1{
font-family: Arial;
text-transform: uppercase;
font-size: 4.3125em;/*69/16*/
}
#content h1 span{
display: block;
line-height: 1.052631579em;/*40/38*/
color: #757474;
font-size: .550724638em;/*38/69*/
}
#footer{
float: left;
margin-top: 20px;
margin-right: 1.041%;
margin-left: 1.041%;
clear: both;
background-repeat: repeat-x;
background-position: 0 -130px;
background-image: url(bg.jpg);
width: 97.9%;
}
@media screen and (max-width: 768px){
#wrapper,#header,#footer,#navigation{
width: 768px;
margin: 0;
}
#logo{
text-align: center;
font-family: Arial;
font-size: 2em;
}
#navigation{
text-align: center;
background-image: none;
background-repeat: repeat-x;
background-position: 0 -130px;
background-image: url(bg.jpg);
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-left: 10px;
padding-right: 10px;
width: 728px;
}
#sidebar{
border-right: none;
border-top: 2px solid #e8e8e8;
padding-top: 20px;
margin-bottom: 20px;
}
}
同时HTML代码结构也可以采用HTML5新增的更加语义化的标签来进行重构如下:
And the winner isn't
And the winner isn't...
Every year when I watch the Oscars I'm annoyed...
that films like King Kong,Moulin Rouge and Munich get the statue whilst the real cinematic heros lose out. Not very Hollywood is it?
We're here to put things right.
these should have won »
当视口宽度为1280px时页面展示结果为:
当视口宽度为1024px时页面展示结果为:
当视口宽度为886px时页面展示结果为:
当视口宽度为768px时页面展示结果为:
流动布局和媒体查询的默契配合
媒体查询约束流动布局的变动范围,而流动布局则简化了从一组媒体查询样式过渡到另一组媒体查询样式的改变过程。
- 使用CSS3制作文字阴影
- 使用CSS3制作盒阴影(即元素阴影)
- 使用CSS3制作渐进背景
- 使用CSS3的多重图片背景
- 使用CSS3背景渐变来制作图案
- 使用CSS3的
@font-face
规则来制作节省带宽的图标
CSS3对响应式设计非常有用:使用CSS3替代图片,在有限带宽的网页中可有效减少http请求(从而使网页加载更快),并可使网页更灵活、更容易维护。
阴影值的速记规则永远是先向右再向下。因此,第一个值指的是右侧阴影的大小,第二个值指的是下方阴影的大小,第三个值指的是模糊距离(即阴影从开始变淡到完全消失的距离),最后一个值是阴影颜色。其中,阴影颜色使用HEX、HSL和RGB颜色都可以,阴影值也可以使用px、em或者rem单位。
在系列博文中,CSS中添加如下代码后:
text-shadow:.039em .039em 0em #dad7d7;
结果如下:
如需要取消文字阴影的话,则在对应元素山添加如下CSS代码后:
text-shadow:none;
结果如下:
还可以制作左上方阴影,如下代码:
text-shadow:-.039em -.039em 0em #dad7d7;
如下结果:
还可以制作浮雕文字阴影效果,此效果使文字有了一点凹陷效果,同时又没有过分炫耀文字阴影!如下代码:
text-shadow:0 1px 0 hsla(0,0%,100%,0.75);
如下结果:
还可以制作多重文字阴影,只需将两组值使用逗号分隔开即可,比如下代码:
text-shadow:0px 1px #fff,4px 4px 0px #dad7d7;
如下结果:
盒阴影的语法与文字阴影完全一样:水平偏移距离、垂直偏移距离、模糊半径,以及阴影颜色。但是,盒阴影的跨浏览器支持并不好,所以明智的做法是使用浏览器私有前缀,例如:
-webkit-box-shadow:0px 3px 5px #444;
-moz-box-shadow:0px 3px 5px #444;
-o-box-shadow:0px 3px 5px #444;
-ms-box-shadow:0px 3px 5px #444;
-khtml-box-shadow:0px 3px 5px #444;
box-shadow:0px 3px 5px #444;
系列博文中如下代码:
.sideBlock img{
max-width:45%;
box-shadow:0px 3px 5px #444;
}
如下效果:
box-shadow
属性可以用来制作内阴影——出现在元素内部,而不是外部。内阴影可用来制作光晕效果,如下所示:
box-shadow:inset 0 0 40px #000000;
语法和之前的盒阴影差不多,只是多出来的inset告诉浏览器设置内阴影效果。现在给标签应用此规则,为整个页面添加光晕效果,这样就会让页面的四周都出现阴影。
body{
-moz-box-shadow:inset 0 0 30px #000000;
-webkit-box-shadow:inset 0 0 30px #000000;
box-shadow:inset 0 0 30px #000000;
}
浏览器中的效果如下:
和文字阴影一样,盒阴影也可以有多重阴影效果。语法也类似,即将两组值用逗号分开,这样两组阴影就会按照代码中的先后顺序从上到下应用到元素上。换句话说,就是代码中先声明的规则在浏览器中会覆盖下面的规则。
box-shadow:inset 0 0 30px hsl(0,0%,0%),
inset 0 0 70px hsla(0,97%,53%,1);
将这段代码加到body上效果如下:
在没有CSS3的时候,如果想做一个背景渐变效果,就得使用一个很细的渐变切片进行水平或者垂直平铺。对于使用图片来说,这确实是一种很好的折中方案。一张仅有一两像素宽的图片,不会给带宽造成太大的负担,而且它可以用在网站上的多个元素上。
给网站的侧边栏制作一个背景渐变效果,只需要添加如下代码:
background: linear-gradient(90deg,#fff 0,#e4e4e4 50%,#fff 100%);
在支持该特性的浏览器中效果如下:
线性背景渐变语法有点复杂,对其做一个分解:
- 圆括号中的第一个值定义了渐变的方向。不定义该值则默认是一个垂直从顶部到底部的渐变。还可以使用如
to top right
这样的值产生一个朝向右上角的对角线渐变。- 下一个值定义的是渐变的起点,包括起点的颜色和位置。也可以使用像
blue 20%
这样的值,这样就是从蓝色开始渐变到下一个颜色,而渐变开始位置则位于假想的渐变路径的20%处。- 下一个值指的是“过渡颜色点”,和起点一样定义了位置和颜色。如果需要的话,可以在渐变“终点”之前定义更多的过渡颜色点(使用逗号分割)。
- 圆括号中的最后一个值始终是渐变的“终点”。不论在起点之后放置了多少个过渡颜色点,最后一个值始终是终点。
CSS3背景渐变不只局限于线性渐变,制作径向渐变同样简单。径向渐变是从一个中心点开始,依据椭圆形或者圆形进行扩张渐变。
径向背景渐变语法如下:
background: -webkit-radial-gradient(center,ellipse cover,#fff 72%,#ddd 100%);
将这个声明追加到#content
规则中,产生的效果如下所示:
分解径向渐变语法
- 圆括号中的第一个值定义了径向开始渐变的起点,本例子中使用了
center
,其实也可以使用如25px 25px
这样的值,这就表示从距元素上边和左边均为25px的那个点开始渐变;- 下一个值指定的是径向渐变的形状和大小,值为
circle,ellipse
等;- 接下来定义渐变起点、过渡颜色点以及终点(这部分和线性渐变是一样的)。
先看一个例子,将刚才给body设置的重复渐变替换为下面的样式:
body{
background-color: white;
background-image:
-webkit-radial-gradient(hsla(0,0%,87%,0.31) 9px,transparent 10px),
-webkit-repeating-radial-gradient(hsla(0,0%,87%,0.31) 0,
hsla(0,0%,87%,0.31) 4px,transparent 5px,
transparent 20px,hsla(0,0%,87%,0.31) 21px,
hsla(0,0%,87%,0.31) 25px,transparent 26px,
transparent 50px);
background-size: 30px 30px,90px 90px;
background-position: 0 0;
}
浏览器中的效果如下图:
CSS高手Lea Verou收集了一系列CSS3背景渐变图案,具体请见http://lea.verou.me/css3patterns/
本来还有一些内容,主要是介绍使用HTML5和CSS3玩转表单以及关于浏览器适配等问题,但由于最近身体抱恙导致不能继续,因此陆陆续续的也算是经历了一个过程后完成了本文,其中有不对之处欢迎指正,同时也为原书做一下宣传,很不错的一本书,《响应式web设计》。