之前对于响应式都是用bootstrap等响应式框架,非常肤浅。就学习了具体的响应式开发相关内容,运用媒体查询写出不同的css布局,锻炼了基本技能,对基础概念也有了新了解。还学习了响应式图片的处理和兼容性处理,也收获良多。

1. 响应式网站

所谓响应式网站,就是一个网站能够兼容多个终端——而不是为每个终端做一个特定的版本,在各种分辨率的设备下都能很好地展示页面效果。

技术要点

flexible grid layout 弹性网格布局
flexible image 弹性图片
media queries 媒体查询

优点和缺点

一套代码适应多终端设备,省人省时省钱,利于SEO。缺点是需要加载更多的样式和脚本资源,造成代码冗余。

实践原则:

制作网站大抵都遵循两个原则:渐近增强(Progressive Enhancement)和优雅降级(Graceful Degradation),渐近增强是指先制作一个简陋但是兼容各个版本浏览器的网页,然后再添加效果。而优雅降级则刚好相反,直接制作出效果绚烂的兼容主流浏览器的产品,然后根据低版本再做出一些兼容性处理。

实现原理

使用相对单位并配合媒体查询来实现页面,我们只需要根据设计图,将绝对单位px转换为相对单位rem或者em并配合@media即可。

2. 非常规文件

humans.txt
包含了参加该网站创建人员的信息,如团队成员、感谢和站点的技术信息。 通过该文本文件,可以快速了解该网站背后的团队信息以及他们的故事。

robots.txt
允许爬虫爬取的配置
它是一个协议,而不是一个命令。robots.txt是搜索引擎中访问网站的时候要查看的第一个文件。

Use-agent: *
Disallow: /admin/

.editorconfig
用来使不同的IDE根据该文件显示相同的代码风格,便于程序员在不同IDE中维护,包括缩进格式、编码格式、换行规格。

# 配置说明
root = true 最顶层的配置文件,之后再不会查找其他文件
[*] 以下规则应用于所有文件
charset = utf-8 所有文件的编码格式为utf-8
indent_size = 4 代码缩进的空格数,可为tab
indent_style = space 代码缩进的样式,为空格
insert_final_newline = true 每个文件以空白行结尾
trim_trailing_whitespace = true 去除换行行首的空白字符
[*.md] 以下规则应用于markdown文件
trim_trailing_whitespace = false 在md文件中,不去除换行行首的空白字符

package.json
定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)。npm install命令根据这个配置文件,自动下载所需的模块,也就是配置项目所需的运行和开发环境。
gulpfile.js
gulp项目的配置文件
gitignore
告诉git版本控制工具,哪些文件不需要添加到版本管理中
LICENSE.txt
用来存放许可协议,名称为大写,包括版权声明,开源协议
CHANGLOG.md
用来存放项目每个版本的更新,以及说明版本号、更新内容、修复了哪些问题等
README.md
用来存放项目简介、使用方式、相关连接

3. IE兼容处理

IE不支持H5标签和媒体查询 (HTML5 elements and media queries)

1.基本写法

<!--[if lt/lte/gt/gte IE 9]>      // IE与版本号之间空格
    lt    <
    lte   <=
    gt    >
    gte   >=
<![endif]-->

2.用法

<!--[if lt IE9]>
<div class="browser_upgrade">您的浏览器版本太老, 为了正常使用功能请点击 <a href="http://browsehappy.com">这里</a>更新您的浏览器!!!</div>
<![endif]-->

3.Boostrap中应用

<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
    <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->

4. W3C部分标准规范

H5标签

H5规范中, 大纲outliner中, section和artical最好有标题,nav可以没有标题, 没有标题的section用div替换

<header></header>  // 头
<footer></footer>  // 尾
<nav></nav>     // 导航, 可以没有标题
<article></article> // 最好有h标题,独立完整,有内容,语义更明确, 例如博客中的文章, 帖子
<section></section>  //最好有h标题,范围广泛, 表示区块, 出现在文档大纲中, 比如广告, 联系方式, 文章中的章节等, 拿不准就用div

lang属性

HTML 的 lang 属性可用于网页或部分网页的语言。这对搜索引擎和浏览器是有帮助的。W3C标准规定,应该通过html标签中的 lang 属性对每张页面中的主要语言进行声明,同时,也规定了lang 属性在以下标签中无效:
base, br, frame, frameset, hr, iframe, param 以及 script

id,class命名规范

id 驼峰命名
class 用中横线-连接,更进一步参考 BEM(元素-块-修饰符),见css进阶,js-用于交互

meta标签

对于响应式的处理,如规定视口大小,规定以最新的IE浏览器来渲染,这些属性都用到了标签,其定义和用法如下:

元素永远位于文档的头部(head),该元素的属性定义了与文档相关联的名称/值对,可提供有关页面的元信息,添加页面关键词,有利于SEO。
其中,在XHML中,必须被正确的关闭;HTML中,没有结束标签。
标签中,必须的属性为content属性,可选的属性为http-equiv、name、scheme等。

<meta charset="utf-8" />
<title>xxx</title>
<meta name="description" content="" />
<meta name="keywords" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0, minimal-ui"  />    // minimal-ui IOS系统隐藏操作栏
<meta name="HandheldFriendly" content="true">
<meta name="MobileOptimized" content="width">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="apple-mobile-web-app-title" content="海涛旅游" />
<meta name="applicable-device" content="mobile">
<meta name="format-detection" content="telephone=no" />
<meta name="apple-itunes-app" content="app-id=914881804, app-argument=https://itunes.apple.com/cn/app/hai-tao-lu-you/id914881804?mt=8"> 
<meta name="screen-orientation" content="portrait">
<meta name="x5-orientation" content="portrait">
<meta name="full-screen" content="yes">
<meta name="x5-fullscreen" content="true">
<meta name="browsermode" content="application">
<meta name="x5-page-mode" content="app">
<meta name="msapplication-tap-highlight" content="no">

viewport视口

1.布局视口(layout viewport)
布局视口为网页PC端版式,为默认布局模式下的页面显示大小。
布局视口

2.可视视口(visual viewport)
可视视口为手机端能看见PC端网页的显示大小,根据屏幕大小不同,显示大小也会不同。
可视视口

3.理想视口(ideal viewport)
理想视口就是布局视口在一个设备上的最佳显示大小,根据屏幕大小自动修改布局视口的尺寸。

4.视口设置代码

<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"  /> 

width=device-width,指将视口宽度定义为设备宽度
minimum-scale=1.0,最小的缩放比例为1倍
maximum-scale=1.0,最大的缩放比例为1倍
user-scalable=no,禁止用户缩放

图片引入的选择

<img src="" alt="">
  1. logo类
  2. 手机中响应式图片
  3. 商品展示列表中的图片
  4. 后台动态添加的图片, 方便切换src
background:url();

装饰性的

5. PC端样式

CSS resets

  1. 让所有标签的样式看起来都一样
  2. 去除了有用的样式
    Normalize.css
  3. 保留有用的默认值,不同于许多 CSS 的重置
  4. 标准化的样式,适用范围广的元素。
  5. 纠正错误和常见的浏览器的不一致性。
  6. 一些细微的改进,提高了易用性。
  7. 使用详细的注释来解释代码。

推荐用Normalize.css
使用完整Normalize.css, 然后在main.css中覆盖, 方便后期升级

打印样式

@media print {
  *,
  *:before,
  *:after {
    background: transparent !important;
    color: #000!important;
    box-shadow: none!important;
    text-shadow: none!important;
  }
  a,
  a:visited {
    text-decoration: underline;
  }
  a[href]:after {
    content: "(" attr(href) ")";
  }
  abbr[title]:after {
    content: "(" attr(title) ")";
  }
  /*
   *使用#和javascript:;的超链接不打印
   */
  a[href^="#"]:after,
  a[href^="javascript:"]:after{
    content:"";
  }
  /* 避免内部插入分页符 */
  pre,
  blockquote {
    border:1px solid #999;
    page-break-inside: avoid; /* Opera浏览器用 */
  }
  thead {
    display: table-header-group;
  }
  tr,img {
    page-break-inside: avoid;
  }
  img {
    max-width: 100%!important;
  }
  /* 标题下文字不超过3行, 标题在下一页; 超过3行标题在当前页  */
  p,
  h2,
  h3 {
    orphans : 3; /* 当元素内部发生分页时, 页面底部保留的最小行数 */
    widows: 3;   /* 当元素内部发生分页时, 页面顶部保留的最小行数 */
  }
  /* 禁止在标题后直接插入分页符 */
  h2,
  h3 {
    page-break-after: avoid;
  }
}

BFC

块级格式化上下文, 触发BFC即可清除浮动。
https://www.jianshu.com/p/66632298e355
父元素高度塌陷的解决办法

能触发BFC的属性:

float:*;
overflow:hidden/auto;
display:table;
display:table-cell;
display:table-caption;
display:inline-block;
position:fixed;
position:absolute;

工具样式(包含清除浮动)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
.center-block {
display: block;
margin-right: auto;
margin-left: auto;
}

.pull-right {
float: right !important;
}

.pull-left {
float: left !important;
}

.text-right {
text-align: right !important;
}

.text-left {
text-align: left !important;
}

.text-center {
text-align: center !important;
}

.hide {
display: none !important;
}

.show {
display: block !important;
}

.invisible {
visibility: hidden;
}

.text-hide {
font: 0/0 a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}

/* :before是为了浏览器顶部空白崩溃,防止margin的叠加 */
.clearfix:before,
.clearfix:after {
content: " ";
display: table;
}

.clearfix:after {
clear: both;
}

/* IE6/7 */
.clearfix{
zoom:1;
}

a标签的LVHA设置

一个鼠标经过的未访问链接同时拥有a:link、a:hover两种属性,在CSS中,如果对于相同元素有针对不同条件的定义,宜将最一般的条件放在最上面,并依次向下,保证最下面的是最特殊的条件。

(LoVe/HAte)原则

a:link、a:visited、a:hover、a:active

a {
  color: #666;
  text-decoration: none;
}
a:hover, a:active {
  color: #0ae;
  text-decoration: underline;
}

chrome浏览器中文字号12px下限问题

/* 问题: 针对中文line-height:3rem (是36px而不是30px) */
html{
    font-size:62.5%;  (10px < 12px, chrome最小支持12px, 所以3rem是36px, 而不是我们想要的30px)
}
/* 解决 */
html{
    font-size:125%;  (20px)
}

inline巧用伪类换行

1
2
3
4
5
6
7
8
/* 为了清除浮动, 达到换行的效果 */
.product h2 em {
display: inline; /* 属性值为inline-block则不换行 */
}
.product h2 em:first-child:before {
content: " ";
display: table;
}

HTML中的空白符

HTML中空白符会在某些浏览器(如chrome)中导致一些小BUG,导致元素之间存在间隙。
解决办法有:删除换行符;使用float;对父元素设置font-size:0;使用CSS4中的white-space-collapsing。

6. 移动端样式

chrome调试工具选择show media queries和 show rulers

@media属性
媒介查询@media这一属性是CSS3中的属性(早在CSS2中已经出现部分属性)。其语法相当于一个判断语句,可以理解为当满足某个条件的时候,去添加括号内的样式。

@media all and(min-width:800px) and (orientation:landscape){
    ......
    //@media申明类型
    //all代表媒体类型,可为print(打印)或者是screen(屏幕显示)
    //and(逻辑操作符)
}

逻辑操作符
and:与,操作符左右都满足为真
or:或,操作符左右有一个满足为真,可用逗号替代
not:非,后跟的表达式,只对逗号或or以前的表达式有效,类似于括号 例如:@media (not(screen and(colod))),print and (color){}
only:只有,防止老旧浏览器不兼容。例如:
@media = “only screen and(min-width:401px)and (max-width:600px)等效于 @media = “only”
//only后跟的所有样式都会失效,都不会显示
@media = “screen and(min-width:401px)and (max-width:600px) 等效于 @media = “screen”
//screen后跟的所有逻辑操作符失效,都会显示该媒体查询内的样式

相对单位rem和em
em相对参照物为父元素font-size,具有继承的特点,缺点是因为依赖父元素的大小,容易混乱;
rem的相对参照物为根元素html,固定不变。
在浏览器的默认设置中,1个em或者rem 都等于16px。

如何选择媒介查询的单位

断点单位可设置px或rem或em

1. px
  根据设备宽度有功能的区分时必须用px, 
eg: 在ipad下没有购买按钮, 在iphone下有购买按钮 (功能)
2. rem (同em)
 媒体查询仅改变样式时, rem能让用户体验变得更好
3. em 兼容性更好, 其余同rem, 因为都是相对浏览器的默认字体大小16px; 

在媒体查询中,相对单位rem和em的基准高于html,所以与在html中设置的rem大小并不一致。媒体查询相对不是html的font-size, 而是浏览器的默认字体大小16px。

1rem=1em=16px。另外,rem兼容性不如em,故采用兼容性更好的em为媒体查询的断点单位。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
方案: 书写在要改变元素的下面
/* 最大屏幕的样式 */
/* px为断点单位 */
@media only screen and (max-width: 800px){
/* 中等屏幕 样式 */
}
@media only screen and (min-width: 481px) and (max-width: 800px){
/* Tablet 样式 */
}
@media only screen and (max-width: 480px){
/* mobile 样式 */
}
/* rem为断点单位,1rem = 16px (浏览器的默认设置) */
@media only screen and (max-width: 50rem { /* 800/16px=50rem */
/* 中等屏幕 样式 */
}
@media only screen and (min-width: 30.0625rem) and (max-width: 50rem){
/* Tablet 样式 */
}
@media only screen and (max-width: 30rem){
/* mobile 样式 */
}

7. css3选择器总结

css参考手册

兄弟选择器

/* css */
ul li + li {
    /* 第一个li被排除 */
}
/* html */
 <ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

属性选择器

/* 属性选择器 */
E[attr]
E[attr="value"]
E[attr*="value"]    // 包含..
/* 以下不常用 */
E[attr^="value"]    // 以..开头
E[attr$="value"]    // 以..结尾

E[attr~="value"]    // 包含..,且..是以空格隔开的
E[attr|="value"]    // 以..为属性 或 ..-开头的   
---
Eg.
a[herf^="http://"]      /* 双引号不能省 */
img[src$=".png"]
a[title~="hello"] a[title~="world"] 都可选择 <a title="hello world"></a>
div[class|="a"]   选择 <div class="a"> 或 <div class="a-**">

伪类和伪元素

1.常用   :link, :visited, :hover, :active, :focus
2.表单   :enabled, :disabled, checked
3. 
    /* p:nth-child(2) 1. p类型, 第2个索引上的 */
    :first-child, :last-child
    :nth-child(even/odd/2n+1/2n), :nth-last-child()         /* 表达式值从1开始 */
    /* p:nth-of-type(2) 1. p类型, 在该类型中的第2个 */
    :first-of-type, :last-of-type
    :nth-of-type(), :nth-last-of-type()
    :only-child      // 只有1个元素, 且元素类型为指定类型
    :only-of-type    // 可以有多个元素, 但只有一个该类型元素
    :empty     //可以有注释, 不包含文本节点(包括空格)和元素节点 (注释不算文本节点)
    :not()
    :first-line
    :first-letter
    :before
    :after
    // 在新标准中要求伪元素用::, ::before, ::after
    // 但是:before和:after在css2.0就实现了
    // 最终为了兼容性用:before和:after
    // 其余的伪元素比如::selection必须写::
    ---
    <div>
        <p></p>
        <h2></h2>
        <p></p>  /* 选中 */
        <p></p>
        <p></p>
    </div>
    /* 此时下面两种写法等价 */
    div p:nth-child(3) {}
    div p:nth-of-type(2) {}

8. 响应式图片

图片的排版和布局自适应,根据设备的大小加载不同的图片。

1. js或服务端 (命令式的实现)

(a) js中设置
根据window的resize事件改编src的路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$(function () {
function makeImageResponsive() {
var width = $(window).width();
var img = $('.content img');
if (width <= 480) {
img.attr('src', 'img/480.png');
} else if (width <= 800) {
img.attr('src', 'img/800.png');
} else {
img.attr('src', 'img/1600.png');
}
}
$(window).on('resize load', makeImageResponsive);
});
/*
原生:
window.onresize = function(){};
window.onload = function(){};
*/

(b) 服务器端设置
设备信息写入cookie, 获取图片时在服务器端返回响应图片

2. srcset和sizes (声明式的实现)

HTML Image 元素
响应式图片srcset全新释义sizes属性w描述符

-> srcset是img的特性, 支持该特性的浏览器会自动根据屏幕宽度改变
-> sizes是阈值的参照, 默认100vw(100% viewport width),而不是父级的尺寸
-> 如果浏览器中缓存过最大尺寸图片, 则任何尺寸下都用该图
-> radio放缩比为2时, 响应断点不是简单的图片宽度/放缩比, 而比该值大,浏览器的内部实现逻辑综合考虑了radio,网速,设备等因素, 所以不用理会

srcset新规范中没有w修饰符

1
2
3
4
5
<img class="image" src="img/480.png" srcset="img/480.png 480w, img/800.png 800w, img/1600.png 1600w" > <!-- 默认sizes是100vw (100% of viewport width) -->
<!-- 媒体查询大于800px时, size是800px; 其余时100% -->
<img class="image" src="img/480.png" srcset="img/480.png 480w, img/800.png 800w, img/1600.png 1600w" sizes="(min-width:800px) 800px, 100vw">
<!-- 媒体查询大于800px时, sizecal(100vw - 30px); 其余时100% -->
<img class="image" src="img/480.png" srcset="img/480.png 480w, img/800.png 800w, img/1600.png 1600w" sizes="(min-width:800px) cal(100vw - 30px), 100vw">

3. picture元素处理

HTML 元素
如何使用 HTML5 的picture元素处理响应式图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- 简单demo -->
<picture>
<source srcset="smaller.jpg" media="(max-width: 768px)">
<source srcset="default.jpg">
<img srcset="default.jpg" alt="My default image">
</picture>
<!-- 复杂demo -->
<picture>
<source srcset="smaller_landscape.jpg" media="(max-width: 40em) and (orientation: landscape)">
<source srcset="smaller_portrait.jpg" media="(max-width: 40em) and (orientation: portrait)">
<source srcset="default_landscape.jpg" media="(min-width: 40em) and (orientation: landscape)">
<source srcset="default_portrait.jpg" media="(min-width: 40em) and (orientation: portrait)">
<img srcset="default_landscape.jpg" alt="My default image">
</picture>

  1. svg(支持矢量图)
  2. polyfill
    picturefill

9. 兼容性处理

Browser hacks

Polyfill或shiv

通过旧浏览器的API来模拟新浏览器功能的兼容库

html5shiv

让IE6-9,Safari 4.x (and iPhone 3.x), and Firefox3.x.等支持html标签(header,nav,footer,section等)

1
2
3
<!--[if lt IE 9]>
<script src="bower_components/html5shiv/dist/html5shiv.js"></script>
<![endif]-->

respond.js (polyfill)

for min/max-width CSS3 Media Queries (for IE 6-8, and more)

1
2
3
4
/* 仅实现支持一下css3媒体查询功能 */ 
@media screen and (min-width: 480px) and (max-width: 800px) {
/** ... **/
}

modernizr
Modernizr.js入门教程

It tells you what HTML,CSS and JavaScript features the user’s browser has to offer.

Modernizr帮助我们检测浏览器是否实现了某个feature,如果实现了那么开发人员就可以充分利用这个feature做一些工作,反之没有实现开发人员也好提供一个fallback。所以,我们要明白的是Modernizr只是帮我们检测feature是否被支持,它并不能够给浏览器添加那些本来不支持的feature。

防御型编程, 主动检测属性的支持

CSS方面

当我们引入了Modernizr.js类库后, 标签的class属性就会被相应的赋值,以显示浏览器是否支持某类CSS属性。
以SVG举例 : 如果浏览器不支持SVG特性,那么在 标签中就会出现 no-svg 类,我们可以做一些fallback的工作;如果支持,则生成svg类。

1
2
3
4
5
6
.svg .logo{
bgackground-image:url(img/logo.svg);
}
.no-svg .logo{
bgackground-image:url(img/logo.png); /* fallback */
}

Can I use

10. 调试和打包发布以及其他

BrowserSync多设备调试

http-server

打包:压缩,合并,增加版本号。
grunt 自动化构建工具
gulp 自动化构建工具
Webpack 静态资源打包工具

产品原型设计
纸笔
axure RP
Sketch (苹果) (原型/UI/矢量图)

交互设计
flinto (Mac)
principle (Mac)

11. 文章引用来源

https://www.imooc.com/article/11729
https://ylzzxt.cn/2016/%E6%89%80%E5%90%91%E6%8A%AB%E9%9D%A1%E7%9A%84%E5%93%8D%E5%BA%94%E5%BC%8F%E5%BC%80%E5%8F%91%E5%B0%8F%E8%AE%B0/
https://www.zybuluo.com/GivenCui/note/685097