etc.
注意:请使用 Chrome 浏览,因为很多地方我并没有针对Firefox, Opera开发
注意: 这绝对不是一个完整的HTML5的介绍,有机会的话或许会慢慢补齐。
其实如果完整的去学习一套理论,对谁都是一个很大的负担。我只是希望大家看过这些介绍之后,能确实有所获得,那么在以后的学习中,能带着一些思考去学习,可能效果会更好。
我刚开始学习JavaScript的时候,看的JavaScript: the Definitive Guide。
但是事实证明,当时选择那本书绝对是不明智的,事实上我也没能坚持看完,
看了几十页就不看了。在做了不少的项目和一些历练之后,我回过头再去看这
本大而全的书的时候,体会则完全不一样了,会有一种融会贯通的感觉。
一个典型的优化过的移动端站点通常含有这样的一个属性:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
Viewport的属性共有7种:
width=device-width
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
竖屏 横屏
width=320
<meta name="viewport" content="width=320">
竖屏 横屏
注: 我的经验中,设置了固定的width以后,scale相关属性一般不生效
initial-scale
= Float Number(如 1.0 / 1 / 0.5)minimum-scale
= Float Number(如 1.0 / 1 / 0.5)maximum-scale
= Float Number(如 1.0 / 1 / 0.5)user-scalable
= [ yes | no ]CSS pixel与device pixel
每个CSS pixel所含有的device pixel不是固定的,一般来说
1 CSS pixel = devicePixelRatio^2 个device pixel
PPI,有时也叫DPI,所表示的是每英寸所拥有的像素(pixel)数目,数值越高,即代表显示屏能够以越高的密度显示图像。
注:这里的像素,指的是device pixels。
PPI准确的计算公式:
<meta name="viewport" content="target-densitydpi=device-dpi,width=device-width, initial-scale=1,maximum-scale=1">
.header { background:url (medium-density-image.png); } @media screen and (-webkit-device-pixel-ratio:2.0) { .header { background:url (retina-density-image.png);} /* CSS for retina-density screens */ } @media screen and (-webkit-min-device-pixel-ratio:1.5) and (-webkit-max-device-pixel-ratio:1.99){ .header { background:url (high-density-image.png);} /* CSS for high-density screens */ } @media screen and (-webkit-max-device-pixel-ratio:0.75) { .header { background:url (low-density-image.png);} /* CSS for low-density screens */ }
移动端用户有的时候会开启自动旋转,需要考虑旋转之后的布局等安排 一般说来,处理的方式有两种:
JavaScript
Media Query
可以通过JavaScript来监控屏幕转动
window.onorientationchange = function() { /*Do Something*/ }; // 或者使用jQuery $(window).on("orientationchange", function() { /*Do Something*/ });
同时,还有一个属性:
window.orientation 表明当前旋转的角度
0 / 90 / -90 / 180
如果仅仅是跟布局相关的,通过Media Query或许是最好的选择
@media (orientation: portrait) { /* Some CSS for portrait */ } @media (orientation: landscape) { /* Some CSS for landscape */ }
其实很多时候使用Media Query,很多时候也不需要考虑是横向还是纵向。 只需要针对宽度做适配即可:
@media screen and (max-width: 479px) { /* Some CSS for Width < 480 */ .desc { background: yellow; } } @media screen and (min-width: 480px) and (max-width: 639px) { /* Some CSS for 480 <= Width < 640 */ .desc { background: blue; } } @media screen and (min-width: 640px) and (max-width: 1023px) { /* Some CSS for 640 <= Width < 1024 */ .desc { background: green; } } @media screen and (min-width: 1024px) { /* Some CSS for Width >= 1024 */ .desc { background: red; } }
@media screen and (max-width: 479px) {.desc { background: yellow; } } @media screen and (min-width: 640px) and (max-width: 1023px) {.desc { background: green; } }
400x519 640x327
@media screen and (min-width: 1024px) {.desc { background: red; } }
前文中讲到通过 target-densitydpi 改变 devicePixelRatio 来优化retina屏幕显示。 但是实际操作中,这样会非常吃力。
实际上,目前也没有一个权威的并且成熟的解决方案。(我还没找到)
各种方案也是百花齐放,我这里只介绍一种我自己的解决方案(绝对不是最好的方案),
有兴趣的同学可以多些了解关于 **响应式图片** 相关的内容。
.header { background-image:url(http://path/of/pic/normal.png); /* 普通屏幕 */ /* ------------ Retina ------------ */ @media only screen and (-o-min-device-pixel-ratio: 2/1), /* Opera */ only screen and (min--moz-device-pixel-ratio: 2), /* Firefox 16 之前 */ only screen and (-webkit-min-device-pixel-ratio: 2), /* Webkit */ only screen and (min-resolution: 240dpi), /* 标准 */ only screen and (min-resolution: 2dppx) /* 标准 */ { .header { background-image:url(http://path/of/pic/large.png); background-size: 50% 50%; } }
<img data-src="http://path/of/pic/normal.png" data-src-2x="http://path/of/pic/large.png" width="400px" height="300px"/> <script type="text/javascript"> $('img[data-src-2x]').each(function() { if (window.devicePixelRatio === 2) { // this.src = this.dataset.src2x; this.src = $(this).attr("data-src-2x"); }else { // this.src = this.dataset.src; this.src = $(this).attr("data-src"); } }); </script>
如果需要判断当前手机是否联网,其实很简单。。。
通过 JavaScript 判断 navigator.onLine
:返回值 true
/ false
<button id="intro-online">点我查看是否在线!</button> <script type="text/javascript"> var onlineBtn = document.getElementById("intro-online"); onlineBtn.addEventListener("click", function() { if (navigator.onLine) alert("ONLINE!"); else alert("OFFLINE!"); }); </script>
同时还有两个 JavaScript的 Events: ononline
, onoffline
Android 2.2+ 以后的内置Webkit中:
navigator.connection = { "type": "4", "UNKNOWN": "0", "ETHERNET": "1", "WIFI": "2", "CELL_2G": "3", "CELL_3G": "4" }
我们可以写出类似于这样的代码:
if (navigator.onLine) { var connection = navigator.connection || navigator.webkitConnection || navigator.mozConnection || {type: 0}; switch(connection.type) { case connection.CELL_3G: // 3G connectionSpeed = 'mediumbandwidth'; break; case connection.CELL_2G: // 2G connectionSpeed = 'lowbandwidth'; break; default: // WIFI, ETHERNET, UNKNOWN connectionSpeed = 'highbandwidth'; } }
注:ECMAScript 5中有不同的定义,而且在目前的手机Chrome上无效果
新的元素,含有语意的元素等
<style> [required] {border-color: #88a; -webkit-box-shadow: 0 0 3px rgba(0, 0, 255, .5); } :invalid {border-color: #e88; -webkit-box-shadow: 0 0 5px rgba(255, 0, 0, .8); } </style> <input type="text" required /> <input type="email" value="zhang.gd@foxmail.com" /> <input type="date" min="1988-01-01" max="2013-12-12" value="2013-02-22"/> <input type="range" min="0" max="50" value="10" /> <input type="search" results="10" placeholder="搜索..." /> <input type="tel" placeholder="021-22228888" pattern="^\d{3,4}[-\s]\d{8}$" /> <input type="color" placeholder="e.g. #bbbbbb" /> <input type="number" step="1" min="-5" max="10" value="0" />
通过HTML5的标签实现进度类的有的时候显得非常简单……
<meter min="0" max="100" low="40" high="90" optimum="100" value="91">A+</meter> <progress value="75" max="100">3/4 complete</progress> <progress></progress>
<input list="names"/> <datalist id="names"> <option value="Abe"/> <option value="Carl"/> <option value="David"/> <option value="Joe"/> <option value="Mac"/> <option value="Michael"/> <option value="Peter"/> </datalist>
强烈推荐:
Apache: weinre
这里介绍了移动端的viewport,orientation,以及一些新的HTML5元素,属性。
移动端必然是一个趋势,
相关的开发这里只是一个抛砖引玉,
还是需要在持续的使用中总结和尝试。
CSS3引入了非常多有趣的技术和效果。
我们这里挑出一些比较成熟的,
有代表性的来一起看看。
其中有些可能大家已经很熟悉了,
这里还是做一次回顾。
.round { border-radius: 30px; -o-border-radius: 30px; -ms-border-radius: 30px; -moz-border-radius: 30px; -webkit-border-radius: 30px; }
渐变效果很多时候可以替代早先图片background实现的效果。 而对于IE,如果不支持的渐变的,则使用 纯色/背景图片平铺/filter 即可。(Trade-off)
-webkit-gradient(type, start_point, end_point, from, to, / stop...);
-webkit-gradient(type, inner_center, inner_radius, outer_center, outer_radius, from, to, / stop...)
type
: 渐变的类型,可以是线性渐变(linear)或是径向渐变(radial)start_point
: 渐变图像中渐变的起始点end_point
: 渐变图像中渐变的结束点stop
: color-stop()方法,指定渐变进程中特定的颜色inner_center
: 内部中心点,径向渐变起始圆环inner_radius
: 内部半径,径向渐变起始圆outer_center
: 外部渐变结束圆的中心点outer_radius
: 外部渐变结束圆的半径from
: 渐变起始点的颜色to
: 渐变结束点的颜色.bg { background: -webkit-gradient(linear, left top, left bottom, from(#00abeb), to(white), color-stop(0.5, white), color-stop(0.5, #66cc00)) } .bg2 { background: -webkit-gradient(radial, 430 50, 0, 430 50, 200, from(red), to(#000)) }
阴影效果非常的炫丽,实现效果其实也很简单。
text-shadow: color x-offset y-offset radius
-webkit-box-shadow: color x-offset y-offset radius
color
: 颜色x-offset
: 阴影横向的位移y-offset
: 阴影纵向的位移radius
: 阴影半径.sh { text-shadow: rgba(64, 64, 64, 0.498039) 0px 0px 5px; -webkit-box-shadow: rgba(0, 0, 128, 0.247059) 0px 0px 8px; }
通常实现页面的动画效果都是通过 JavaScript 的setInterval 或者 setTimeout 控制CSS值的变化来实现一个连贯的动作。 CSS3则是直接提供了这么一个非常简单的属性,省去了JavaScript的工作。
-webkit-transition: property time function delay
#box { -webkit-transition: left 2s ease; } #box.left { left: 0px; } #box.right { left: 920px; }
动画完成后,我们往往要继续进行一些操作,或者继续动画。这时就需要监测Transition的结束了。这里介绍两种方法:
方法一: setTimeout
最传统也最简单的方法应该就是这个 setTimeout
了。大家也知道这个使用的方法:
setTimeout(function() { // do something here }, 1000)
方法二:onTransitionEnd
var myDiv, transition; myDiv = document.getElementById('demo'); if('ontransitionend' in window) { transition = 'transitionend'; // Firefox } else if('onwebkittransitionend' in window) { transition = 'webkitTransitionEnd'; // Chrome/Safari (+ Mobile Safari)/Android } else if('onotransitionend' in myDiv || navigator.appName == 'Opera') { // 在Opera 10.61, DOM元素中不存在"onotransitionend" 属性, 所以转而判断appName是否为Opera transition = 'oTransitionEnd'; } else { transition = false; // 无视IE吧 } myDiv.addEventListener(transition, function(){ //alert(Date.now() + ' transition end!'); }, false);
Transform提供了强大对于既有元素变形的能力。它拥有若干函数可以操作元素。 甚至包括了一些3D方法,这里就只讲一些2D的功能。对于3D有兴趣的同学,可以私下交流~
div { transform: rotate(30deg); -ms-transform: rotate(30deg); /* IE 9 */ -webkit-transform: rotate(30deg); /* Safari and Chrome */ -o-transform: rotate(30deg); /* Opera */ -moz-transform: rotate(30deg); /* Firefox */ }
给定x,y值,挪动当前元素的位置
div { -webkit-transform: translate(50px,100px); }
给定角度,旋转当前元素
div { -webkit-transform: rotate(30deg); }
给定横轴和纵轴,放大当前元素
div { -webkit-transform: scale(2,4); }
给定X轴角度和Y轴角度,将X轴,Y轴顺时针旋转
div { -webkit-transform:skew(30deg,20deg); }
将所有的Transform方法集中到一起,含有6个参数:
(a, b, c, d, tx, ty)
matrix 涉及到矩阵运算,有兴趣的同学可以看下此文:
http://dev.opera.com/articles/view/understanding-the-css-transforms-matrix/,
当然前提是你线性代数没忘……
div { -webkit-transform:matrix(0.866,0.5,-0.5,0.866,0,0); }
transform与transition一同使用的时候,我们可以制造出许多原本在浏览器上无法实现的动画效果!
.box { -webkit-transform: rotate(10deg); -webkit-transition: -webkit-transform 2s ease-in-out; } .box:hover { -webkit-transform: rotate(-10deg); }
Animation可以说是一个大杀器了,
通过设定不同的阶段的状态,然后再设置Animation的一些属性,
则可以非常轻松的完成一系列的动画效果。
学习animation首先需要了解一下 `keyframes`。
与大部分CSS3属性一样,又是各种前缀……
@keyframes somename { /*some definition*/ } @-o-keyframes somename { /*some definition*/ } @-moz-keyframes somename { /*some definition*/ } @-webkit-keyframes somename { /*some definition*/ }
keyframes实际上是定义每个阶段的状态,有这样的一些关键词:
from, to, 0%, 25%, 100%
from
与 0%
, to
与 100%
是相同的,百分比表示动画进行到百分比的时间时的状态。
@-webkit-keyframes simple { from { background: red } to { background: yellow } } @-webkit-keyframes complex { 0% {-webkit-transform: rotate(0deg);left:0px;} 25% {-webkit-transform: rotate(20deg);left:0px;} 50% {-webkit-transform: rotate(0deg);left:800px;top:50px;} 55% {-webkit-transform: rotate(0deg);left:800px;top:50px;} 70% {-webkit-transform: rotate(0deg);left:800px;top:50px;background:#1ec7e6;} 100% {-webkit-transform: rotate(-360deg);left:0px;} }
Animation的属性需要指明它需要使用哪个keyframes, 一般来说第一个参数就是指定的那个keyframes的名称。如下:
@-webkit-keyframes simple { from { background: red } to { background: yellow } } .box { animation: simple 5s; -o-animation: simple 5s; / Opera / -moz-animation: simple 5s; / Firefox / -webkit-animation: simple 5s; / Safari and Chrome / }
Animation含有较多的属性:
所以相比于简化版的 -webkit-animation,animation的属性还可以这样更加详细的指定:
.box { -webkit-animation-name: complex; -webkit-animation-duration: 5s; -webkit-animation-timing-function: ease; -webkit-animation-delay: 2s; -webkit-animation-iteration-count: infinite; -webkit-animation-direction: alternate; -webkit-animation-play-state: running; }
与 transitionEnd 类似,可以通过setTimeout来处理,各浏览器也有对应的事件:
在前面的篇章中,
我们已经使用到了媒体查询的属性。
可以说这个是当下比较热门的技术解决方案了。
这里对此做一个基本的介绍。
Media Query的引用语法有几种,可以根据需求和代码的风格来处理:
inline
@media screen and (min-width: 1024px) { /* Some CSS for Width >= 1024 */ .desc { background: red; } }
link
<link rel="stylesheet" media="only screen and (max-device-width:360px)" href="mobile360.css" type="text/css" />
style+import
<style type="text/css" media="screen and (min-width:1440px)"> @import url("huge.css"); </style>
实际操作中,还是推荐使用前两种方法。
设备屏幕像素比
max & min
max
和 min
表示大于等于,小于等于:
如下表示当设备宽度介于 361px
和 640px
之间应用规则 mobile640.css
:
<link rel="stylesheet" media="screen and (min-device-width:361px) and (max-device-width:640px)" href="mobile640.css" type="text/css" />
and
and
用来表示同时符合多个表达式的情况。
<link rel="stylesheet" media="screen and (min-device-width:361px) and (max-device-width:640px)" href="mobile640.css" type="text/css" />
only
only
用来表明仅仅符合该Query的才引用后续的style。
一般来说,only
更多的是用来防止支持 media 属性,但不支持 Media Query的浏览器错误解析。
<link rel="stylesheet" media="only screen and (max-device-width:360px)" href="mobile360.css" type="text/css" />
not
顾名思义,not
的作用就是排除不符合表达式的设备
<link rel="stylesheet" media="not print (max-width:1024px)" href="mobile360.css" type="text/css" />
prefix- related
对于带有前缀的设备特性,涉及到的 min 和 max 关键字略有不同:
-o-min-device-pixel-ratio
-o-webkit-device-pixel-ratio
min--moz-device-pixel-ratio
CSS3 内容非常之多,这里只是涉及到一部分,有兴趣的话,大家可以私下再了解。
这里也顺便推荐两个小站点,挺有意思:
人们都认为Web应用在断网的时候就无法运行了。
但是Application Cache给出了一个否定!
可以参考这个网站:
断网的时候它照样可以打开,并且刷新页面。
只要你不清除缓存。
实际上,这不只是断网的问题,
它还从大大减少了带宽的问题,降低了服务器压力。
要激活 Application Cache,必须在 html 标签上加上一个属性 manifest
。
<html manifest="example.appcache"> ... </html>
一个最简单的 manifest
将会像这样:
CACHE MANIFEST
index.html
stylesheet.css
images/logo.png
scripts/main.js
这里有几点需要注意:
CACHE MANIFEST
是必须的,且必须在第一行unlimitedStorage
,参考那个浏览器的具体设定,比如 Chrome 仅允许 App 和 Extension 使用,通过设置 manifest.json
manifest
下载失败,浏览器将使用旧的 manifest
CACHE MANIFEST
CACHE:
/favicon.ico
index.html
stylesheet.css
images/logo.png
scripts/main.js
NETWORK: # Resources that require the user to be online.
login.php
/myapi
http://api.twitter.com
FALLBACK:
/main.py /static.html # static.html will be served if main.py is inaccessible
images/large/ images/offline.jpg # offline.jpg will be served in place of all images in images/large/
*.html /offline.html # offline.html will be served in place of all other .html files
Application Cache只有在一下情况才会更新:
manifest
文件被修改,注意,改变 manifest
文件列表中的文件并不会更新缓存,只有manifest
文件本身被修改才行var appCache = window.applicationCache; appCache.update(); // Attempt to update the user's cache. if (appCache.status == window.applicationCache.UPDATEREADY) { appCache.swapCache(); // The fetch was successful, swap in the new cache. }
Application Cache的更多的内容可以参考:
http://www.whatwg.org/specs/web-apps/current-work/#applicationcache
高山流水,笑谈前端风云