<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/rss.xsl" type="text/xsl"?>
<rss version="2.0">
  <channel>
    <title>IT瘾css推荐</title>
    <link>https://itindex.net/tags/css</link>
    <description>IT社区推荐资讯 - ITIndex.net</description>
    <language>zh</language>
    <copyright>https://itindex.net/</copyright>
    <generator>https://itindex.net/</generator>
    <docs>http://backend.userland.com/rss</docs>
    <image>
      <url>https://itindex.net/images/logo.gif</url>
      <title>IT社区推荐资讯 - ITIndex.net</title>
      <link>https://itindex.net/tags/css</link>
    </image>
    <item>
      <title>如何优雅的实现网页多主题风格换肤功能？</title>
      <link>https://itindex.net/detail/62655-%E7%BD%91%E9%A1%B5-%E5%8A%9F%E8%83%BD</link>
      <description>&lt;p&gt;  &lt;strong&gt;海阔凭鱼跃，天高任鸟飞。好久不见！我是猫力Molly&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;对于网页换肤，例如最常见的深色、浅色风格已经是很常见的一个需求了。一直以来也有很多的实现方案，这里我主要介绍一下基于   &lt;code&gt;CSS variable&lt;/code&gt;的实现方式&lt;/p&gt; &lt;h2&gt;简单列举下一些其它实现方式&lt;/h2&gt; &lt;p&gt;  &lt;strong&gt;1、把不同风格样式写到不同的类名下面，通过切换类名来实现换肤&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;这种方式没啥明显的优点，只是单纯的实现了此需求。反而增加了css样式文件代码冗余且会造成大量重复代码，样式代码不利于拓展维护，且开发效率低下&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;2、实现多套主题样式文件，通过 link 标签动态加载不同的样式文件&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;这种方式的优点大概是做到了按需加载吧，但同时也造成了需要拷贝大量重复代码来单独修改，也算是做到了样式隔离，相比上一种方式稍稍提高了一点可维护性吧&lt;/p&gt; &lt;p&gt;在多个样式文件切换的时候，可能会有加载延迟。这时候可以考虑使用   &lt;code&gt;alternate&lt;/code&gt; 来解决&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;3、通过less或sass的变量方式实现&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;这种方式我们可以将所有风格变量抽离出来，在样式代码中直接使用该变量，是一种比较推荐的方式。极大提高了代码的拓展性和维护性&lt;/p&gt; &lt;h2&gt;CSS variable的实现方式&lt;/h2&gt; &lt;p&gt;  &lt;img alt="image.png" src="https://segmentfault.com/img/remote/1460000043451608" title="image.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;如图所示，目前主流浏览器都已经支持  &lt;code&gt;css variable&lt;/code&gt;，我们尽管放心使用&lt;/p&gt; &lt;p&gt;  &lt;code&gt;CSS variable&lt;/code&gt; 允许我们在 css 里面声明变量，在变量前加上两根小横线即可（--）&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;body {
  --foo: #000;
  --bar: #fff;
}&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;需要注意的是  &lt;code&gt;css vars&lt;/code&gt;变量声明，区分大小写  &lt;code&gt;--foo&lt;/code&gt; 与   &lt;code&gt;--Foo&lt;/code&gt; 是两个不同的变量&lt;/p&gt; &lt;h3&gt;var() 函数&lt;/h3&gt; &lt;p&gt;使用var()函数来读取变量&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;p{
    color:var(--foo)
}&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;  &lt;code&gt;var()&lt;/code&gt;函数支持第二个参数，用于表示变量的默认值，如果变量值不存在，则以默认值为准&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;p{
    color:var(--fooo, #ccc)
}&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;关于  &lt;code&gt;var()&lt;/code&gt;函数此处不做过多赘述，详情请查阅  &lt;a href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/var" rel="nofollow noreferrer"&gt;官方文档&lt;/a&gt;&lt;/p&gt; &lt;h2&gt;方案落地&lt;/h2&gt; &lt;p&gt;大致思路：不管深色或是浅色风格，我们都可以把它视作一个个主题。把每个主题的颜色值、盒子宽高、图片地址等抽离为一个字典对象结构。一个主题对应一个配置文件，再通过切换配置文件来实现主题风格的变化&lt;/p&gt; &lt;h3&gt;一、和UI设计师沟通好各主题的色阶&lt;/h3&gt; &lt;p&gt;一个主题对应一份配置文件，所以我们需要提前和UI设计师沟通好各主题对应的色阶，字号，一些通用样式规则等&lt;/p&gt; &lt;p&gt;  &lt;img alt="image.png" src="https://segmentfault.com/img/remote/1460000043451609" title="image.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;  &lt;img alt="image.png" src="https://segmentfault.com/img/remote/1460000043451610" title="image.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;  &lt;code&gt;css vars&lt;/code&gt;变量名称是不变的，变量值随着主题的切换而发生改变&lt;/p&gt; &lt;p&gt;我的UI同事使用的是 figma，然后我发现 figma 右侧的信息栏里面有颜色编号，正好可以使用这个来当做变量名称。在编码阶段，看到这个编号，就知道用什么变量名了，非常方便。&lt;/p&gt; &lt;p&gt;如果你的UI同事使用的是别的设计工具，最好也是提前约定好变量名，使其大家都方便&lt;/p&gt; &lt;p&gt;  &lt;img alt="image.png" src="https://segmentfault.com/img/remote/1460000043451611" title="image.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;h3&gt;二、将各主题色阶抽离为一个字典对象&lt;/h3&gt; &lt;p&gt;dark.js&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;export default {
  &amp;apos;--grey900&amp;apos;: &amp;apos;#EBEEF5&amp;apos;,
  &amp;apos;--grey600&amp;apos;: &amp;apos;#A7ABC0&amp;apos;,
  &amp;apos;--grey500&amp;apos;: &amp;apos;#72768D&amp;apos;,
  &amp;apos;--grey400&amp;apos;: &amp;apos;#5D6177&amp;apos;,
  &amp;apos;--grey300&amp;apos;: &amp;apos;#404759&amp;apos;,
  &amp;apos;--grey200&amp;apos;: &amp;apos;#2C323E&amp;apos;,
  &amp;apos;--grey100&amp;apos;: &amp;apos;#282B32&amp;apos;,
  &amp;apos;--grey50&amp;apos;: &amp;apos;#171B22&amp;apos;,
  &amp;apos;--grey0&amp;apos;: &amp;apos;#222730&amp;apos;,
  ...
}  &lt;/code&gt;&lt;/pre&gt; &lt;p&gt;white.js&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;export default {
  &amp;apos;--grey900&amp;apos;: &amp;apos;#1F2429&amp;apos;,
  &amp;apos;--grey600&amp;apos;: &amp;apos;#646C73&amp;apos;,
  &amp;apos;--grey500&amp;apos;: &amp;apos;#8D9399&amp;apos;,
  &amp;apos;--grey400&amp;apos;: &amp;apos;#C3C7CB&amp;apos;,
  &amp;apos;--grey300&amp;apos;: &amp;apos;#E4E6E7&amp;apos;,
  &amp;apos;--grey200&amp;apos;: &amp;apos;#EFF0F1&amp;apos;,
  &amp;apos;--grey100&amp;apos;: &amp;apos;#F4F5F6&amp;apos;,
  &amp;apos;--grey50&amp;apos;: &amp;apos;#F8F9FA&amp;apos;,
  &amp;apos;--grey0&amp;apos;: &amp;apos;#FFFFFF&amp;apos;,
  ...
}  &lt;/code&gt;&lt;/pre&gt; &lt;h3&gt;三、通过js设置style变量&lt;/h3&gt; &lt;p&gt;这里我们需要用到   &lt;code&gt;document.body.style&lt;/code&gt; 的api&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;// 设置变量
document.body.style.setProperty(&amp;apos;--foo&amp;apos;, &amp;apos;#666&amp;apos;)

// 读取变量
document.body.style.getPropertyValue(&amp;apos;--foo&amp;apos;)

// 删除变量
document.body.style.removeProperty(&amp;apos;--foo&amp;apos;)&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;遍历变量字典对象，根据不同主题，给网页设置对应变量&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;import C from &amp;apos;@/utils/cssVarMap&amp;apos;

setCssVar (flag) {
  const varList = Object.entries(flag ? C.white : C.dark)
  varList.forEach(([key, val]) =&amp;gt; {
    document.body.style.setProperty(key, val)
  })
}&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;至此，我们已经完成根据不同主题设置不同主题变量了，可以愉快的在样式文件里面使用  &lt;code&gt;css vars&lt;/code&gt;&lt;/p&gt; &lt;p&gt;  &lt;img alt="image.png" src="https://segmentfault.com/img/remote/1460000043451612" title="image.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;这种方式操作简单，且极大的提高了代码的拓展性和维护性。之后再有别的主题，也不过是多增加一份配置文件而已，不会增加额外的副作用。&lt;/p&gt; &lt;h3&gt;举一反三&lt;/h3&gt; &lt;h4&gt;1、结合媒体查询&lt;/h4&gt; &lt;p&gt;通过结合媒体查询，我们可以实现更复杂的交互场景&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;body {
  --foo: #fff
}

p {
    color: var(--foo)
}

@media screen and (min-width: 768px) {
  body {
    --foo: #000
  }
}&lt;/code&gt;&lt;/pre&gt; &lt;h4&gt;2、结合js业务逻辑&lt;/h4&gt; &lt;p&gt;在一些特殊需求场景下，我们可以结合js业务逻辑，动态追加或编辑   &lt;code&gt;css vars&lt;/code&gt;&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;const docStyle = document.documentElement.style;

document.addEventListener(&amp;apos;mousemove&amp;apos;, (e) =&amp;gt; {
  docStyle.setProperty(&amp;apos;--foo&amp;apos;, e.clientX);
});&lt;/code&gt;&lt;/pre&gt; &lt;h4&gt;3、存储一些信息&lt;/h4&gt; &lt;p&gt;既然是声明变量，那么就有存储信息的功能。我们可以试着将一些信息存储在   &lt;code&gt;css vars&lt;/code&gt; 里面，再通过  &lt;code&gt;document.body.style.getPropertyValue(&amp;apos;--foo&amp;apos;)&lt;/code&gt;去读取使用。不过大部分场景应该使用不到这种方法，也算是提供一种思路吧。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;css vars&lt;/strong&gt;是个潜力股，一起来挖掘它更多巧妙的用法吧&lt;/p&gt; &lt;h2&gt;感谢&lt;/h2&gt; &lt;p&gt;欢迎关注我的个人公众号  &lt;a href="https://getapi.run/recommend/yy/1.jpg" rel="nofollow noreferrer"&gt;前端有猫腻&lt;/a&gt;每天给你推送新鲜的优质好文。回复 “福利” 即可获得我精心准备的前端知识大礼包。愿你一路前行，眼里有光！&lt;/p&gt; &lt;p&gt;感兴趣的小伙伴还可以加我  &lt;a href="http://tool.edian.xyz" rel="nofollow noreferrer"&gt;微信：猫力molly&lt;/a&gt;或  &lt;a href="http://tool.edian.xyz" rel="nofollow noreferrer"&gt;前端交流群&lt;/a&gt;和众多优秀的前端攻城狮一起交流技术，一起玩耍！&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>javascript css html react.js vue.js</category>
      <guid isPermaLink="true">https://itindex.net/detail/62655-%E7%BD%91%E9%A1%B5-%E5%8A%9F%E8%83%BD</guid>
      <pubDate>Wed, 22 Feb 2023 10:00:00 CST</pubDate>
    </item>
    <item>
      <title>写给中高级前端关于性能优化的9大策略和6大指标 | 网易四年实践</title>
      <link>https://itindex.net/detail/61610-%E5%89%8D%E7%AB%AF-%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96-%E7%AD%96%E7%95%A5</link>
      <description>&lt;h3&gt;前言&lt;/h3&gt; &lt;p&gt;笔者近半年一直在参与项目重构，在重构过程中大量应用  &lt;strong&gt;性能优化&lt;/strong&gt;和  &lt;strong&gt;设计模式&lt;/strong&gt;两方面的知识。  &lt;strong&gt;性能优化&lt;/strong&gt;和  &lt;strong&gt;设计模式&lt;/strong&gt;两方面的知识不管在工作还是面试时都是高频应用场景，趁着这次参与大规模项目重构的机会，笔者认真梳理出一些常规且必用的  &lt;code&gt;性能优化建议&lt;/code&gt;，同时结合日常开发经验整理出笔者在网易四年来实践到的认为有用的所有  &lt;code&gt;性能优化建议&lt;/code&gt;，与大家一起分享分享！(由于篇幅有限，那  &lt;code&gt;设计模式&lt;/code&gt;在后面再专门出一篇文章呗)&lt;/p&gt; &lt;p&gt;可能有些  &lt;code&gt;性能优化建议&lt;/code&gt;已被大家熟知，不过也不影响这次分享，当然笔者也将一些平时可能不会注意的细节罗列出来。&lt;/p&gt; &lt;p&gt;平时大家认为  &lt;code&gt;性能优化&lt;/code&gt;是一种无序的应用场景，但在笔者看来它是一种有序的应用场景且很多  &lt;code&gt;性能优化&lt;/code&gt;都是互相铺垫甚至一带一路。从过程趋势来看，  &lt;code&gt;性能优化&lt;/code&gt;可分为  &lt;strong&gt;网络层面&lt;/strong&gt;和  &lt;strong&gt;渲染层面&lt;/strong&gt;；从结果趋势来看，  &lt;code&gt;性能优化&lt;/code&gt;可分为  &lt;strong&gt;时间层面&lt;/strong&gt;和  &lt;strong&gt;体积层面&lt;/strong&gt;。简单来说就是  &lt;code&gt;要在访问网站时使其快准狠地立马呈现在用户眼前&lt;/code&gt;。&lt;/p&gt; &lt;p&gt;  &lt;img alt="&amp;#24615;&amp;#33021;&amp;#20248;&amp;#21270;.png" src="https://segmentfault.com/img/remote/1460000040343059" title="&amp;#24615;&amp;#33021;&amp;#20248;&amp;#21270;.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;所有的  &lt;code&gt;性能优化&lt;/code&gt;都围绕着  &lt;code&gt;两大层面两小层面&lt;/code&gt;实现，核心层面是  &lt;code&gt;网络层面&lt;/code&gt;和  &lt;code&gt;渲染层面&lt;/code&gt;，辅助层面是  &lt;code&gt;时间层面&lt;/code&gt;和  &lt;code&gt;体积层面&lt;/code&gt;，而辅助层面则充满在核心层面里。于是笔者通过本文整理出关于前端  &lt;code&gt;性能优化&lt;/code&gt;的  &lt;strong&gt;九大策略&lt;/strong&gt;和  &lt;strong&gt;六大指标&lt;/strong&gt;。当然这些  &lt;code&gt;策略&lt;/code&gt;和  &lt;code&gt;指标&lt;/code&gt;都是笔者自己定义，方便通过某种方式为性能优化做一些规范。&lt;/p&gt; &lt;p&gt;因此在工作或面试时结合这些特征就能完美地诠释  &lt;code&gt;性能优化&lt;/code&gt;所延伸出来的知识了。  &lt;strong&gt;前方高能，不看也得收藏，走起！！！&lt;/strong&gt;&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;所有代码示例为了凸显主题，只展示核心配置代码，其他配置并未补上，请自行脑补&lt;/code&gt;&lt;/pre&gt; &lt;h3&gt;九大策略&lt;/h3&gt; &lt;h4&gt;网络层面&lt;/h4&gt; &lt;p&gt;  &lt;strong&gt;网络层面&lt;/strong&gt;的性能优化，无疑是如何让资源  &lt;code&gt;体积更小加载更快&lt;/code&gt;，因此笔者从以下四方面做出建议。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;strong&gt;构建策略&lt;/strong&gt;：基于构建工具(   &lt;code&gt;Webpack/Rollup/Parcel/Esbuild/Vite/Gulp&lt;/code&gt;)&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;图像策略&lt;/strong&gt;：基于图像类型(   &lt;code&gt;JPG/PNG/SVG/WebP/Base64&lt;/code&gt;)&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;分发策略&lt;/strong&gt;：基于内容分发网络(   &lt;code&gt;CDN&lt;/code&gt;)&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;缓存策略&lt;/strong&gt;：基于浏览器缓存(   &lt;code&gt;强缓存/协商缓存&lt;/code&gt;)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;上述四方面都是一步接着一步完成，充满在整个项目流程里。  &lt;strong&gt;构建策略&lt;/strong&gt;和  &lt;strong&gt;图像策略&lt;/strong&gt;处于开发阶段，  &lt;strong&gt;分发策略&lt;/strong&gt;和  &lt;strong&gt;缓存策略&lt;/strong&gt;处于生产阶段，因此在每个阶段都可检查是否按顺序接入上述策略。通过这种方式就能最大限度增加  &lt;code&gt;性能优化&lt;/code&gt;应用场景。&lt;/p&gt; &lt;h5&gt;构建策略&lt;/h5&gt; &lt;p&gt;该策略主要围绕  &lt;code&gt;webpack&lt;/code&gt;做相关处理，同时也是接入最普遍的  &lt;code&gt;性能优化策略&lt;/code&gt;。其他构建工具的处理也是大同小异，可能只是配置上不一致。说到  &lt;code&gt;webpack&lt;/code&gt;的  &lt;code&gt;性能优化&lt;/code&gt;，无疑是从  &lt;code&gt;时间层面&lt;/code&gt;和  &lt;code&gt;体积层面&lt;/code&gt;入手。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;笔者发现目前webpack v5整体兼容性还不是特别好，某些功能配合第三方工具可能出现问题，故暂未升级到v5，继续使用v4作为生产工具，故以下配置均基于v4，但总体与v5的配置出入不大&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;笔者对两层面分别做出6个  &lt;code&gt;性能优化建议&lt;/code&gt;总共12个  &lt;code&gt;性能优化建议&lt;/code&gt;，为了方便记忆均使用四字词语概括，方便大家消化。⏱表示  &lt;code&gt;减少打包时间&lt;/code&gt;，表示  &lt;code&gt;减少打包体积&lt;/code&gt;。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;strong&gt;减少打包时间&lt;/strong&gt;：   &lt;code&gt;缩减范围&lt;/code&gt;、   &lt;code&gt;缓存副本&lt;/code&gt;、   &lt;code&gt;定向搜索&lt;/code&gt;、   &lt;code&gt;提前构建&lt;/code&gt;、   &lt;code&gt;并行构建&lt;/code&gt;、   &lt;code&gt;可视结构&lt;/code&gt;&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;减少打包体积&lt;/strong&gt;：   &lt;code&gt;分割代码&lt;/code&gt;、   &lt;code&gt;摇树优化&lt;/code&gt;、   &lt;code&gt;动态垫片&lt;/code&gt;、   &lt;code&gt;按需加载&lt;/code&gt;、   &lt;code&gt;作用提升&lt;/code&gt;、   &lt;code&gt;压缩资源&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt; &lt;blockquote&gt;⏱缩减范围&lt;/blockquote&gt; &lt;p&gt;  &lt;strong&gt;配置include/exclude缩小Loader对文件的搜索范围&lt;/strong&gt;，好处是  &lt;code&gt;避免不必要的转译&lt;/code&gt;。  &lt;code&gt;node_modules目录&lt;/code&gt;的体积这么大，那得增加多少时间成本去检索所有文件啊？&lt;/p&gt; &lt;p&gt;  &lt;code&gt;include/exclude&lt;/code&gt;通常在各大  &lt;code&gt;Loader&lt;/code&gt;里配置，  &lt;code&gt;src目录&lt;/code&gt;通常作为源码目录，可做如下处理。当然  &lt;code&gt;include/exclude&lt;/code&gt;可根据实际情况修改。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;export default {
    // ...
    module: {
        rules: [{
            exclude: /node_modules/,
            include: /src/,
            test: /\.js$/,
            use: &amp;quot;babel-loader&amp;quot;
        }]
    }
};&lt;/code&gt;&lt;/pre&gt; &lt;blockquote&gt;⏱缓存副本&lt;/blockquote&gt; &lt;p&gt;  &lt;strong&gt;配置cache缓存Loader对文件的编译副本&lt;/strong&gt;，好处是  &lt;code&gt;再次编译时只编译修改过的文件&lt;/code&gt;。未修改过的文件干嘛要随着修改过的文件重新编译呢？&lt;/p&gt; &lt;p&gt;大部分  &lt;code&gt;Loader/Plugin&lt;/code&gt;都会提供一个可使用编译缓存的选项，通常包含  &lt;code&gt;cache&lt;/code&gt;字眼。以  &lt;code&gt;babel-loader&lt;/code&gt;和  &lt;code&gt;eslint-webpack-plugin&lt;/code&gt;为例。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;import EslintPlugin from &amp;quot;eslint-webpack-plugin&amp;quot;;

export default {
    // ...
    module: {
        rules: [{
            // ...
            test: /\.js$/,
            use: [{
                loader: &amp;quot;babel-loader&amp;quot;,
                options: { cacheDirectory: true }
            }]
        }]
    },
    plugins: [
        new EslintPlugin({ cache: true })
    ]
};&lt;/code&gt;&lt;/pre&gt; &lt;blockquote&gt;⏱定向搜索&lt;/blockquote&gt; &lt;p&gt;  &lt;strong&gt;配置resolve提高文件的搜索速度&lt;/strong&gt;，好处是  &lt;code&gt;定向指定必须文件路径&lt;/code&gt;。若某些第三方库以常规形式引入可能报错或希望程序自动索引特定类型文件都可通过该方式解决。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;alias&lt;/code&gt;映射模块路径，  &lt;code&gt;extensions&lt;/code&gt;表明文件后缀，  &lt;code&gt;noParse&lt;/code&gt;过滤无依赖文件。通常配置  &lt;code&gt;alias&lt;/code&gt;和  &lt;code&gt;extensions&lt;/code&gt;就足够。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;export default {
    // ...
    resolve: {
        alias: {
            &amp;quot;#&amp;quot;: AbsPath(&amp;quot;&amp;quot;), // 根目录快捷方式
            &amp;quot;@&amp;quot;: AbsPath(&amp;quot;src&amp;quot;), // src目录快捷方式
            swiper: &amp;quot;swiper/js/swiper.min.js&amp;quot;
        }, // 模块导入快捷方式
        extensions: [&amp;quot;.js&amp;quot;, &amp;quot;.ts&amp;quot;, &amp;quot;.jsx&amp;quot;, &amp;quot;.tsx&amp;quot;, &amp;quot;.json&amp;quot;, &amp;quot;.vue&amp;quot;] // import路径时文件可省略后缀名
    }
};&lt;/code&gt;&lt;/pre&gt; &lt;blockquote&gt;⏱提前构建&lt;/blockquote&gt; &lt;p&gt;  &lt;strong&gt;配置DllPlugin将第三方依赖提前打包&lt;/strong&gt;，好处是  &lt;code&gt;将DLL与业务代码完全分离且每次只构建业务代码&lt;/code&gt;。这是一个古老配置，在  &lt;code&gt;webpack v2&lt;/code&gt;时已存在，不过现在  &lt;code&gt;webpack v4+&lt;/code&gt;已不推荐使用该配置，因为其版本迭代带来的性能提升足以忽略  &lt;code&gt;DllPlugin&lt;/code&gt;所带来的效益。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;DLL&lt;/strong&gt;意为  &lt;code&gt;动态链接库&lt;/code&gt;，指一个包含可由多个程序同时使用的代码库。在前端领域里可认为是另类缓存的存在，它把公共代码打包为DLL文件并存到硬盘里，再次打包时动态链接  &lt;code&gt;DLL文件&lt;/code&gt;就无需再次打包那些公共代码，从而提升构建速度，减少打包时间。&lt;/p&gt; &lt;p&gt;配置  &lt;code&gt;DLL&lt;/code&gt;总体来说相比其他配置复杂，配置流程可大致分为三步。&lt;/p&gt; &lt;p&gt;首先告知构建脚本哪些依赖做成  &lt;code&gt;DLL&lt;/code&gt;并生成  &lt;code&gt;DLL文件&lt;/code&gt;和  &lt;code&gt;DLL映射表文件&lt;/code&gt;。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;import { DefinePlugin, DllPlugin } from &amp;quot;webpack&amp;quot;;

export default {
    // ...
    entry: {
        vendor: [&amp;quot;react&amp;quot;, &amp;quot;react-dom&amp;quot;, &amp;quot;react-router-dom&amp;quot;]
    },
    mode: &amp;quot;production&amp;quot;,
    optimization: {
        splitChunks: {
            cacheGroups: {
                vendor: {
                    chunks: &amp;quot;all&amp;quot;,
                    name: &amp;quot;vendor&amp;quot;,
                    test: /node_modules/
                }
            }
        }
    },
    output: {
        filename: &amp;quot;[name].dll.js&amp;quot;, // 输出路径和文件名称
        library: &amp;quot;[name]&amp;quot;, // 全局变量名称：其他模块会从此变量上获取里面模块
        path: AbsPath(&amp;quot;dist/static&amp;quot;) // 输出目录路径
    },
    plugins: [
        new DefinePlugin({
            &amp;quot;process.env.NODE_ENV&amp;quot;: JSON.stringify(&amp;quot;development&amp;quot;) // DLL模式下覆盖生产环境成开发环境(启动第三方依赖调试模式)
        }),
        new DllPlugin({
            name: &amp;quot;[name]&amp;quot;, // 全局变量名称：减小搜索范围，与output.library结合使用
            path: AbsPath(&amp;quot;dist/static/[name]-manifest.json&amp;quot;) // 输出目录路径
        })
    ]
};&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;然后在  &lt;code&gt;package.json&lt;/code&gt;里配置执行脚本且每次构建前首先执行该脚本打包出  &lt;code&gt;DLL文件&lt;/code&gt;。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;{
    &amp;quot;scripts&amp;quot;: {
        &amp;quot;dll&amp;quot;: &amp;quot;webpack --config webpack.dll.js&amp;quot;
    }
}&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;最后链接  &lt;code&gt;DLL文件&lt;/code&gt;并告知  &lt;code&gt;webpack&lt;/code&gt;可命中的  &lt;code&gt;DLL文件&lt;/code&gt;让其自行读取。使用  &lt;a href="https://github.com/jharris4/html-webpack-tags-plugin" rel="nofollow noreferrer"&gt;html-webpack-tags-plugin&lt;/a&gt;在打包时自动插入  &lt;code&gt;DLL文件&lt;/code&gt;。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;import { DllReferencePlugin } from &amp;quot;webpack&amp;quot;;
import HtmlTagsPlugin from &amp;quot;html-webpack-tags-plugin&amp;quot;;

export default {
    // ...
    plugins: [
        // ...
        new DllReferencePlugin({
            manifest: AbsPath(&amp;quot;dist/static/vendor-manifest.json&amp;quot;) // manifest文件路径
        }),
        new HtmlTagsPlugin({
            append: false, // 在生成资源后插入
            publicPath: &amp;quot;/&amp;quot;, // 使用公共路径
            tags: [&amp;quot;static/vendor.dll.js&amp;quot;] // 资源路径
        })
    ]
};&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;为了那几秒钟的时间成本，笔者建议配置上较好。当然也可使用  &lt;a href="https://github.com/asfktz/autodll-webpack-plugin" rel="nofollow noreferrer"&gt;autodll-webpack-plugin&lt;/a&gt;代替手动配置。&lt;/p&gt; &lt;blockquote&gt;⏱并行构建&lt;/blockquote&gt; &lt;p&gt;  &lt;strong&gt;配置Thread将Loader单进程转换为多进程&lt;/strong&gt;，好处是  &lt;code&gt;释放CPU多核并发的优势&lt;/code&gt;。在使用  &lt;code&gt;webpack&lt;/code&gt;构建项目时会有大量文件需解析和处理，构建过程是计算密集型的操作，随着文件增多会使构建过程变得越慢。&lt;/p&gt; &lt;p&gt;运行在  &lt;code&gt;Node&lt;/code&gt;里的  &lt;code&gt;webpack&lt;/code&gt;是单线程模型，简单来说就是  &lt;code&gt;webpack&lt;/code&gt;待处理的任务需一件件处理，不能同一时刻处理多件任务。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;文件读写&lt;/code&gt;与  &lt;code&gt;计算操作&lt;/code&gt;无法避免，能不能让  &lt;code&gt;webpack&lt;/code&gt;同一时刻处理多个任务，发挥多核  &lt;code&gt;CPU&lt;/code&gt;电脑的威力以提升构建速度呢？  &lt;a href="https://github.com/webpack-contrib/thread-loader" rel="nofollow noreferrer"&gt;thread-loader&lt;/a&gt;来帮你，根据  &lt;code&gt;CPU&lt;/code&gt;个数开启线程。&lt;/p&gt; &lt;p&gt;在此需注意一个问题，若项目文件不算多就不要使用该  &lt;code&gt;性能优化建议&lt;/code&gt;，毕竟开启多个线程也会存在性能开销。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;import Os from &amp;quot;os&amp;quot;;

export default {
    // ...
    module: {
        rules: [{
            // ...
            test: /\.js$/,
            use: [{
                loader: &amp;quot;thread-loader&amp;quot;,
                options: { workers: Os.cpus().length }
            }, {
                loader: &amp;quot;babel-loader&amp;quot;,
                options: { cacheDirectory: true }
            }]
        }]
    }
};&lt;/code&gt;&lt;/pre&gt; &lt;blockquote&gt;⏱可视结构&lt;/blockquote&gt; &lt;p&gt;  &lt;strong&gt;配置BundleAnalyzer分析打包文件结构&lt;/strong&gt;，好处是  &lt;code&gt;找出导致体积过大的原因&lt;/code&gt;。从而通过分析原因得出优化方案减少构建时间。  &lt;code&gt;BundleAnalyzer&lt;/code&gt;是  &lt;code&gt;webpack&lt;/code&gt;官方插件，可直观分析  &lt;code&gt;打包文件&lt;/code&gt;的模块组成部分、模块体积占比、模块包含关系、模块依赖关系、文件是否重复、压缩体积对比等可视化数据。&lt;/p&gt; &lt;p&gt;可使用  &lt;a href="https://github.com/webpack-contrib/webpack-bundle-analyzer" rel="nofollow noreferrer"&gt;webpack-bundle-analyzer&lt;/a&gt;配置，有了它，我们就能快速找到相关问题。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;import { BundleAnalyzerPlugin } from &amp;quot;webpack-bundle-analyzer&amp;quot;;

export default {
    // ...
    plugins: [
        // ...
        BundleAnalyzerPlugin()
    ]
};&lt;/code&gt;&lt;/pre&gt; &lt;blockquote&gt;分割代码&lt;/blockquote&gt; &lt;p&gt;  &lt;strong&gt;分割各个模块代码，提取相同部分代码&lt;/strong&gt;，好处是  &lt;code&gt;减少重复代码的出现频率&lt;/code&gt;。  &lt;code&gt;webpack v4&lt;/code&gt;使用  &lt;code&gt;splitChunks&lt;/code&gt;替代  &lt;code&gt;CommonsChunksPlugin&lt;/code&gt;实现代码分割。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;splitChunks&lt;/code&gt;配置较多，详情可参考  &lt;a href="https://webpack.docschina.org/configuration/optimization/#optimizationsplitchunks" rel="nofollow noreferrer"&gt;官网&lt;/a&gt;，在此笔者贴上常用配置。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;export default {
    // ...
    optimization: {
        runtimeChunk: { name: &amp;quot;manifest&amp;quot; }, // 抽离WebpackRuntime函数
        splitChunks: {
            cacheGroups: {
                common: {
                    minChunks: 2,
                    name: &amp;quot;common&amp;quot;,
                    priority: 5,
                    reuseExistingChunk: true, // 重用已存在代码块
                    test: AbsPath(&amp;quot;src&amp;quot;)
                },
                vendor: {
                    chunks: &amp;quot;initial&amp;quot;, // 代码分割类型
                    name: &amp;quot;vendor&amp;quot;, // 代码块名称
                    priority: 10, // 优先级
                    test: /node_modules/ // 校验文件正则表达式
                }
            }, // 缓存组
            chunks: &amp;quot;all&amp;quot; // 代码分割类型：all全部模块，async异步模块，initial入口模块
        } // 代码块分割
    }
};&lt;/code&gt;&lt;/pre&gt; &lt;blockquote&gt;摇树优化&lt;/blockquote&gt; &lt;p&gt;  &lt;strong&gt;删除项目中未被引用代码&lt;/strong&gt;，好处是  &lt;code&gt;移除重复代码和未使用代码&lt;/code&gt;。  &lt;code&gt;摇树优化&lt;/code&gt;首次出现于  &lt;code&gt;rollup&lt;/code&gt;，是  &lt;code&gt;rollup&lt;/code&gt;的核心概念，后来在  &lt;code&gt;webpack v2&lt;/code&gt;里借鉴过来使用。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;摇树优化&lt;/code&gt;只对  &lt;code&gt;ESM规范&lt;/code&gt;生效，对其他模块规范失效。  &lt;code&gt;摇树优化&lt;/code&gt;针对静态结构分析，只有  &lt;code&gt;import/export&lt;/code&gt;才能提供静态的  &lt;code&gt;导入/导出&lt;/code&gt;功能。因此在编写业务代码时必须使用  &lt;code&gt;ESM规范&lt;/code&gt;才能让  &lt;code&gt;摇树优化&lt;/code&gt;移除重复代码和未使用代码。&lt;/p&gt; &lt;p&gt;在  &lt;code&gt;webpack&lt;/code&gt;里只需将打包环境设置成  &lt;code&gt;生产环境&lt;/code&gt;就能让  &lt;code&gt;摇树优化&lt;/code&gt;生效，同时业务代码使用  &lt;code&gt;ESM规范&lt;/code&gt;编写，使用  &lt;code&gt;import&lt;/code&gt;导入模块，使用  &lt;code&gt;export&lt;/code&gt;导出模块。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;export default {
    // ...
    mode: &amp;quot;production&amp;quot;
};&lt;/code&gt;&lt;/pre&gt; &lt;blockquote&gt;动态垫片&lt;/blockquote&gt; &lt;p&gt;  &lt;strong&gt;通过垫片服务根据UA返回当前浏览器代码垫片&lt;/strong&gt;，好处是  &lt;code&gt;无需将繁重的代码垫片打包进去&lt;/code&gt;。每次构建都配置  &lt;code&gt;@babel/preset-env&lt;/code&gt;和  &lt;code&gt;core-js&lt;/code&gt;根据某些需求将  &lt;code&gt;Polyfill&lt;/code&gt;打包进来，这无疑又为代码体积增加了贡献。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;@babel/preset-env&lt;/code&gt;提供的  &lt;code&gt;useBuiltIns&lt;/code&gt;可按需导入  &lt;code&gt;Polyfill&lt;/code&gt;。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;strong&gt;false&lt;/strong&gt;：无视   &lt;code&gt;target.browsers&lt;/code&gt;将所有   &lt;code&gt;Polyfill&lt;/code&gt;加载进来&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;entry&lt;/strong&gt;：根据   &lt;code&gt;target.browsers&lt;/code&gt;将部分   &lt;code&gt;Polyfill&lt;/code&gt;加载进来(仅引入有浏览器不支持的   &lt;code&gt;Polyfill&lt;/code&gt;，需在入口文件   &lt;code&gt;import &amp;quot;core-js/stable&amp;quot;&lt;/code&gt;)&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;usage&lt;/strong&gt;：根据   &lt;code&gt;target.browsers&lt;/code&gt;和检测代码里ES6的使用情况将部分   &lt;code&gt;Polyfill&lt;/code&gt;加载进来(无需在入口文件   &lt;code&gt;import &amp;quot;core-js/stable&amp;quot;&lt;/code&gt;)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;在此推荐大家使用  &lt;code&gt;动态垫片&lt;/code&gt;。  &lt;code&gt;动态垫片&lt;/code&gt;可根据浏览器  &lt;code&gt;UserAgent&lt;/code&gt;返回当前浏览器  &lt;code&gt;Polyfill&lt;/code&gt;，其思路是根据浏览器的  &lt;code&gt;UserAgent&lt;/code&gt;从  &lt;code&gt;browserlist&lt;/code&gt;查找出当前浏览器哪些特性缺乏支持从而返回这些特性的  &lt;code&gt;Polyfill&lt;/code&gt;。对这方面感兴趣的同学可参考  &lt;a href="https://github.com/Financial-Times/polyfill-library" rel="nofollow noreferrer"&gt;polyfill-library&lt;/a&gt;和  &lt;a href="https://github.com/Financial-Times/polyfill-service" rel="nofollow noreferrer"&gt;polyfill-service&lt;/a&gt;的源码。&lt;/p&gt; &lt;p&gt;在此提供两个  &lt;code&gt;动态垫片&lt;/code&gt;服务，可在不同浏览器里点击以下链接看看输出不同的  &lt;code&gt;Polyfill&lt;/code&gt;。相信  &lt;code&gt;IExplore&lt;/code&gt;还是最多  &lt;code&gt;Polyfill&lt;/code&gt;的，它自豪地说：  &lt;code&gt;我就是我，不一样的烟火&lt;/code&gt;。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;strong&gt;官方CDN服务&lt;/strong&gt;：   &lt;a href="https://polyfill.io/v3/polyfill.min.js" rel="nofollow noreferrer"&gt;https://polyfill.io/v3/polyfill.min.js&lt;/a&gt;&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;阿里CDN服务&lt;/strong&gt;：   &lt;a href="https://polyfill.alicdn.com/polyfill.min.js" rel="nofollow noreferrer"&gt;https://polyfill.alicdn.com/polyfill.min.js&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;使用  &lt;a href="https://github.com/jharris4/html-webpack-tags-plugin" rel="nofollow noreferrer"&gt;html-webpack-tags-plugin&lt;/a&gt;在打包时自动插入  &lt;code&gt;动态垫片&lt;/code&gt;。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;import HtmlTagsPlugin from &amp;quot;html-webpack-tags-plugin&amp;quot;;

export default {
    plugins: [
        new HtmlTagsPlugin({
            append: false, // 在生成资源后插入
            publicPath: false, // 使用公共路径
            tags: [&amp;quot;https://polyfill.alicdn.com/polyfill.min.js&amp;quot;] // 资源路径
        })
    ]
};&lt;/code&gt;&lt;/pre&gt; &lt;blockquote&gt;按需加载&lt;/blockquote&gt; &lt;p&gt;  &lt;strong&gt;将路由页面/触发性功能单独打包为一个文件，使用时才加载&lt;/strong&gt;，好处是  &lt;code&gt;减轻首屏渲染的负担&lt;/code&gt;。因为项目功能越多其打包体积越大，导致首屏渲染速度越慢。&lt;/p&gt; &lt;p&gt;首屏渲染时只需对应  &lt;code&gt;JS代码&lt;/code&gt;而无需其他  &lt;code&gt;JS代码&lt;/code&gt;，所以可使用  &lt;code&gt;按需加载&lt;/code&gt;。  &lt;code&gt;webpack v4&lt;/code&gt;提供模块按需切割加载功能，配合  &lt;code&gt;import()&lt;/code&gt;可做到首屏渲染减包的效果，从而加快首屏渲染速度。只有当触发某些功能时才会加载当前功能的  &lt;code&gt;JS代码&lt;/code&gt;。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;webpack v4&lt;/code&gt;提供魔术注解命名  &lt;code&gt;切割模块&lt;/code&gt;，若无注解则切割出来的模块无法分辨出属于哪个业务模块，所以一般都是一个业务模块共用一个  &lt;code&gt;切割模块&lt;/code&gt;的注解名称。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;const Login = () =&amp;gt; import( /* webpackChunkName: &amp;quot;login&amp;quot; */ &amp;quot;../../views/login&amp;quot;);
const Logon = () =&amp;gt; import( /* webpackChunkName: &amp;quot;logon&amp;quot; */ &amp;quot;../../views/logon&amp;quot;);&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;运行起来控制台可能会报错，在  &lt;code&gt;package.json&lt;/code&gt;的  &lt;code&gt;babel&lt;/code&gt;相关配置里接入  &lt;a href="https://babeljs.io/docs/en/babel-plugin-syntax-dynamic-import.html" rel="nofollow noreferrer"&gt;@babel/plugin-syntax-dynamic-import&lt;/a&gt;即可。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;{
    // ...
    &amp;quot;babel&amp;quot;: {
        // ...
        &amp;quot;plugins&amp;quot;: [
            // ...
            &amp;quot;@babel/plugin-syntax-dynamic-import&amp;quot;
        ]
    }
}&lt;/code&gt;&lt;/pre&gt; &lt;blockquote&gt;作用提升&lt;/blockquote&gt; &lt;p&gt;  &lt;strong&gt;分析模块间依赖关系，把打包好的模块合并到一个函数中&lt;/strong&gt;，好处是  &lt;code&gt;减少函数声明和内存花销&lt;/code&gt;。  &lt;code&gt;作用提升&lt;/code&gt;首次出现于  &lt;code&gt;rollup&lt;/code&gt;，是  &lt;code&gt;rollup&lt;/code&gt;的核心概念，后来在  &lt;code&gt;webpack v3&lt;/code&gt;里借鉴过来使用。&lt;/p&gt; &lt;p&gt;在未开启  &lt;code&gt;作用提升&lt;/code&gt;前，构建后的代码会存在大量函数闭包。由于模块依赖，通过  &lt;code&gt;webpack&lt;/code&gt;打包后会转换成  &lt;code&gt;IIFE&lt;/code&gt;，大量函数闭包包裹代码会导致打包体积增大(  &lt;code&gt;模块越多越明显&lt;/code&gt;)。在运行代码时创建的函数作用域变多，从而导致更大的内存开销。&lt;/p&gt; &lt;p&gt;在开启  &lt;code&gt;作用提升&lt;/code&gt;后，构建后的代码会按照引入顺序放到一个函数作用域里，通过适当重命名某些变量以防止变量名冲突，从而减少函数声明和内存花销。&lt;/p&gt; &lt;p&gt;在  &lt;code&gt;webpack&lt;/code&gt;里只需将打包环境设置成  &lt;code&gt;生产环境&lt;/code&gt;就能让  &lt;code&gt;作用提升&lt;/code&gt;生效，或显式设置  &lt;code&gt;concatenateModules&lt;/code&gt;。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;export default {
    // ...
    mode: &amp;quot;production&amp;quot;
};
// 显式设置
export default {
    // ...
    optimization: {
        // ...
        concatenateModules: true
    }
};&lt;/code&gt;&lt;/pre&gt; &lt;blockquote&gt;压缩资源&lt;/blockquote&gt; &lt;p&gt;  &lt;strong&gt;压缩HTML/CSS/JS代码，压缩字体/图像/音频/视频&lt;/strong&gt;，好处是  &lt;code&gt;更有效减少打包体积&lt;/code&gt;。极致地优化代码都有可能不及优化一个资源文件的体积更有效。&lt;/p&gt; &lt;p&gt;针对  &lt;code&gt;HTML&lt;/code&gt;代码，使用  &lt;a href="https://github.com/jantimon/html-webpack-plugin" rel="nofollow noreferrer"&gt;html-webpack-plugin&lt;/a&gt;开启压缩功能。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;import HtmlPlugin from &amp;quot;html-webpack-plugin&amp;quot;;

export default {
    // ...
    plugins: [
        // ...
        HtmlPlugin({
            // ...
            minify: {
                collapseWhitespace: true,
                removeComments: true
            } // 压缩HTML
        })
    ]
};&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;针对  &lt;code&gt;CSS/JS&lt;/code&gt;代码，分别使用以下插件开启压缩功能。其中  &lt;code&gt;OptimizeCss&lt;/code&gt;基于  &lt;code&gt;cssnano&lt;/code&gt;封装，  &lt;code&gt;Uglifyjs&lt;/code&gt;和  &lt;code&gt;Terser&lt;/code&gt;都是  &lt;code&gt;webpack&lt;/code&gt;官方插件，同时需注意压缩  &lt;code&gt;JS代码&lt;/code&gt;需区分  &lt;code&gt;ES5&lt;/code&gt;和  &lt;code&gt;ES6&lt;/code&gt;。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;a href="https://github.com/NMFR/optimize-css-assets-webpack-plugin" rel="nofollow noreferrer"&gt;optimize-css-assets-webpack-plugin&lt;/a&gt;：压缩   &lt;code&gt;CSS代码&lt;/code&gt;&lt;/li&gt;  &lt;li&gt;   &lt;a href="https://github.com/webpack-contrib/uglifyjs-webpack-plugin" rel="nofollow noreferrer"&gt;uglifyjs-webpack-plugin&lt;/a&gt;：压缩   &lt;code&gt;ES5&lt;/code&gt;版本的   &lt;code&gt;JS代码&lt;/code&gt;&lt;/li&gt;  &lt;li&gt;   &lt;a href="https://github.com/webpack-contrib/terser-webpack-plugin" rel="nofollow noreferrer"&gt;terser-webpack-plugin&lt;/a&gt;：压缩   &lt;code&gt;ES6&lt;/code&gt;版本的   &lt;code&gt;JS代码&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt; &lt;pre&gt;  &lt;code&gt;import OptimizeCssAssetsPlugin from &amp;quot;optimize-css-assets-webpack-plugin&amp;quot;;
import TerserPlugin from &amp;quot;terser-webpack-plugin&amp;quot;;
import UglifyjsPlugin from &amp;quot;uglifyjs-webpack-plugin&amp;quot;;

const compressOpts = type =&amp;gt; ({
    cache: true, // 缓存文件
    parallel: true, // 并行处理
    [`${type}Options`]: {
        beautify: false,
        compress: { drop_console: true }
    } // 压缩配置
});
const compressCss = new OptimizeCssAssetsPlugin({
    cssProcessorOptions: {
        autoprefixer: { remove: false }, // 设置autoprefixer保留过时样式
        safe: true // 避免cssnano重新计算z-index
    }
});
const compressJs = USE_ES6
    ? new TerserPlugin(compressOpts(&amp;quot;terser&amp;quot;))
    : new UglifyjsPlugin(compressOpts(&amp;quot;uglify&amp;quot;));

export default {
    // ...
    optimization: {
        // ...
        minimizer: [compressCss, compressJs] // 代码压缩
    }
};&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;针对  &lt;code&gt;字体/音频/视频&lt;/code&gt;文件，还真没相关  &lt;code&gt;Plugin&lt;/code&gt;供我们使用，就只能拜托大家在发布项目到生产服前使用对应的压缩工具处理了。针对  &lt;code&gt;图像&lt;/code&gt;文件，大部分  &lt;code&gt;Loader/Plugin&lt;/code&gt;封装时均使用了某些图像处理工具，而这些工具的某些功能又托管在国外服务器里，所以导致经常安装失败。具体解决方式可回看笔者曾经发布的  &lt;a href="https://juejin.cn/post/6844904192247595022" rel="nofollow noreferrer"&gt;《聊聊NPM镜像那些险象环生的坑》&lt;/a&gt;一文寻求答案。&lt;/p&gt; &lt;p&gt;鉴于此，笔者花了一点小技巧开发了一个  &lt;code&gt;Plugin&lt;/code&gt;用于配合  &lt;code&gt;webpack&lt;/code&gt;压缩图像，详情请参考  &lt;a href="https://github.com/JowayYoung/tinyimg-webpack-plugin" rel="nofollow noreferrer"&gt;tinyimg-webpack-plugin&lt;/a&gt;。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;import TinyimgPlugin from &amp;quot;tinyimg-webpack-plugin&amp;quot;;

export default {
    // ...
    plugins: [
        // ...
        TinyimgPlugin()
    ]
};&lt;/code&gt;&lt;/pre&gt; &lt;hr&gt;&lt;/hr&gt; &lt;p&gt;上述  &lt;code&gt;构建策略&lt;/code&gt;都集成到笔者开源的  &lt;a href="https://github.com/JowayYoung/bruce-cli" rel="nofollow noreferrer"&gt;bruce-cli&lt;/a&gt;里，它是一个  &lt;strong&gt;React/Vue&lt;/strong&gt;应用自动化构建脚手架，其零配置开箱即用的优点非常适合入门级、初中级、快速开发项目的前端同学使用，还可通过创建  &lt;code&gt;brucerc.js&lt;/code&gt;文件覆盖其默认配置，只需专注业务代码的编写无需关注构建代码的编写，让项目结构更简洁。详情请戳  &lt;a href="https://github.com/JowayYoung/bruce-cli" rel="nofollow noreferrer"&gt;这里&lt;/a&gt;，使用时记得查看文档，支持一个  &lt;a href="https://github.com/JowayYoung/bruce-cli" rel="nofollow noreferrer"&gt;Star&lt;/a&gt;哈！&lt;/p&gt; &lt;h5&gt;图像策略&lt;/h5&gt; &lt;p&gt;该策略主要围绕  &lt;code&gt;图像类型&lt;/code&gt;做相关处理，同时也是接入成本较低的  &lt;code&gt;性能优化策略&lt;/code&gt;。只需做到以下两点即可。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;strong&gt;图像选型&lt;/strong&gt;：了解所有图像类型的特点及其何种应用场景最合适&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;图像压缩&lt;/strong&gt;：在部署到生产环境前使用工具或脚本对其压缩处理&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;code&gt;图像选型&lt;/code&gt;一定要知道每种图像类型的  &lt;code&gt;体积/质量/兼容/请求/压缩/透明/场景&lt;/code&gt;等参数相对值，这样才能迅速做出判断在何种场景使用何种类型的图像。&lt;/p&gt; &lt;table&gt;  &lt;tr&gt;   &lt;th align="center"&gt;类型&lt;/th&gt;   &lt;th align="center"&gt;体积&lt;/th&gt;   &lt;th align="center"&gt;质量&lt;/th&gt;   &lt;th align="center"&gt;兼容&lt;/th&gt;   &lt;th align="center"&gt;请求&lt;/th&gt;   &lt;th align="center"&gt;压缩&lt;/th&gt;   &lt;th align="center"&gt;透明&lt;/th&gt;   &lt;th&gt;场景&lt;/th&gt;&lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center"&gt;JPG&lt;/td&gt;   &lt;td align="center"&gt;小&lt;/td&gt;   &lt;td align="center"&gt;中&lt;/td&gt;   &lt;td align="center"&gt;高&lt;/td&gt;   &lt;td align="center"&gt;是&lt;/td&gt;   &lt;td align="center"&gt;有损&lt;/td&gt;   &lt;td align="center"&gt;不支持&lt;/td&gt;   &lt;td&gt;背景图、轮播图、色彩丰富图&lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center"&gt;PNG&lt;/td&gt;   &lt;td align="center"&gt;大&lt;/td&gt;   &lt;td align="center"&gt;高&lt;/td&gt;   &lt;td align="center"&gt;高&lt;/td&gt;   &lt;td align="center"&gt;是&lt;/td&gt;   &lt;td align="center"&gt;无损&lt;/td&gt;   &lt;td align="center"&gt;支持&lt;/td&gt;   &lt;td&gt;图标、透明图&lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center"&gt;SVG&lt;/td&gt;   &lt;td align="center"&gt;小&lt;/td&gt;   &lt;td align="center"&gt;高&lt;/td&gt;   &lt;td align="center"&gt;高&lt;/td&gt;   &lt;td align="center"&gt;是&lt;/td&gt;   &lt;td align="center"&gt;无损&lt;/td&gt;   &lt;td align="center"&gt;支持&lt;/td&gt;   &lt;td&gt;图标、矢量图&lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center"&gt;WebP&lt;/td&gt;   &lt;td align="center"&gt;小&lt;/td&gt;   &lt;td align="center"&gt;中&lt;/td&gt;   &lt;td align="center"&gt;低&lt;/td&gt;   &lt;td align="center"&gt;是&lt;/td&gt;   &lt;td align="center"&gt;兼备&lt;/td&gt;   &lt;td align="center"&gt;支持&lt;/td&gt;   &lt;td&gt;看兼容情况&lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center"&gt;Base64&lt;/td&gt;   &lt;td align="center"&gt;看情况&lt;/td&gt;   &lt;td align="center"&gt;中&lt;/td&gt;   &lt;td align="center"&gt;高&lt;/td&gt;   &lt;td align="center"&gt;否&lt;/td&gt;   &lt;td align="center"&gt;无损&lt;/td&gt;   &lt;td align="center"&gt;支持&lt;/td&gt;   &lt;td&gt;图标&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;p&gt;  &lt;code&gt;图像压缩&lt;/code&gt;可在上述  &lt;code&gt;构建策略-压缩资源&lt;/code&gt;里完成，也可自行使用工具完成。由于现在大部分  &lt;code&gt;webpack&lt;/code&gt;图像压缩工具不是安装失败就是各种环境问题(  &lt;code&gt;你懂的&lt;/code&gt;)，所以笔者还是推荐在发布项目到生产服前使用图像压缩工具处理，这样运行稳定也不会增加打包时间。&lt;/p&gt; &lt;p&gt;好用的图像压缩工具无非就是以下几个，若有更好用的工具麻烦在评论里补充喔！&lt;/p&gt; &lt;table&gt;  &lt;tr&gt;   &lt;th align="center"&gt;工具&lt;/th&gt;   &lt;th align="center"&gt;开源&lt;/th&gt;   &lt;th align="center"&gt;收费&lt;/th&gt;   &lt;th align="center"&gt;API&lt;/th&gt;   &lt;th&gt;免费体验&lt;/th&gt;&lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center"&gt;    &lt;a href="https://www.tuhaokuai.com" rel="nofollow noreferrer"&gt;QuickPicture&lt;/a&gt;&lt;/td&gt;   &lt;td align="center"&gt;✖️&lt;/td&gt;   &lt;td align="center"&gt;✔️&lt;/td&gt;   &lt;td align="center"&gt;✖️&lt;/td&gt;   &lt;td&gt;可压缩类型较多，压缩质感较好，有体积限制，有数量限制&lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center"&gt;    &lt;a href="https://shrinkme.app" rel="nofollow noreferrer"&gt;ShrinkMe&lt;/a&gt;&lt;/td&gt;   &lt;td align="center"&gt;✖️&lt;/td&gt;   &lt;td align="center"&gt;✖️&lt;/td&gt;   &lt;td align="center"&gt;✖️&lt;/td&gt;   &lt;td&gt;可压缩类型较多，压缩质感一般，无数量限制，有体积限制&lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center"&gt;    &lt;a href="https://squoosh.app" rel="nofollow noreferrer"&gt;Squoosh&lt;/a&gt;&lt;/td&gt;   &lt;td align="center"&gt;✔️&lt;/td&gt;   &lt;td align="center"&gt;✖️&lt;/td&gt;   &lt;td align="center"&gt;✔️&lt;/td&gt;   &lt;td&gt;可压缩类型较少，压缩质感一般，无数量限制，有体积限制&lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center"&gt;    &lt;a href="https://tinyjpg.com" rel="nofollow noreferrer"&gt;TinyJpg&lt;/a&gt;&lt;/td&gt;   &lt;td align="center"&gt;✖️&lt;/td&gt;   &lt;td align="center"&gt;✔️&lt;/td&gt;   &lt;td align="center"&gt;✔️&lt;/td&gt;   &lt;td&gt;可压缩类型较少，压缩质感很好，有数量限制，有体积限制&lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center"&gt;    &lt;a href="https://tinypng.com" rel="nofollow noreferrer"&gt;TinyPng&lt;/a&gt;&lt;/td&gt;   &lt;td align="center"&gt;✖️&lt;/td&gt;   &lt;td align="center"&gt;✔️&lt;/td&gt;   &lt;td align="center"&gt;✔️&lt;/td&gt;   &lt;td&gt;可压缩类型较少，压缩质感很好，有数量限制，有体积限制&lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center"&gt;    &lt;a href="https://zhitu.isux.us" rel="nofollow noreferrer"&gt;Zhitu&lt;/a&gt;&lt;/td&gt;   &lt;td align="center"&gt;✖️&lt;/td&gt;   &lt;td align="center"&gt;✖️&lt;/td&gt;   &lt;td align="center"&gt;✖️&lt;/td&gt;   &lt;td&gt;可压缩类型一般，压缩质感一般，有数量限制，有体积限制&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;p&gt;若不想在网站里来回拖动图像文件，可使用笔者开源的图像批处理工具  &lt;a href="https://github.com/JowayYoung/img-master" rel="nofollow noreferrer"&gt;img-master&lt;/a&gt;代替，不仅有压缩功能，还有分组功能、标记功能和变换功能。目前笔者负责的全部项目都使用该工具处理，一直用一直爽！&lt;/p&gt; &lt;p&gt;  &lt;code&gt;图像策略&lt;/code&gt;也许处理一张图像就能完爆所有  &lt;code&gt;构建策略&lt;/code&gt;，因此是一种很廉价但极有效的  &lt;code&gt;性能优化策略&lt;/code&gt;。&lt;/p&gt; &lt;h5&gt;分发策略&lt;/h5&gt; &lt;p&gt;该策略主要围绕  &lt;code&gt;内容分发网络&lt;/code&gt;做相关处理，同时也是接入成本较高的  &lt;code&gt;性能优化策略&lt;/code&gt;，需足够资金支持。&lt;/p&gt; &lt;p&gt;虽然接入成本较高，但大部分企业都会购买一些  &lt;code&gt;CDN服务器&lt;/code&gt;，所以在部署的事情上就不用过分担忧，尽管使用就好。该策略尽量遵循以下两点就能发挥  &lt;code&gt;CDN&lt;/code&gt;最大作用。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;strong&gt;所有静态资源走CDN&lt;/strong&gt;：开发阶段确定哪些文件属于静态资源&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;把静态资源与主页面置于不同域名下&lt;/strong&gt;：避免请求带上   &lt;code&gt;Cookie&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;strong&gt;内容分发网络&lt;/strong&gt;简称  &lt;strong&gt;CDN&lt;/strong&gt;，指一组分布在各地存储数据副本并可根据就近原则满足数据请求的服务器。其核心特征是  &lt;code&gt;缓存&lt;/code&gt;和  &lt;code&gt;回源&lt;/code&gt;，缓存是把资源复制到  &lt;code&gt;CDN服务器&lt;/code&gt;里，回源是  &lt;code&gt;资源过期/不存在&lt;/code&gt;就向上层服务器请求并复制到  &lt;code&gt;CDN服务器&lt;/code&gt;里。&lt;/p&gt; &lt;p&gt;使用  &lt;code&gt;CDN&lt;/code&gt;可降低网络拥塞，提高用户访问响应速度和命中率。构建在现有网络基础上的智能虚拟网络，依靠部署在各地服务器，通过中心平台的调度、负载均衡、内容分发等功能模块，使用户就近获取所需资源，这就是  &lt;code&gt;CDN&lt;/code&gt;的终极使命。&lt;/p&gt; &lt;p&gt;基于  &lt;code&gt;CDN&lt;/code&gt;的  &lt;strong&gt;就近原则&lt;/strong&gt;所带来的优点，可将网站所有静态资源全部部署到  &lt;code&gt;CDN服务器&lt;/code&gt;里。那静态资源包括哪些文件？通常来说就是无需服务器产生计算就能得到的资源，例如不常变化的  &lt;code&gt;样式文件&lt;/code&gt;、  &lt;code&gt;脚本文件&lt;/code&gt;和  &lt;code&gt;多媒体文件(字体/图像/音频/视频)&lt;/code&gt;等。&lt;/p&gt; &lt;p&gt;若需单独配置  &lt;code&gt;CDN服务器&lt;/code&gt;，可考虑  &lt;a href="https://www.aliyun.com/product/oss" rel="nofollow noreferrer"&gt;阿里云OSS&lt;/a&gt;、  &lt;a href="https://www.163yun.com/product/nos" rel="nofollow noreferrer"&gt;网易树帆NOS&lt;/a&gt;和  &lt;a href="https://www.qiniu.com/products/kodo" rel="nofollow noreferrer"&gt;七牛云Kodo&lt;/a&gt;，当然配置起来还需购买该产品对应的  &lt;code&gt;CDN服务&lt;/code&gt;。由于篇幅问题，这些配置在购买后会有相关教程，可自行体会，在此就不再叙述了。&lt;/p&gt; &lt;p&gt;笔者推荐大家首选  &lt;a href="https://www.163yun.com/product/nos" rel="nofollow noreferrer"&gt;网易树帆NOS&lt;/a&gt;，毕竟对自家产品还是挺有信心的，不小心给自家产品打了个小广告了，哈哈！&lt;/p&gt; &lt;h5&gt;缓存策略&lt;/h5&gt; &lt;p&gt;该策略主要围绕  &lt;code&gt;浏览器缓存&lt;/code&gt;做相关处理，同时也使接入成本最低的  &lt;code&gt;性能优化策略&lt;/code&gt;。其显著减少网络传输所带来的损耗，提升网页访问速度，是一种很值得使用的  &lt;code&gt;性能优化策略&lt;/code&gt;。&lt;/p&gt; &lt;p&gt;通过下图可知，为了让  &lt;code&gt;浏览器缓存&lt;/code&gt;发挥最大作用，该策略尽量遵循以下五点就能发挥  &lt;code&gt;浏览器缓存&lt;/code&gt;最大作用。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;strong&gt;考虑拒绝一切缓存策略&lt;/strong&gt;：   &lt;code&gt;Cache-Control:no-store&lt;/code&gt;&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;考虑资源是否每次向服务器请求&lt;/strong&gt;：   &lt;code&gt;Cache-Control:no-cache&lt;/code&gt;&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;考虑资源是否被代理服务器缓存&lt;/strong&gt;：   &lt;code&gt;Cache-Control:public/private&lt;/code&gt;&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;考虑资源过期时间&lt;/strong&gt;：   &lt;code&gt;Expires:t/Cache-Control:max-age=t,s-maxage=t&lt;/code&gt;&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;考虑协商缓存&lt;/strong&gt;：   &lt;code&gt;Last-Modified/Etag&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;img alt="&amp;#32531;&amp;#23384;&amp;#21028;&amp;#26029;&amp;#26426;&amp;#21046;" src="https://segmentfault.com/img/remote/1460000040343060" title="&amp;#32531;&amp;#23384;&amp;#21028;&amp;#26029;&amp;#26426;&amp;#21046;"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;同时  &lt;code&gt;浏览器缓存&lt;/code&gt;也是高频面试题之一，笔者觉得上述涉及到的名词在不同语序串联下也能完全理解才能真正弄懂  &lt;code&gt;浏览器缓存&lt;/code&gt;在  &lt;code&gt;性能优化&lt;/code&gt;里起到的作用。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;缓存策略&lt;/code&gt;通过设置  &lt;code&gt;HTTP&lt;/code&gt;报文实现，在形式上分为  &lt;strong&gt;强缓存/强制缓存&lt;/strong&gt;和  &lt;strong&gt;协商缓存/对比缓存&lt;/strong&gt;。为了方便对比，笔者将某些细节使用图例展示，相信你有更好的理解。&lt;/p&gt; &lt;p&gt;  &lt;img alt="&amp;#24378;&amp;#32531;&amp;#23384;.png" src="https://segmentfault.com/img/remote/1460000040343061" title="&amp;#24378;&amp;#32531;&amp;#23384;.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;  &lt;img alt="&amp;#21327;&amp;#21830;&amp;#32531;&amp;#23384;.png" src="https://segmentfault.com/img/remote/1460000040343062" title="&amp;#21327;&amp;#21830;&amp;#32531;&amp;#23384;.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;整个  &lt;code&gt;缓存策略&lt;/code&gt;机制很明了，  &lt;code&gt;先走强缓存，若命中失败才走协商缓存&lt;/code&gt;。若命中  &lt;code&gt;强缓存&lt;/code&gt;，直接使用  &lt;code&gt;强缓存&lt;/code&gt;；若未命中  &lt;code&gt;强缓存&lt;/code&gt;，发送请求到服务器检查是否命中  &lt;code&gt;协商缓存&lt;/code&gt;；若命中  &lt;code&gt;协商缓存&lt;/code&gt;，服务器返回304通知浏览器使用  &lt;code&gt;本地缓存&lt;/code&gt;，否则返回  &lt;code&gt;最新资源&lt;/code&gt;。&lt;/p&gt; &lt;p&gt;有两种较常用的应用场景值得使用  &lt;code&gt;缓存策略&lt;/code&gt;一试，当然更多应用场景都可根据项目需求制定。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;strong&gt;频繁变动资源&lt;/strong&gt;：设置   &lt;code&gt;Cache-Control:no-cache&lt;/code&gt;，使浏览器每次都发送请求到服务器，配合   &lt;code&gt;Last-Modified/ETag&lt;/code&gt;验证资源是否有效&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;不常变化资源&lt;/strong&gt;：设置   &lt;code&gt;Cache-Control:max-age=31536000&lt;/code&gt;，对文件名哈希处理，当代码修改后生成新的文件名，当HTML文件引入文件名发生改变才会下载最新文件&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;渲染层面&lt;/h4&gt; &lt;p&gt;  &lt;strong&gt;渲染层面&lt;/strong&gt;的性能优化，无疑是如何让代码  &lt;code&gt;解析更好执行更快&lt;/code&gt;。因此笔者从以下五方面做出建议。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;strong&gt;CSS策略&lt;/strong&gt;：基于CSS规则&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;DOM策略&lt;/strong&gt;：基于DOM操作&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;阻塞策略&lt;/strong&gt;：基于脚本加载&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;回流重绘策略&lt;/strong&gt;：基于回流重绘&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;异步更新策略&lt;/strong&gt;：基于异步更新&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;上述五方面都是编写代码时完成，充满在整个项目流程的开发阶段里。因此在开发阶段需时刻注意以下涉及到的每一点，养成良好的开发习惯，  &lt;code&gt;性能优化&lt;/code&gt;也自然而然被使用上了。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;渲染层面&lt;/code&gt;的  &lt;code&gt;性能优化&lt;/code&gt;更多表现在编码细节上，而并非实体代码。简单来说就是遵循某些编码规则，才能将  &lt;code&gt;渲染层面&lt;/code&gt;的  &lt;code&gt;性能优化&lt;/code&gt;发挥到最大作用。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;回流重绘策略&lt;/strong&gt;在  &lt;code&gt;渲染层面&lt;/code&gt;的  &lt;code&gt;性能优化&lt;/code&gt;里占比较重，也是最常规的  &lt;code&gt;性能优化&lt;/code&gt;之一。上年笔者发布的掘金小册  &lt;a href="https://juejin.cn/book/6850413616484040711" rel="nofollow noreferrer"&gt;《玩转CSS的艺术之美》&lt;/a&gt;使用一整章讲解  &lt;code&gt;回流重绘&lt;/code&gt;，本章已开通试读，更多细节请戳  &lt;a href="https://juejin.cn/book/6850413616484040711/section/6850413616559194119" rel="nofollow noreferrer"&gt;这里&lt;/a&gt;。&lt;/p&gt; &lt;h5&gt;CSS策略&lt;/h5&gt; &lt;ul&gt;  &lt;li&gt;避免出现超过三层的   &lt;code&gt;嵌套规则&lt;/code&gt;&lt;/li&gt;  &lt;li&gt;避免为   &lt;code&gt;ID选择器&lt;/code&gt;添加多余选择器&lt;/li&gt;  &lt;li&gt;避免使用   &lt;code&gt;标签选择器&lt;/code&gt;代替   &lt;code&gt;类选择器&lt;/code&gt;&lt;/li&gt;  &lt;li&gt;避免使用   &lt;code&gt;通配选择器&lt;/code&gt;，只对目标节点声明规则&lt;/li&gt;  &lt;li&gt;避免重复匹配重复定义，关注   &lt;code&gt;可继承属性&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h5&gt;DOM策略&lt;/h5&gt; &lt;ul&gt;  &lt;li&gt;缓存   &lt;code&gt;DOM计算属性&lt;/code&gt;&lt;/li&gt;  &lt;li&gt;避免过多   &lt;code&gt;DOM操作&lt;/code&gt;&lt;/li&gt;  &lt;li&gt;使用   &lt;code&gt;DOMFragment&lt;/code&gt;缓存批量化   &lt;code&gt;DOM操作&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h5&gt;阻塞策略&lt;/h5&gt; &lt;ul&gt;  &lt;li&gt;脚本与   &lt;code&gt;DOM/其它脚本&lt;/code&gt;的依赖关系很强：对   &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;设置   &lt;code&gt;defer&lt;/code&gt;&lt;/li&gt;  &lt;li&gt;脚本与   &lt;code&gt;DOM/其它脚本&lt;/code&gt;的依赖关系不强：对   &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;设置   &lt;code&gt;async&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h5&gt;回流重绘策略&lt;/h5&gt; &lt;ul&gt;  &lt;li&gt;缓存   &lt;code&gt;DOM计算属性&lt;/code&gt;&lt;/li&gt;  &lt;li&gt;使用类合并样式，避免逐条改变样式&lt;/li&gt;  &lt;li&gt;使用   &lt;code&gt;display&lt;/code&gt;控制   &lt;code&gt;DOM显隐&lt;/code&gt;，将   &lt;code&gt;DOM离线化&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h5&gt;异步更新策略&lt;/h5&gt; &lt;ul&gt;  &lt;li&gt;在   &lt;code&gt;异步任务&lt;/code&gt;中修改   &lt;code&gt;DOM&lt;/code&gt;时把其包装成   &lt;code&gt;微任务&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;六大指标&lt;/h3&gt; &lt;p&gt;笔者根据  &lt;code&gt;性能优化&lt;/code&gt;的重要性和实际性划分出  &lt;code&gt;九大策略&lt;/code&gt;和  &lt;code&gt;六大指标&lt;/code&gt;，其实它们都是一条条活生生的  &lt;code&gt;性能优化建议&lt;/code&gt;。有些  &lt;code&gt;性能优化建议&lt;/code&gt;接不接入影响都不大，因此笔者将  &lt;code&gt;九大策略&lt;/code&gt;定位高于  &lt;code&gt;六大指标&lt;/code&gt;。针对  &lt;code&gt;九大策略&lt;/code&gt;还是建议在开发阶段和生产阶段接入，在项目复盘时可将  &lt;code&gt;六大指标&lt;/code&gt;的条条框框根据实际应用场景接入。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;六大指标&lt;/code&gt;基本囊括大部分  &lt;code&gt;性能优化&lt;/code&gt;细节，可作为  &lt;code&gt;九大策略&lt;/code&gt;的补充。笔者根据每条  &lt;code&gt;性能优化建议&lt;/code&gt;的特征将  &lt;code&gt;指标&lt;/code&gt;划分为以下六方面。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;strong&gt;加载优化&lt;/strong&gt;：资源在加载时可做的性能优化&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;执行优化&lt;/strong&gt;：资源在执行时可做的性能优化&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;渲染优化&lt;/strong&gt;：资源在渲染时可做的性能优化&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;样式优化&lt;/strong&gt;：样式在编码时可做的性能优化&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;脚本优化&lt;/strong&gt;：脚本在编码时可做的性能优化&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;V8引擎优化&lt;/strong&gt;：针对   &lt;code&gt;V8引擎&lt;/code&gt;特征可做的性能优化&lt;/li&gt;&lt;/ul&gt; &lt;h5&gt;加载优化&lt;/h5&gt; &lt;p&gt;  &lt;img alt="&amp;#20845;&amp;#22823;&amp;#25351;&amp;#26631;-&amp;#21152;&amp;#36733;&amp;#20248;&amp;#21270;.png" src="https://segmentfault.com/img/remote/1460000040343063" title="&amp;#20845;&amp;#22823;&amp;#25351;&amp;#26631;-&amp;#21152;&amp;#36733;&amp;#20248;&amp;#21270;.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;h5&gt;执行优化&lt;/h5&gt; &lt;p&gt;  &lt;img alt="&amp;#20845;&amp;#22823;&amp;#25351;&amp;#26631;-&amp;#25191;&amp;#34892;&amp;#20248;&amp;#21270;.png" src="https://segmentfault.com/img/remote/1460000040343064" title="&amp;#20845;&amp;#22823;&amp;#25351;&amp;#26631;-&amp;#25191;&amp;#34892;&amp;#20248;&amp;#21270;.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;h5&gt;渲染优化&lt;/h5&gt; &lt;p&gt;  &lt;img alt="&amp;#20845;&amp;#22823;&amp;#25351;&amp;#26631;-&amp;#28210;&amp;#26579;&amp;#20248;&amp;#21270;.png" src="https://segmentfault.com/img/remote/1460000040343065" title="&amp;#20845;&amp;#22823;&amp;#25351;&amp;#26631;-&amp;#28210;&amp;#26579;&amp;#20248;&amp;#21270;.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;h5&gt;样式优化&lt;/h5&gt; &lt;p&gt;  &lt;img alt="&amp;#20845;&amp;#22823;&amp;#25351;&amp;#26631;-&amp;#26679;&amp;#24335;&amp;#20248;&amp;#21270;.png" src="https://segmentfault.com/img/remote/1460000040343066" title="&amp;#20845;&amp;#22823;&amp;#25351;&amp;#26631;-&amp;#26679;&amp;#24335;&amp;#20248;&amp;#21270;.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;h5&gt;脚本优化&lt;/h5&gt; &lt;p&gt;  &lt;img alt="&amp;#20845;&amp;#22823;&amp;#25351;&amp;#26631;-&amp;#33050;&amp;#26412;&amp;#20248;&amp;#21270;.png" src="https://segmentfault.com/img/remote/1460000040343067" title="&amp;#20845;&amp;#22823;&amp;#25351;&amp;#26631;-&amp;#33050;&amp;#26412;&amp;#20248;&amp;#21270;.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;h5&gt;V8引擎优化&lt;/h5&gt; &lt;p&gt;  &lt;img alt="&amp;#20845;&amp;#22823;&amp;#25351;&amp;#26631;-V8&amp;#24341;&amp;#25806;&amp;#20248;&amp;#21270;.png" src="https://segmentfault.com/img/remote/1460000040343068" title="&amp;#20845;&amp;#22823;&amp;#25351;&amp;#26631;-V8&amp;#24341;&amp;#25806;&amp;#20248;&amp;#21270;.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;h3&gt;总结&lt;/h3&gt; &lt;p&gt;  &lt;strong&gt;性能优化&lt;/strong&gt;作为老生常谈的知识，必然会在工作或面试时遇上。很多时候不是想到某条  &lt;code&gt;性能优化建议&lt;/code&gt;就去做或答，而是要对这方面有一个整体认知，知道为何这样设计，这样设计的目的能达到什么效果。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;性能优化&lt;/code&gt;不是通过一篇文章就能全部讲完，若详细去讲可能要写两本书的篇幅才能讲完。本文能到给大家的就是一个方向一种态度，学以致用呗，希望阅读完本文会对你有所帮助。&lt;/p&gt; &lt;p&gt;最后，笔者将本文所有内容整理成一张高清脑图，由于体积太大无法上传，可关注笔者个人公众号  &lt;strong&gt;IQ前端&lt;/strong&gt;并回复  &lt;code&gt;性能优化&lt;/code&gt;获取口袋知识图谱吧！&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>前端 html css javascript 性能优化</category>
      <guid isPermaLink="true">https://itindex.net/detail/61610-%E5%89%8D%E7%AB%AF-%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96-%E7%AD%96%E7%95%A5</guid>
      <pubDate>Wed, 14 Jul 2021 08:00:00 CST</pubDate>
    </item>
    <item>
      <title>为什么我们要熟悉这些通信协议？ 【精读】</title>
      <link>https://itindex.net/detail/59874-%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE-%E7%B2%BE%E8%AF%BB</link>
      <description>&lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbvCVD?w=1198&amp;h=868" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h1&gt;前端的最重要的基础知识点是什么？&lt;/h1&gt;
 &lt;ul&gt;
  &lt;li&gt;原生   &lt;code&gt;javaScript&lt;/code&gt;，   &lt;code&gt;HTML&lt;/code&gt;,   &lt;code&gt;CSS&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;Dom&lt;/code&gt;操作&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;EventLoop&lt;/code&gt;和渲染机制&lt;/li&gt;
  &lt;li&gt;各类工程化的工具原理以及使用，根据需求定制编写插件和包。（webpack的plugin和babel的预设包）&lt;/li&gt;
  &lt;li&gt;数据结构和算法（特别是   &lt;code&gt;IM&lt;/code&gt;以及超大型高并发网站应用等，例如   &lt;code&gt;B站&lt;/code&gt;）&lt;/li&gt;
  &lt;li&gt;最后便是通信协议&lt;/li&gt;
&lt;/ul&gt;
 &lt;blockquote&gt;在使用某个技术的时候，一定要去追寻原理和底层的实现，长此以往坚持，只要自身底层的基础扎实，无论技术怎么变化，学习起来都不会太累，总的来说就是拒绝5分钟技术&lt;/blockquote&gt;
 &lt;h2&gt;从输入一个  &lt;code&gt;url&lt;/code&gt;地址，到显示页面发生了什么出发：&lt;/h2&gt;
 &lt;ul&gt;
  &lt;li&gt;1.浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;&lt;/li&gt;
  &lt;li&gt;2.建立TCP连接（三次握手）;&lt;/li&gt;
  &lt;li&gt;3.浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求，该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;&lt;/li&gt;
  &lt;li&gt;4.服务器对浏览器请求作出响应，并把对应的 html 文本发送给浏览器;&lt;/li&gt;
  &lt;li&gt;5.浏览器将该 html 文本并显示内容;&lt;/li&gt;
  &lt;li&gt;6.释放 TCP连接（四次挥手）;&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;目前常见的通信协议都是建立在  &lt;code&gt;TCP&lt;/code&gt;链接之上&lt;/h2&gt;
 &lt;h3&gt;那么什么是  &lt;code&gt;TCP&lt;/code&gt;呢&lt;/h3&gt;
 &lt;h4&gt;TCP是因特网中的传输层协议，使用三次握手协议建立连接。当主动方发出SYN连接请求后，等待对方回答&lt;/h4&gt;
 &lt;blockquote&gt;TCP三次握手的过程如下：&lt;/blockquote&gt;
 &lt;ul&gt;
  &lt;li&gt;客户端发送   &lt;code&gt;SYN&lt;/code&gt;报文给服务器端，进入   &lt;code&gt;SYN_SEND&lt;/code&gt;状态。&lt;/li&gt;
  &lt;li&gt;服务器端收到   &lt;code&gt;SYN&lt;/code&gt;报文，回应一个   &lt;code&gt;SYN&lt;/code&gt;（SEQ=y）ACK（ACK=x+1）报文，进入SYN_RECV状态。&lt;/li&gt;
  &lt;li&gt;客户端收到服务器端的SYN报文，回应一个ACK（ACK=y+1）报文，进入Established状态。&lt;/li&gt;
  &lt;li&gt;三次握手完成，TCP客户端和服务器端成功地建立连接，可以开始传输数据了。&lt;/li&gt;
&lt;/ul&gt;
 &lt;blockquote&gt;如图所示：&lt;/blockquote&gt;
 &lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbvCVC?w=1082&amp;h=914" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;blockquote&gt;
  &lt;code&gt;TCP&lt;/code&gt;的四次挥手：&lt;/blockquote&gt;
 &lt;ul&gt;
  &lt;li&gt;建立一个连接需要三次握手，而终止一个连接要经过四次握手，这是由TCP的半关闭（half-close）造成的。具体过程如下图所示。&lt;/li&gt;
  &lt;li&gt;某个应用进程首先调用close，称该端执行“主动关闭”（active close）。该端的TCP于是发送一个FIN分节，表示数据发送完毕。&lt;/li&gt;
  &lt;li&gt;接收到这个FIN的对端执行 “被动关闭”（passive close），这个FIN由TCP确认。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;注意：FIN的接收也作为一个文件结束符（end-of-file）传递给接收端应用进程，放在已排队等候该应用进程接收的任何其他数据之后，因为，FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;一段时间后，接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。&lt;/li&gt;
  &lt;li&gt;接收这个最终FIN的原发送端TCP（即执行主动关闭的那一端）确认这个FIN。 [3]&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;既然每个方向都需要一个FIN和一个ACK，因此通常需要4个分节。&lt;/p&gt;
 &lt;blockquote&gt;特别提示：   &lt;code&gt;SYN&lt;/code&gt;报文用来通知，  &lt;code&gt;FIN&lt;/code&gt;报文是用来同步的&lt;/blockquote&gt;
 &lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbvCVz?w=1742&amp;h=1194" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;blockquote&gt;以上就是面试官常问的三次握手，四次挥手，但是这不仅仅面试题，上面仅仅答到了一点皮毛，学习这些是为了让我们后续方便了解他的优缺点。&lt;/blockquote&gt;
 &lt;h2&gt;在  &lt;code&gt;TCP&lt;/code&gt;连接建立后，我们可以有多种协议的方式通信交换数据：&lt;/h2&gt;
 &lt;h3&gt;最古老的方式一：  &lt;code&gt;http 1.0&lt;/code&gt;
&lt;/h3&gt;
 &lt;ul&gt;
  &lt;li&gt;早先1.0的HTTP版本，是一种无状态、无连接的应用层协议。&lt;/li&gt;
  &lt;li&gt;HTTP1.0规定浏览器和服务器保持短暂的连接，浏览器的每次请求都需要与服务器建立一个TCP连接，服务器处理完成后立即断开TCP连接（无连接），服务器不跟踪每个客户端也不记录过去的请求（无状态）。&lt;/li&gt;
  &lt;li&gt;这种无状态性可以借助cookie/session机制来做身份认证和状态记录。而下面两个问题就比较麻烦了。&lt;/li&gt;
  &lt;li&gt;首先，无连接的特性导致最大的性能缺陷就是无法复用连接。每次发送请求的时候，都需要进行一次TCP的连接，而TCP的连接释放过程又是比较费事的。这种无连接的特性会使得网络的利用率非常低。&lt;/li&gt;
  &lt;li&gt;其次就是队头阻塞（headoflineblocking）。由于HTTP1.0规定下一个请求必须在前一个请求响应到达之前才能发送。假设前一个请求响应一直不到达，那么下一个请求就不发送，同样的后面的请求也给阻塞了。&lt;/li&gt;
&lt;/ul&gt;
 &lt;blockquote&gt;
  &lt;code&gt;Http 1.0&lt;/code&gt;的致命缺点,就是无法复用  &lt;code&gt;TCP&lt;/code&gt;连接和并行发送请求，这样每次一个请求都需要三次握手，而且其实建立连接和释放连接的这个过程是最耗时的，传输数据相反却不那么耗时。还有本地时间被修改导致响应头  &lt;code&gt;expires&lt;/code&gt;的缓存机制失效的问题～（后面会详细讲）&lt;/blockquote&gt;
 &lt;ul&gt;  &lt;li&gt;常见的请求报文～&lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbvCVA?w=1582&amp;h=1432" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h3&gt;于是出现了  &lt;code&gt;Http 1.1&lt;/code&gt;，这也是技术的发展必然结果～&lt;/h3&gt;
 &lt;ul&gt;
  &lt;li&gt;
   &lt;code&gt;Http 1.1&lt;/code&gt;出现，继承了   &lt;code&gt;Http1.0&lt;/code&gt;的优点，也克服了它的缺点，出现了   &lt;code&gt;keep-alive&lt;/code&gt;这个头部字段，它表示会在建立   &lt;code&gt;TCP&lt;/code&gt;连接后，完成首次的请求，并不会立刻断开   &lt;code&gt;TCP&lt;/code&gt;连接，而是保持这个连接状态～进而可以复用这个通道&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;Http 1.1&lt;/code&gt;并且支持请求管道化，“并行”发送请求，但是这个并行，也不是真正意义上的并行，而是可以让我们把先进先出队列从客户端（请求队列）迁移到服务端（响应队列）&lt;/li&gt;
&lt;/ul&gt;
 &lt;blockquote&gt;例如：客户端同时发了两个请求分别来获取html和css，假如说服务器的css资源先准备就绪，服务器也会先发送html再发送css。&lt;/blockquote&gt;
 &lt;ul&gt;  &lt;li&gt;
   &lt;code&gt;B站&lt;/code&gt;首页，就有   &lt;code&gt;keep-alive&lt;/code&gt;，因为他们也有   &lt;code&gt;IM&lt;/code&gt;的成分在里面。需要大量复用   &lt;code&gt;TCP&lt;/code&gt;连接～&lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbvCVE?w=1442&amp;h=1234" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;
   &lt;code&gt;HTTP1.1&lt;/code&gt;好像还是无法解决队头阻塞的问题&lt;/li&gt;&lt;/ul&gt;
 &lt;blockquote&gt;实际上，现阶段的浏览器厂商采取了另外一种做法，它允许我们打开多个TCP的会话。也就是说，上图我们看到的并行，其实是不同的TCP连接上的HTTP请求和响应。这也就是我们所熟悉的浏览器对同域下并行加载6~8个资源的限制。而这，才是真正的并行！&lt;/blockquote&gt;
 &lt;h4&gt;
  &lt;code&gt;Http 1.1&lt;/code&gt;的致命缺点：&lt;/h4&gt;
 &lt;ul&gt;
  &lt;li&gt;1.明文传输&lt;/li&gt;
  &lt;li&gt;2.其实还是没有解决无状态连接的&lt;/li&gt;
  &lt;li&gt;3.当有多个请求同时被挂起的时候 就会拥塞请求通道，导致后面请求无法发送&lt;/li&gt;
  &lt;li&gt;4.臃肿的消息首部:HTTP/1.1能压缩请求内容,但是消息首部不能压缩;在现今请求中,消息首部占请求绝大部分(甚至是全部)也较为常见.&lt;/li&gt;
&lt;/ul&gt;
 &lt;blockquote&gt;我们也可以用  &lt;code&gt;dns-prefetch和 preconnect tcp&lt;/code&gt;来优化～&lt;/blockquote&gt;
 &lt;pre&gt;  &lt;code&gt;&amp;lt;link rel=&amp;quot;preconnect&amp;quot; href=&amp;quot;//example.com&amp;quot; crossorigin&amp;gt;
&amp;lt;link rel=&amp;quot;dns=prefetch&amp;quot; href=&amp;quot;//example.com&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;ul&gt;  &lt;li&gt;
   &lt;code&gt;Tip&lt;/code&gt;:     &lt;code&gt;webpack&lt;/code&gt;可以做任何事情，这些都可以用插件实现&lt;/li&gt;&lt;/ul&gt;
 &lt;h3&gt;基于这些缺点，出现了  &lt;code&gt;Http 2.0&lt;/code&gt;
&lt;/h3&gt;
 &lt;h4&gt;相较于HTTP1.1，HTTP2.0的主要优点有采用二进制帧封装，传输变成多路复用，流量控制算法优化，服务器端推送，首部压缩，优先级等特点。&lt;/h4&gt;
 &lt;h4&gt;HTTP1.x的解析是基于文本的，基于文本协议的格式解析存在天然缺陷，文本的表现形式有多样性，要做到健壮性考虑的场景必然很多。而HTTP/2会将所有传输的信息分割为更小的消息和帧，然后采用二进制的格式进行编码，HTTP1.x的头部信息会被封装到HEADER frame，而相应的RequestBody则封装到DATAframe里面。不改动HTTP的语义，使用二进制编码，实现方便且健壮。&lt;/h4&gt;
 &lt;h4&gt;多路复用&lt;/h4&gt;
 &lt;ul&gt;  &lt;li&gt;所有的请求都是通过一个 TCP 连接并发完成。HTTP/1.x 虽然通过 pipeline 也能并发请求，但是多个请求之间的响应会被阻塞的，所以 pipeline 至今也没有被普及应用，而 HTTP/2 做到了真正的并发请求。同时，流还支持优先级和流量控制。当流并发时，就会涉及到流的优先级和依赖。即：HTTP2.0对于同一域名下所有请求都是基于流的，不管对于同一域名访问多少文件，也只建立一路连接。优先级高的流会被优先发送。图片请求的优先级要低于 CSS 和 SCRIPT，这个设计可以确保重要的东西可以被优先加载完&lt;/li&gt;&lt;/ul&gt;
 &lt;h4&gt;流量控制&lt;/h4&gt;
 &lt;ul&gt;  &lt;li&gt;TCP协议通过sliding window的算法来做流量控制。发送方有个sending window，接收方有receive window。http2.0的flow control是类似receive window的做法，数据的接收方通过告知对方自己的flow window大小表明自己还能接收多少数据。只有Data类型的frame才有flow control的功能。对于flow control，如果接收方在flow window为零的情况下依然更多的frame，则会返回block类型的frame，这张场景一般表明http2.0的部署出了问题。&lt;/li&gt;&lt;/ul&gt;
 &lt;h4&gt;服务器端推送&lt;/h4&gt;
 &lt;ul&gt;  &lt;li&gt;服务器端的推送，就是服务器可以对一个客户端请求发送多个响应。除了对最初请求的响应外，服务器还可以额外向客户端推送资源，而无需客户端明确地请求。当浏览器请求一个html，服务器其实大概知道你是接下来要请求资源了，而不需要等待浏览器得到html后解析页面再发送资源请求。&lt;/li&gt;&lt;/ul&gt;
 &lt;h4&gt;首部压缩&lt;/h4&gt;
 &lt;ul&gt;
  &lt;li&gt;HTTP 2.0 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对，对于相同的数据，不再通过每次请求和响应发送;通信期间几乎不会改变的通用键-值对(用户代理、可接受的媒体类型,等等)只 需发送一次。事实上,如果请求中不包含首部(例如对同一资源的轮询请求),那么 首部开销就是零字节。此时所有首部都自动使用之前请求发送的首部。&lt;/li&gt;
  &lt;li&gt;如果首部发生变化了，那么只需要发送变化了数据在Headers帧里面，新增或修改的首部帧会被追加到“首部表”。首部表在 HTTP 2.0 的连接存续期内始终存在,由客户端和服务器共同渐进地更新 。&lt;/li&gt;
  &lt;li&gt;本质上，当然是为了减少请求啦，通过多个js或css合并成一个文件，多张小图片拼合成Sprite图，可以让多个HTTP请求减少为一个，减少额外的协议开销，而提升性能。当然，一个HTTP的请求的body太大也是不合理的，有个度。文件的合并也会牺牲模块化和缓存粒度，可以把“稳定”的代码or 小图 合并为一个文件or一张Sprite，让其充分地缓存起来，从而区分开迭代快的文件。&lt;/li&gt;
&lt;/ul&gt;
 &lt;blockquote&gt;
  &lt;code&gt;Demo&lt;/code&gt;的性能对比：&lt;/blockquote&gt;
 &lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbvCVH?w=1700&amp;h=938" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h2&gt;
  &lt;code&gt;Http&lt;/code&gt;的那些致命缺陷，并没有完全解决，于是有了  &lt;code&gt;https&lt;/code&gt;，也是目前应用最广的协议之一&lt;/h2&gt;
 &lt;h3&gt;
  &lt;code&gt;HTTP+ 加密 + 认证 + 完整性保护 =HTTPS &lt;/code&gt; ?&lt;/h3&gt;
 &lt;h4&gt;可以这样认为～HTTP 加上加密处理和认证以及完整性保护后即是 HTTPS&lt;/h4&gt;
 &lt;ul&gt;
  &lt;li&gt;如果在 HTTP 协议通信过程中使用未经加密的明文，比如在 Web 页面中输入信用卡号，如果这条通信线路遭到窃听，那么信用卡号就暴露了。&lt;/li&gt;
  &lt;li&gt;另外，对于 HTTP 来说，服务器也好，客户端也好，都是没有办法确认通信方的。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;因为很有可能并不是和原本预想的通信方在实际通信。并且还需要考虑到接收到的报文在通信途中已经遭到篡改这一可能性。&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;为了统一解决上述这些问题，需要在 HTTP 上再加入加密处理和认证等机制。我们把添加了加密及认证机制的 HTTP 称为 HTTPS&lt;/li&gt;&lt;/ul&gt;
 &lt;blockquote&gt;不加密的重要内容被  &lt;code&gt;wireshark&lt;/code&gt;这类工具抓到包，后果很严重～&lt;/blockquote&gt;
 &lt;h3&gt;HTTPS 是身披 SSL 外壳的 HTTP&lt;/h3&gt;
 &lt;ul&gt;  &lt;li&gt;HTTPS 并非是应用层的一种新协议。只是 HTTP 通信接口部分用 SSL（SecureSocket Layer）和 TLS（Transport Layer Security）协议代替而已。&lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;通常，HTTP 直接和 TCP 通信。&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;当使用 SSL 时，则演变成先和 SSL 通信，再由 SSL和 TCP 通信了。简言之，所谓 HTTPS，其实就是身披 SSL 协议这层外壳的HTTP。&lt;/li&gt;
  &lt;li&gt;在采用 SSL 后，HTTP 就拥有了 HTTPS 的加密、证书和完整性保护这些功能。SSL 是独立于 HTTP 的协议，所以不光是 HTTP 协议，其他运行在应用层的 SMTP和 Telnet 等协议均可配合 SSL 协议使用。可以说 SSL 是当今世界上应用最为广泛的网络安全术。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbvCVI?w=1736&amp;h=740" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h3&gt;相互交换密钥的公开密钥加密技术 -----对称加密&lt;/h3&gt;
 &lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbvCVM?w=1720&amp;h=1310" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;在对 SSL 进行讲解之前，我们先来了解一下加密方法。SSL 采用一种叫做公开密钥加密（Public-key cryptography）的加密处理方式。&lt;/li&gt;
  &lt;li&gt;近代的加密方法中加密算法是公开的，而密钥却是保密的。通过这种方式得以保持加密方法的安全性。&lt;/li&gt;
&lt;/ul&gt;
 &lt;blockquote&gt;加密和解密都会用到密钥。没有密钥就无法对密码解密，反过来说，任何人只要持有密钥就能解密了。如果密钥被攻击者获得，那加密也就失去了意义。&lt;/blockquote&gt;
 &lt;ul&gt;  &lt;li&gt;
   &lt;a href="https://blog.csdn.net/ituling/article/details/52541585" rel="nofollow noreferrer"&gt;https://blog.csdn.net/ituling...&lt;/a&gt;，    &lt;code&gt;Https&lt;/code&gt;加密篇幅太长，这篇文章写得很好，大家可以去看看。&lt;/li&gt;&lt;/ul&gt;
 &lt;h4&gt;HTTPS 采用混合加密机制&lt;/h4&gt;
 &lt;ul&gt;
  &lt;li&gt;HTTPS 采用共享密钥加密和公开密钥加密两者并用的混合加密机制。&lt;/li&gt;
  &lt;li&gt;但是公开密钥加密与共享密钥加密相比，其处理速度要慢。所以应充分利用两者各自的优势，将多种方法组合起来用于通信。在交换密钥环节使用公开密钥加密方式，之后的建立通信交换报文阶段则使用共享密钥加密方式。&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;
  &lt;code&gt;HTTPS&lt;/code&gt;虽好，非对称加密虽好，但是不要滥用&lt;/h2&gt;
 &lt;h3&gt;HTTPS 也存在一些问题，那就是当使用 SSL 时，它的处理速度会变慢。&lt;/h3&gt;
 &lt;h4&gt;SSL 的慢分两种。一种是指通信慢。另一种是指由于大量消耗 CPU 及内存等资源，导致处理速度变慢。&lt;/h4&gt;
 &lt;ul&gt;
  &lt;li&gt;和使用 HTTP 相比，网络负载可能会变慢 2 到 100 倍。除去和 TCP 连接、发送 HTTP 请求 ? 响应以外，还必须进行 SSL 通信，因此整体上处理通信量不可避免会增加。&lt;/li&gt;
  &lt;li&gt;另一点是 SSL 必须进行加密处理。在服务器和客户端都需要进行加密和解密的运算处理。因此从结果上讲，比起 HTTP 会更多地消耗服务器和客户端的硬件资源，导致负载增强。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;针对速度变慢这一问题，并没有根本性的解决方案，我们会使用 SSL 加速器这种（专用服务器）硬件来改善该问题。该硬件为 SSL 通信专用硬件，相对软件来讲，能够提高数倍 SSL 的计算速度。仅在 SSL 处理时发挥 SSL加速器的功效，以分担负载。&lt;/p&gt;
 &lt;h2&gt;为什么不一直使用 HTTPS&lt;/h2&gt;
 &lt;ul&gt;  &lt;li&gt;既然 HTTPS 那么安全可靠，那为何所有的 Web 网站不一直使用 HTTPS？&lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;其中一个原因是，因为与纯文本通信相比，加密通信会消耗更多的 CPU 及内存资源。如果每次通信都加密，会消耗相当多的资源，平摊到一台计算机上时，能够处理的请求数量必定也会随之减少。&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;因此，如果是非敏感信息则使用 HTTP 通信，只有在包含个人信息等敏感数据时，才利用 HTTPS 加密通信。&lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;特别是每当那些访问量较多的 Web 网站在进行加密处理时，它们所承担着的负载不容小觑。在进行加密处理时，并非对所有内容都进行加密处理，而是仅在那些需要信息隐藏时才会加密，以节约资源。&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;除此之外，想要节约购买证书的开销也是原因之一。&lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;要进行 HTTPS 通信，证书是必不可少的。而使用的证书必须向认证机构（CA）购买。证书价格可能会根据不同的认证机构略有不同。通常，一年的授权需要数万日元（现在一万日元大约折合 600 人民币）。那些购买证书并不合算的服务以及一些个人网站，可能只会选择采用HTTP 的通信方式。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbvCVR?w=1158&amp;h=1002" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h2&gt;复习完了基本的协议，介绍下报文格式：&lt;/h2&gt;
 &lt;ul&gt;  &lt;li&gt;请求报文格式&lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbvCVT?w=1728&amp;h=852" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;响应报文格式&lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbvCVU?w=1614&amp;h=690" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;blockquote&gt;所谓响应头，请求头，其实都可以自己添加字段，只要前后端给对应的处理机制即可&lt;/blockquote&gt;
 &lt;h2&gt;
  &lt;code&gt;Node.js&lt;/code&gt;代码实现响应头的设置&lt;/h2&gt;
 &lt;pre&gt;  &lt;code&gt;
  if (config.cache.expires) {
                        res.setHeader(&amp;quot;expries&amp;quot;, new Date(Date.now() + (config.cache.maxAge * 1000)))
                    }
                    if (config.cache.lastModified) {
                        res.setHeader(&amp;quot;last-modified&amp;quot;, stat.mtime.toUTCString())
                    }
                    if (config.cache.etag) {
                        res.setHeader(&amp;apos;Etag&amp;apos;, etagFn(stat))
                    }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;h2&gt;响应头的详解：&lt;/h2&gt;
 &lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbvCVW?w=1760&amp;h=1426" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h3&gt;本人的开源项目，手写的  &lt;code&gt;Node.js&lt;/code&gt;静态资源服务器，  &lt;a href="https://github.com/JinJieTan/util-static-server" rel="nofollow noreferrer"&gt;https://github.com/JinJieTan/...&lt;/a&gt;，欢迎   &lt;code&gt;star&lt;/code&gt;~&lt;/h3&gt;
 &lt;h2&gt;浏览器的缓存策略：&lt;/h2&gt;
 &lt;ul&gt;  &lt;li&gt;首次请求：&lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbvCVX?w=1642&amp;h=1088" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;非首次请求：&lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbvCVZ?w=1528&amp;h=1316" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;用户行为与缓存：&lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbvCV0?w=1606&amp;h=1374" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h2&gt;不能缓存的请求：&lt;/h2&gt;
 &lt;h3&gt;无法被浏览器缓存的请求如下：&lt;/h3&gt;
 &lt;ul&gt;
  &lt;li&gt;HTTP信息头中包含Cache-Control:no-cache，pragma:no-cache（HTTP1.0），或Cache-Control:max-age=0等告诉浏览器不用缓存的请求&lt;/li&gt;
  &lt;li&gt;需要根据Cookie，认证信息等决定输入内容的动态请求是不能被缓存的&lt;/li&gt;
  &lt;li&gt;经过HTTPS安全加密的请求（有人也经过测试发现，ie其实在头部加入Cache-Control：max-age信息，firefox在头部加入Cache-Control:Public之后，能够对HTTPS的资源进行缓寸）&lt;/li&gt;
  &lt;li&gt;经过HTTPS安全加密的请求（有人也经过测试发现，ie其实在头部加入Cache-Control：max-age信息，firefox在头部加入Cache-Control:Public之后，能够对HTTPS的资源进行缓存，参考《HTTPS的七个误解》）&lt;/li&gt;
  &lt;li&gt;POST请求无法被缓存&lt;/li&gt;
  &lt;li&gt;HTTP响应头中不包含Last-Modified/Etag，也不包含Cache-Control/Expires的请求无法被缓存&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;即时通讯协议&lt;/h2&gt;
 &lt;h3&gt;从最初的没有  &lt;code&gt;websocket&lt;/code&gt;协议开始：&lt;/h3&gt;
 &lt;blockquote&gt;传统的协议无法服务端主动  &lt;code&gt;push&lt;/code&gt;数据，于是有了这些骚操作：&lt;/blockquote&gt;
 &lt;ul&gt;
  &lt;li&gt;轮询，在一个定时器中不停向服务端发送请求。&lt;/li&gt;
  &lt;li&gt;长轮询，发送请求给服务端，直到服务端觉得可以返回数据了再返回响应，否则这个请求一直挂起～&lt;/li&gt;
  &lt;li&gt;以上两种都有瑕疵，而且比较明显，这里不再描述。&lt;/li&gt;
&lt;/ul&gt;
 &lt;h3&gt;为了解决实时通讯，数据同步的问题，出现了  &lt;code&gt;webSocket&lt;/code&gt;.&lt;/h3&gt;
 &lt;ul&gt;
  &lt;li&gt;
   &lt;code&gt;webSockets&lt;/code&gt;的目标是在一个单独的持久连接上提供全双工、双向通信。在Javascript创建了Web Socket之后，会有一个HTTP请求发送到浏览器以发起连接。在取得服务器响应后，建立的连接会将HTTP升级从HTTP协议交换为WebSocket协议。&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;webSocket&lt;/code&gt;原理： 在   &lt;code&gt;TCP&lt;/code&gt;连接第一次握手的时候，升级为   &lt;code&gt;ws&lt;/code&gt;协议。后面的数据交互都复用这个   &lt;code&gt;TCP&lt;/code&gt;通道。&lt;/li&gt;
  &lt;li&gt;客户端代码实现：&lt;/li&gt;
&lt;/ul&gt;
 &lt;pre&gt;  &lt;code&gt;  const ws = new WebSocket(&amp;apos;ws://localhost:8080&amp;apos;);
        ws.onopen = function () {
            ws.send(&amp;apos;123&amp;apos;)
            console.log(&amp;apos;open&amp;apos;)
        }
        ws.onmessage = function () {
            console.log(&amp;apos;onmessage&amp;apos;)
        }
        ws.onerror = function () {
            console.log(&amp;apos;onerror&amp;apos;)
        }
        ws.onclose = function () {
            console.log(&amp;apos;onclose&amp;apos;)
        }&lt;/code&gt;&lt;/pre&gt;
 &lt;ul&gt;  &lt;li&gt;服务端使用    &lt;code&gt;Node.js&lt;/code&gt;语言实现&lt;/li&gt;&lt;/ul&gt;
 &lt;pre&gt;  &lt;code&gt;const express = require(&amp;apos;express&amp;apos;)
const { Server } = require(&amp;quot;ws&amp;quot;);
const app = express()
const wsServer = new Server({ port: 8080 })
wsServer.on(&amp;apos;connection&amp;apos;, (ws) =&amp;gt; {
    ws.onopen = function () {
        console.log(&amp;apos;open&amp;apos;)
    }
    ws.onmessage = function (data) {
        console.log(data)
        ws.send(&amp;apos;234&amp;apos;)
        console.log(&amp;apos;onmessage&amp;apos; + data)
    }
    ws.onerror = function () {
        console.log(&amp;apos;onerror&amp;apos;)
    }
    ws.onclose = function () {
        console.log(&amp;apos;onclose&amp;apos;)
    }
});

app.listen(8000, (err) =&amp;gt; {
    if (!err) { console.log(&amp;apos;监听OK&amp;apos;) } else {
        console.log(&amp;apos;监听失败&amp;apos;)
    }
})&lt;/code&gt;&lt;/pre&gt;
 &lt;h2&gt;
  &lt;code&gt;webSocket&lt;/code&gt;的报文格式有一些不一样：&lt;/h2&gt;
 &lt;p&gt;![图片上传中...]&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;
   &lt;p&gt;客户端和服务端进行Websocket消息传递是这样的:&lt;/p&gt;
   &lt;ul&gt;
    &lt;li&gt;客户端：将消息切割成多个帧，并发送给服务端。&lt;/li&gt;
    &lt;li&gt;服务端：接收消息帧，并将关联的帧重新组装成完整的消息。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;
 &lt;h2&gt;即时通讯的心跳检测：&lt;/h2&gt;
 &lt;h3&gt;
  &lt;code&gt;ping&lt;/code&gt;and  &lt;code&gt;pong&lt;/code&gt;
&lt;/h3&gt;
 &lt;ul&gt;  &lt;li&gt;服务端   &lt;code&gt;Go&lt;/code&gt;实现：&lt;/li&gt;&lt;/ul&gt;
 &lt;pre&gt;  &lt;code&gt;package main

import (
    &amp;quot;net/http&amp;quot;
    &amp;quot;time&amp;quot;

    &amp;quot;github.com/gorilla/websocket&amp;quot;
)

var (
    //完成握手操作
    upgrade = websocket.Upgrader{
       //允许跨域(一般来讲,websocket都是独立部署的)
       CheckOrigin:func(r *http.Request) bool {
            return true
       },
    }
)

func wsHandler(w http.ResponseWriter, r *http.Request) {
   var (
         conn *websocket.Conn
         err error
         data []byte
   )
   //服务端对客户端的http请求(升级为websocket协议)进行应答，应答之后，协议升级为websocket，http建立连接时的tcp三次握手将保持。
   if conn, err = upgrade.Upgrade(w, r, nil); err != nil {
        return
   }

    //启动一个协程，每隔5s向客户端发送一次心跳消息
    go func() {
        var (
            err error
        )
        for {
            if err = conn.WriteMessage(websocket.TextMessage, []byte(&amp;quot;heartbeat&amp;quot;)); err != nil {
                return
            }
            time.Sleep(5 * time.Second)
        }
    }()

   //得到websocket的长链接之后,就可以对客户端传递的数据进行操作了
   for {
         //通过websocket长链接读到的数据可以是text文本数据，也可以是二进制Binary
        if _, data, err = conn.ReadMessage(); err != nil {
            goto ERR
     }
     if err = conn.WriteMessage(websocket.TextMessage, data); err != nil {
         goto ERR
     }
   }
ERR:
    //出错之后，关闭socket连接
    conn.Close()
}

func main() {
    http.HandleFunc(&amp;quot;/ws&amp;quot;, wsHandler)
    http.ListenAndServe(&amp;quot;0.0.0.0:7777&amp;quot;, nil)
}&lt;/code&gt;&lt;/pre&gt;
 &lt;h3&gt;客户端的心跳检测(  &lt;code&gt;Node.js&lt;/code&gt;实现)：&lt;/h3&gt;
 &lt;pre&gt;  &lt;code&gt;this.heartTimer = setInterval(() =&amp;gt; {
      if (this.heartbeatLoss &amp;lt; MAXLOSSTIMES) {
        events.emit(&amp;apos;network&amp;apos;, &amp;apos;sendHeart&amp;apos;);
        this.heartbeatLoss += 1;
        this.phoneLoss += 1;
      } else {
        events.emit(&amp;apos;network&amp;apos;, &amp;apos;offline&amp;apos;);
        this.stop();
      }
      if (this.phoneLoss &amp;gt; MAXLOSSTIMES) {
        this.PhoneLive = false;
        events.emit(&amp;apos;network&amp;apos;, &amp;apos;phoneDisconnect&amp;apos;);
      }
    }, 5000);
&lt;/code&gt;&lt;/pre&gt;
 &lt;h2&gt;自定义即时通信协议：&lt;/h2&gt;
 &lt;h3&gt;从  &lt;code&gt;new Socket&lt;/code&gt;开始：&lt;/h3&gt;
 &lt;ul&gt;
  &lt;li&gt;目前即时通讯大都使用现有大公司成熟的   &lt;code&gt;SDK&lt;/code&gt;接入，但是逼格高些还是自己重写比较好。&lt;/li&gt;
  &lt;li&gt;打个小广告，我们公司就是自己定义的即时通讯协议～招聘一位高级前端，地点深圳-深南大道，做跨平台   &lt;code&gt;IM&lt;/code&gt;桌面应用开发的～&lt;/li&gt;
  &lt;li&gt;客户端代码实现（Node.js）:&lt;/li&gt;
&lt;/ul&gt;
 &lt;pre&gt;  &lt;code&gt;
const {Socket} = require(&amp;apos;net&amp;apos;) 
const tcp = new Socket()
tcp.setKeepAlive(true);
tcp.setNoDelay(true);
//保持底层tcp链接不断，长连接
指定对应域名端口号链接
tcp.connect(80,166.166.0.0)
建立连接后
根据后端传送的数据类型 使用对应不同的解析
readUInt8 readUInt16LE readUInt32LE readIntLE等处理后得到myBuf 
const myBuf = buffer.slice(start);//从对应的指针开始的位置截取buffer
const header = myBuf.slice(headstart,headend)//截取对应的头部buffer
const body = JSON.parse(myBuf.slice(headend-headstart,bodylength).tostring())
//精确截取数据体的buffer,并且转化成js对象&lt;/code&gt;&lt;/pre&gt;
 &lt;blockquote&gt;即时通讯强烈推荐使用  &lt;code&gt;Golang&lt;/code&gt;,  &lt;code&gt;GRPC&lt;/code&gt;,  &lt;code&gt;Prob&lt;/code&gt;传输数据。&lt;/blockquote&gt;
 &lt;h2&gt;上面的一些代码，都在我的开源项目中：&lt;/h2&gt;
 &lt;ul&gt;
  &lt;li&gt;手写的静态资源服务器,   &lt;a href="https://github.com/JinJieTan/util-static-server" rel="nofollow noreferrer"&gt;https://github.com/JinJieTan/...&lt;/a&gt;
&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;webpack-electron-react-websocket&lt;/code&gt;的Demo,    &lt;a href="https://github.com/JinJieTan/react-electron-webpack" rel="nofollow noreferrer"&gt;https://github.com/JinJieTan/...&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
 &lt;blockquote&gt;觉得写得不错，可以点个赞支持下，文章也借鉴了一下其他大佬的文章，但是地址都贴上来了～ 欢迎  &lt;code&gt;gitHub&lt;/code&gt;点个  &lt;code&gt;star&lt;/code&gt;哦～&lt;/blockquote&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>html5 html css node.js javascript</category>
      <guid isPermaLink="true">https://itindex.net/detail/59874-%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE-%E7%B2%BE%E8%AF%BB</guid>
      <pubDate>Sat, 27 Jul 2019 13:07:04 CST</pubDate>
    </item>
    <item>
      <title>使用Node.js爬取任意网页资源并输出高质量PDF文件到本地~</title>
      <link>https://itindex.net/detail/59698-node-js-%E7%BD%91%E9%A1%B5</link>
      <description>&lt;p&gt;  &lt;img alt="detail?ct=503316480&amp;z=0&amp;ipn=d&amp;word=%E6%B5%B7%E8%BE%B9%E5%A3%81%E7%BA%B8&amp;hs=2&amp;pn=0&amp;spn=0&amp;di=10120&amp;pi=0&amp;rn=1&amp;tn=baiduimagedetail&amp;is=0%2C0&amp;ie=utf-8&amp;oe=utf-8&amp;cl=2&amp;lm=-1&amp;cs=3590237416%2C2845421745&amp;os=3026828862%2C3835093178&amp;simid=0%2C0&amp;adpicid=0&amp;lpn=0&amp;ln=30&amp;fr=ala&amp;fm=&amp;sme=&amp;cg=&amp;bdtype=0&amp;oriquery=%E6%B5%B7%E8%BE%B9%E5%A3%81%E7%BA%B8&amp;objurl=http%3A%2F%2Fabc.2008php.com%2F2017_Website_appreciate%2F2017-10-09%2F20171009204205.jpg&amp;fromurl=ippr_z2C%24qAzdH3FAzdH3Fwkv_z%26e3Bdaabrir_z%26e3Bv54AzdH3Fp7h7AzdH3Fda80AzdH3F8aalAzdH3Flcblld_z%26e3Bip4s&amp;gsm=0&amp;islist=&amp;querylist=" src="https://segmentfault.com/img/bVbtVeV?w=3840&amp;h=2160" title="detail?ct=503316480&amp;z=0&amp;ipn=d&amp;word=%E6%B5%B7%E8%BE%B9%E5%A3%81%E7%BA%B8&amp;hs=2&amp;pn=0&amp;spn=0&amp;di=10120&amp;pi=0&amp;rn=1&amp;tn=baiduimagedetail&amp;is=0%2C0&amp;ie=utf-8&amp;oe=utf-8&amp;cl=2&amp;lm=-1&amp;cs=3590237416%2C2845421745&amp;os=3026828862%2C3835093178&amp;simid=0%2C0&amp;adpicid=0&amp;lpn=0&amp;ln=30&amp;fr=ala&amp;fm=&amp;sme=&amp;cg=&amp;bdtype=0&amp;oriquery=%E6%B5%B7%E8%BE%B9%E5%A3%81%E7%BA%B8&amp;objurl=http%3A%2F%2Fabc.2008php.com%2F2017_Website_appreciate%2F2017-10-09%2F20171009204205.jpg&amp;fromurl=ippr_z2C%24qAzdH3FAzdH3Fwkv_z%26e3Bdaabrir_z%26e3Bv54AzdH3Fp7h7AzdH3Fda80AzdH3F8aalAzdH3Flcblld_z%26e3Bip4s&amp;gsm=0&amp;islist=&amp;querylist="&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;blockquote&gt;本文适合无论是否有爬虫以及  &lt;code&gt;Node.js&lt;/code&gt;基础的朋友观看~&lt;/blockquote&gt;
 &lt;h5&gt;需求：&lt;/h5&gt;
 &lt;ul&gt;
  &lt;li&gt;使用   &lt;code&gt;Node.js&lt;/code&gt;爬取网页资源，开箱即用的配置&lt;/li&gt;
  &lt;li&gt;将爬取到的网页内容以   &lt;code&gt;PDF&lt;/code&gt;格式输出&lt;/li&gt;
&lt;/ul&gt;
 &lt;h5&gt;如果你是一名技术人员，那么可以看我接下来的文章，否则，请直接移步到我的  &lt;code&gt;github&lt;/code&gt;仓库，直接看文档使用即可&lt;/h5&gt;
 &lt;h4&gt;仓库地址:  &lt;a href="https://github.com/JinJieTan/puppeteer-pdf" rel="nofollow noreferrer"&gt;附带文档和源码&lt;/a&gt;,别忘了给个  &lt;code&gt;star&lt;/code&gt;哦&lt;/h4&gt;
 &lt;h4&gt;本需求使用到的技术：  &lt;code&gt;Node.js&lt;/code&gt;和  &lt;code&gt;puppeteer&lt;/code&gt;
&lt;/h4&gt;
 &lt;ul&gt;
  &lt;li&gt;
   &lt;code&gt;puppeteer&lt;/code&gt; 官网地址:    &lt;a href="https://zhaoqize.github.io/puppeteer-api-zh_CN/#/" rel="nofollow noreferrer"&gt;puppeteer地址&lt;/a&gt;
&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;Node.js&lt;/code&gt;官网地址:   &lt;a href="http://nodejs.cn/" rel="nofollow noreferrer"&gt;链接描述&lt;/a&gt;
&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;Puppeteer&lt;/code&gt;是谷歌官方出品的一个通过   &lt;code&gt;DevTools&lt;/code&gt;协议控制   &lt;code&gt;headless Chrome&lt;/code&gt;的   &lt;code&gt;Node&lt;/code&gt;库。可以通过Puppeteer的提供的api直接控制Chrome模拟大部分用户操作来进行UI Test或者作为爬虫访问页面来收集数据。&lt;/li&gt;
  &lt;li&gt;环境和安装&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;Puppeteer&lt;/code&gt;本身依赖6.4以上的Node，但是为了异步超级好用的   &lt;code&gt;async/await&lt;/code&gt;，推荐使用7.6版本以上的Node。另外headless Chrome本身对服务器依赖的库的版本要求比较高，centos服务器依赖偏稳定，v6很难使用headless Chrome，提升依赖版本可能出现各种服务器问题（包括且不限于无法使用ssh），最好使用高版本服务器。（建议使用最新版本的   &lt;code&gt;Node.js&lt;/code&gt;）&lt;/li&gt;
&lt;/ul&gt;
 &lt;h4&gt;小试牛刀，爬取京东资源&lt;/h4&gt;
 &lt;pre&gt;  &lt;code&gt;const puppeteer = require(&amp;apos;puppeteer&amp;apos;); //  引入依赖  
(async () =&amp;gt; {   //使用async函数完美异步 
    const browser = await puppeteer.launch();  //打开新的浏览器
    const page = await browser.newPage();   // 打开新的网页 
    await page.goto(&amp;apos;https://www.jd.com/&amp;apos;);  //前往里面 &amp;apos;url&amp;apos; 的网页
    const result = await page.evaluate(() =&amp;gt; {   //这个result数组包含所有的图片src地址
        let arr = []; //这个箭头函数内部写处理的逻辑  
        const imgs = document.querySelectorAll(&amp;apos;img&amp;apos;);
        imgs.forEach(function (item) {
            arr.push(item.src)
        })
        return arr 
    });
    // &amp;apos;此时的result就是得到的爬虫数据，可以通过&amp;apos;fs&amp;apos;模块保存&amp;apos;
})()

  复制过去 使用命令行命令 ` node 文件名 ` 就可以运行获取爬虫数据了 
这个 puppeteer 的包 ，其实是替我们开启了另一个浏览器，重新去开启网页，获取它们的数据。
&lt;/code&gt;&lt;/pre&gt;
 &lt;ul&gt;  &lt;li&gt;上面只爬取了京东首页的图片内容，假设我的需求进一步扩大，需要爬取京东首页&lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;中的所有  &lt;code&gt;&amp;lt;a&amp;gt; 标签对应的跳转网页中的所有 title的文字内容，最后放到一个数组中&lt;/code&gt;。&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;我们的   &lt;code&gt;async&lt;/code&gt;函数上面一共分了五步， 只有    &lt;code&gt;puppeteer.launch()&lt;/code&gt; ,&lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;  &lt;code&gt;browser.newPage()&lt;/code&gt;,   &lt;code&gt; browser.close()&lt;/code&gt; 是固定的写法。&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;
   &lt;code&gt; page.goto&lt;/code&gt; 指定我们去哪个网页爬取数据，可以更换内部url地址，也可以多次&lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;调用这个方法。&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;
   &lt;code&gt; page.evaluate&lt;/code&gt; 这个函数，内部是处理我们进入想要爬取网页的数据逻辑&lt;/li&gt;&lt;/ul&gt;
 &lt;ul&gt;  &lt;li&gt;
   &lt;code&gt;page.goto&lt;/code&gt;和   &lt;code&gt; page.evaluate&lt;/code&gt;两个方法，可以在   &lt;code&gt;async&lt;/code&gt;内部调用多次，&lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;那意味着我们可以先进入京东网页，处理逻辑后，再次调用  &lt;code&gt;page.goto&lt;/code&gt;这个函数，&lt;/p&gt;
 &lt;blockquote&gt;注意，上面这一切逻辑，都是  &lt;code&gt;puppeteer&lt;/code&gt;这个包帮我们在看不见的地方开启了另外一个  &lt;br /&gt;浏览器，然后处理逻辑，所以最终要调用  &lt;code&gt;browser.close()&lt;/code&gt;方法关闭那个浏览器。&lt;/blockquote&gt;
 &lt;p&gt;这时候我们对上一篇的代码进行优化，爬取对应的资源。&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt; const puppeteer = require(&amp;apos;puppeteer&amp;apos;);
(async () =&amp;gt; {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto(&amp;apos;https://www.jd.com/&amp;apos;);
    const hrefArr = await page.evaluate(() =&amp;gt; {
        let arr = [];
        const aNodes = document.querySelectorAll(&amp;apos;.cate_menu_lk&amp;apos;);
        aNodes.forEach(function (item) {
            arr.push(item.href)
        })
        return arr
    });
    let arr = [];
    for (let i = 0; i &amp;lt; hrefArr.length; i++) {
        const url = hrefArr[i];
        console.log(url) //这里可以打印 
        await page.goto(url);
        const result = await page.evaluate(() =&amp;gt; { //这个方法内部console.log无效 
            
              return  $(&amp;apos;title&amp;apos;).text();  //返回每个界面的title文字内容
        });
        arr.push(result)  //每次循环给数组中添加对应的值
    }
    console.log(arr)  //得到对应的数据  可以通过Node.js的 fs 模块保存到本地
    await browser.close()
})()
&lt;/code&gt;&lt;/pre&gt;
 &lt;blockquote&gt;上面有天坑   page.evaluate函数内部的console.log不能打印，而且内部不能获取外部的变量,只能return返回，  &lt;br /&gt;使用的选择器必须先去对应界面的控制台实验过能不能选择DOM再使用，比如京东无法使用querySelector。这里由于  &lt;br /&gt;京东的分界面都使用了jQuery，所以我们可以用jQuery，总之他们开发能用的选择器，我们都可以用，否则就不可以。&lt;/blockquote&gt;
 &lt;h4&gt;接下来我们直接来爬取  &lt;code&gt;Node.js&lt;/code&gt;的官网首页然后直接生成  &lt;code&gt;PDF&lt;/code&gt;
&lt;/h4&gt;
 &lt;h5&gt;无论您是否了解Node.js和puppeteer的爬虫的人员都可以操作，请您一定万分仔细阅读本文档并按顺序执行每一步&lt;/h5&gt;
 &lt;blockquote&gt;本项目实现需求：给我们一个网页地址，爬取他的网页内容，然后输出成我们想要的PDF格式文档，请注意，是高质量的PDF文档&lt;/blockquote&gt;
 &lt;ul&gt;
  &lt;li&gt;第一步，安装   &lt;code&gt;Node.js&lt;/code&gt; ,推荐   &lt;code&gt;http://nodejs.cn/download/&lt;/code&gt;，   &lt;code&gt;Node.js&lt;/code&gt;的中文官网下载对应的操作系统包&lt;/li&gt;
  &lt;li&gt;第二步，在下载安装完了   &lt;code&gt;Node.js&lt;/code&gt;后， 启动   &lt;code&gt;windows&lt;/code&gt;命令行工具(windows下启动系统搜索功能，输入cmd，回车，就出来了)&lt;/li&gt;
  &lt;li&gt;第三步 需要查看环境变量是否已经自动配置,在命令行工具中输入    &lt;code&gt;node -v&lt;/code&gt;，如果出现    &lt;code&gt;v10. ***&lt;/code&gt;字段，则说明成功安装   &lt;code&gt;Node.js&lt;/code&gt;
&lt;/li&gt;
  &lt;li&gt;第四步 如果您在第三步发现输入   &lt;code&gt;node -v&lt;/code&gt;还是没有出现 对应的字段，那么请您重启电脑即可&lt;/li&gt;
  &lt;li&gt;第五步 打开本项目文件夹，打开命令行工具（windows系统中直接在文件的   &lt;code&gt;url&lt;/code&gt;地址栏输入   &lt;code&gt;cmd&lt;/code&gt;就可以打开了），输入    &lt;code&gt;npm i cnpm  nodemon -g &lt;/code&gt;
&lt;/li&gt;
  &lt;li&gt;第六步 下载   &lt;code&gt;puppeteer&lt;/code&gt;爬虫包，在完成第五步后，使用   &lt;code&gt;cnpm i puppeteer --save &lt;/code&gt;命令 即可下载&lt;/li&gt;
  &lt;li&gt;第七步 完成第六步下载后，打开本项目的   &lt;code&gt;url.js&lt;/code&gt;，将您需要爬虫爬取的网页地址替换上去(默认是   &lt;code&gt;http://nodejs.cn/&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;第八步 在命令行中输入    &lt;code&gt;nodemon index.js&lt;/code&gt; 即可爬取对应的内容，并且自动输出到当前文件夹下面的   &lt;code&gt;index.pdf&lt;/code&gt;文件中&lt;/li&gt;
&lt;/ul&gt;
 &lt;blockquote&gt;
  &lt;code&gt;TIPS&lt;/code&gt;: 本项目设计思想就是一个网页一个  &lt;code&gt;PDF&lt;/code&gt;文件，所以每次爬取一个单独页面后，请把  &lt;code&gt;index.pdf&lt;/code&gt;拷贝出去，然后继续更换  &lt;code&gt;url&lt;/code&gt;地址，继续爬取，生成新的  &lt;code&gt;PDF&lt;/code&gt;文件，当然，您也可以通过循环编译等方式去一次性爬取多个网页生成多个  &lt;code&gt;PDF&lt;/code&gt;文件。  &lt;p&gt;对应像京东首页这样的开启了图片懒加载的网页，爬取到的部分内容是   &lt;code&gt;loading&lt;/code&gt;状态的内容，对于有一些反爬虫机制的网页，爬虫也会出现问题，但是绝大多数网站都是可以的&lt;/p&gt;
&lt;/blockquote&gt;
 &lt;pre&gt;  &lt;code&gt;const puppeteer = require(&amp;apos;puppeteer&amp;apos;);
const url = require(&amp;apos;./url&amp;apos;);
(async () =&amp;gt; {
    const browser = await puppeteer.launch({ headless: true })
    const page = await browser.newPage()
    //选择要打开的网页  
    await page.goto(url, { waitUntil: &amp;apos;networkidle0&amp;apos; })
    //选择你要输出的那个PDF文件路径，把爬取到的内容输出到PDF中，必须是存在的PDF，可以是空内容，如果不是空的内容PDF，那么会覆盖内容
    let pdfFilePath = &amp;apos;./index.pdf&amp;apos;;
    //根据你的配置选项，我们这里选择A4纸的规格输出PDF，方便打印
    await page.pdf({
        path: pdfFilePath,
        format: &amp;apos;A4&amp;apos;,
        scale: 1,
        printBackground: true,
        landscape: false,
        displayHeaderFooter: false
    });
    await browser.close()
})()
&lt;/code&gt;&lt;/pre&gt;
 &lt;h4&gt;文件解构设计&lt;/h4&gt;
 &lt;p&gt;  &lt;img alt="clipboard.png" src="https://segmentfault.com/img/bVbtVfj?w=202&amp;h=229" title="clipboard.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;blockquote&gt;数据在这个时代非常珍贵，按照网页的设计逻辑，选定特定的  &lt;code&gt;href&lt;/code&gt;的地址，可以先直接获取对应的资源，也可以通过再次使用   &lt;code&gt; page.goto&lt;/code&gt;方法进入，再调用  &lt;code&gt; page.evaluate()&lt;/code&gt; 处理逻辑，或者输出对应的  &lt;code&gt;PDF&lt;/code&gt;文件，当然也可以一口气输出多个  &lt;code&gt;PDF&lt;/code&gt;文件~  &lt;br /&gt;这里就不做过多介绍了，毕竟  &lt;code&gt; Node.js &lt;/code&gt;是可以上天的，或许未来它真的什么都能做。这么优质简短的教程，请收藏  &lt;br /&gt;或者转发给您的朋友，谢谢。&lt;/blockquote&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>html5 html css node.js javascript</category>
      <guid isPermaLink="true">https://itindex.net/detail/59698-node-js-%E7%BD%91%E9%A1%B5</guid>
      <pubDate>Fri, 14 Jun 2019 23:55:03 CST</pubDate>
    </item>
    <item>
      <title>前端性能优化不完全手册</title>
      <link>https://itindex.net/detail/59441-%E5%89%8D%E7%AB%AF-%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96-%E5%AE%8C%E5%85%A8</link>
      <description>&lt;h4&gt;性能优化是一门大学问，本文仅对个人一些积累知识的阐述，欢迎下面补充。&lt;/h4&gt;
 &lt;blockquote&gt;抛出一个问题，从输入  &lt;code&gt;url&lt;/code&gt;地址栏到所有内容显示到界面上做了哪些事？&lt;/blockquote&gt;
 &lt;ul&gt;
  &lt;li&gt;1.浏览器向   &lt;code&gt; DNS &lt;/code&gt;服务器请求解析该 URL 中的域名所对应的    &lt;code&gt;IP&lt;/code&gt; 地址;&lt;/li&gt;
  &lt;li&gt;2.建立   &lt;code&gt;TCP&lt;/code&gt;连接（三次握手）;&lt;/li&gt;
  &lt;li&gt;3.浏览器发出读取文件(   &lt;code&gt;URL&lt;/code&gt; 中域名后面部分对应的文件)的   &lt;code&gt;HTTP&lt;/code&gt; 请求，该请求报文作为    &lt;code&gt;TCP&lt;/code&gt; 三次握手的第三个报文的数据发送给服务器;&lt;/li&gt;
  &lt;li&gt;4.服务器对浏览器请求作出响应，并把对应的 html 文本发送给浏览器;&lt;/li&gt;
  &lt;li&gt;5.浏览器将该    &lt;code&gt;html&lt;/code&gt; 文本并显示内容;&lt;/li&gt;
  &lt;li&gt;6.释放    &lt;code&gt;TCP&lt;/code&gt;连接（四次挥手）;&lt;/li&gt;
&lt;/ul&gt;
 &lt;blockquote&gt;上面这个问题是一个面试官非常喜欢问的问题，我们下面把这6个步骤分解，逐步细谈优化。&lt;/blockquote&gt;
 &lt;h4&gt;一、  &lt;code&gt;DNS&lt;/code&gt; 解析&lt;/h4&gt;
 &lt;ul&gt;  &lt;li&gt;
   &lt;p&gt;DNS`解析:将域名解析为ip地址 ,由上往下匹配，只要命中便停止&lt;/p&gt;
   &lt;ul&gt;
    &lt;li&gt;走缓存&lt;/li&gt;
    &lt;li&gt;浏览器DNS缓存&lt;/li&gt;
    &lt;li&gt;本机DNS缓存&lt;/li&gt;
    &lt;li&gt;路由器DNS缓存&lt;/li&gt;
    &lt;li&gt;网络运营商服务器DNS缓存 （80%的DNS解析在这完成的）&lt;/li&gt;
    &lt;li&gt;递归查询&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;
 &lt;blockquote&gt;优化策略：尽量允许使用浏览器的缓存，能给我们节省大量时间。&lt;/blockquote&gt;
 &lt;h4&gt;二、  &lt;code&gt;TCP&lt;/code&gt;的三次握手&lt;/h4&gt;
 &lt;ul&gt;  &lt;li&gt;
   &lt;p&gt;SYN （同步序列编号）ACK（确认字符）&lt;/p&gt;
   &lt;ul&gt;
    &lt;li&gt;第一次握手：Client将标志位SYN置为1，随机产生一个值seq=J，并将该数据包发送给Server，Client进入SYN_SENT状态，等 待Server确认。&lt;/li&gt;
    &lt;li&gt;第二次握手：Server收到数据包后由标志位SYN=1知道Client请求建立连接，Server将标志位SYN和ACK都置为1，ack=J+1，随机产生一个值seq=K，并将该数据包发送给Client以确认连接请求，Server进入SYN_RCVD状态。&lt;/li&gt;
    &lt;li&gt;第三次握手：Client收到确认后，检查ack是否为J+1，ACK是否为1，如果正确则将标志位ACK置为1，ack=K+1，并将该数据包发送给Server，Server检查ack是否为K+1，ACK是否为1，如果正确则连接建立成功，Client和Server进入ESTABLISHED状态，完成三次握手，随后Client与Server之间可以开始传输数据了。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;
 &lt;h4&gt;三、浏览器发送请求&lt;/h4&gt;
 &lt;blockquote&gt;优化策略:&lt;/blockquote&gt;
 &lt;li&gt;  &lt;ul&gt;
   &lt;li&gt;1.    &lt;code&gt;HTTP&lt;/code&gt;协议通信最耗费时间的是建立    &lt;code&gt;TCP&lt;/code&gt;连接的过程，那我们就可以使用    &lt;code&gt;HTTP Keep-Alive&lt;/code&gt;，在    &lt;code&gt;HTTP &lt;/code&gt;早期，每个    &lt;code&gt;HTTP &lt;/code&gt;请求都要求打开一个    &lt;code&gt;TCP socket&lt;/code&gt;连接，并且使用一次之后就断开这个    &lt;code&gt;TCP&lt;/code&gt;连接。 使用    &lt;code&gt;keep-alive&lt;/code&gt;可以改善这种状态，即在一次TCP连接中可以持续发送多份数据而不会断开连接。通过使用    &lt;code&gt;keep-alive&lt;/code&gt;机制，可以减少    &lt;code&gt;TCP&lt;/code&gt;连接建立次数，也意味着可以减少    &lt;code&gt;TIME_WAIT&lt;/code&gt;状态连接，以此提高性能和提高    &lt;code&gt;http&lt;/code&gt;服务器的吞吐率(更少的    &lt;code&gt;tcp&lt;/code&gt;连接意味着更少的系统内核调用&lt;/li&gt;
   &lt;li&gt;2.但是，    &lt;code&gt;keep-alive&lt;/code&gt;并不是免费的午餐,长时间的    &lt;code&gt;TCP&lt;/code&gt;连接容易导致系统资源无效占用。配置不当的    &lt;code&gt;keep-alive&lt;/code&gt;，有时比重复利用连接带来的损失还更大。所以，正确地设置    &lt;code&gt;keep-alive timeout&lt;/code&gt;时间非常重要。(这个    &lt;code&gt;keep-alive_timout&lt;/code&gt;时间值意味着：一个    &lt;code&gt;http&lt;/code&gt;产生的    &lt;code&gt;tcp&lt;/code&gt;连接在传送完最后一个响应后，还需要    &lt;code&gt;hold&lt;/code&gt;住    &lt;code&gt;keepalive_timeout&lt;/code&gt;秒后，才开始关闭这个连接)，如果想更详细了解可以看这篇文章    &lt;a href="https://www.cnblogs.com/freefish12/p/5394876.html" rel="nofollow noreferrer"&gt;keep-alve性能优化的测试结果&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
 &lt;ul&gt;
  &lt;li&gt;3.使用   &lt;code&gt;webScoket&lt;/code&gt;通信协议，仅一次   &lt;code&gt;TCP&lt;/code&gt;握手就一直保持连接，而且他对二进制数据的传输有更好的支持，可以应用于即时通信，海量高并发场景。   &lt;a href="https://www.cnblogs.com/fuqiang88/p/5956363.html" rel="nofollow noreferrer"&gt;webSocket的原理以及详解&lt;/a&gt;
&lt;/li&gt;
  &lt;li&gt;4.减少   &lt;code&gt;HTTP&lt;/code&gt;请求次数，每次   &lt;code&gt;HTTP&lt;/code&gt;请求都会有请求头，返回响应都会有响应头，多次请求不仅浪费时间而且会让网络传输很多无效的资源，使用前端模块化技术    &lt;code&gt;AMD CMD commonJS ES6等模块化方案&lt;/code&gt;将多个文件压缩打包成一个，当然也不能都放在一个文件中，因为这样传输起来可能会很慢，权衡取一个中间值&lt;/li&gt;
  &lt;li&gt;5.配置使用懒加载，对于一些用户不立刻使用到的文件到特定的事件触发再请求，也许用户只是想看到你首页上半屏的内容，但是你却请求了整个页面的所有图片，如果用户量很大，那么这是一种极大的浪费&lt;/li&gt;
  &lt;li&gt;6.服务器资源的部署尽量使用同源策略&lt;/li&gt;
&lt;/ul&gt;
 &lt;h4&gt;四、服务器返回响应，浏览器接受到响应数据&lt;/h4&gt;
 &lt;h4&gt;五、浏览器解析数据，绘制渲染页面的过程&lt;/h4&gt;
 &lt;ul&gt;
  &lt;li&gt;先预解析（将需要发送请求的标签的请求发出去）&lt;/li&gt;
  &lt;li&gt;从上到下解析   &lt;code&gt;html&lt;/code&gt;文件&lt;/li&gt;
  &lt;li&gt;遇到HTML标签，调用html解析器将其解析   &lt;code&gt;DOM&lt;/code&gt;树&lt;/li&gt;
  &lt;li&gt;遇到   &lt;code&gt;css&lt;/code&gt;标记，调用css解析器将其解析   &lt;code&gt;CSSOM&lt;/code&gt;树&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;link&lt;/code&gt; 阻塞 - 为了解决闪屏，所有解决闪屏的样式&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;style&lt;/code&gt; 非阻塞，与闪屏的样式不相关的&lt;/li&gt;
  &lt;li&gt;将   &lt;code&gt;DOM&lt;/code&gt;树和   &lt;code&gt;CSSOM&lt;/code&gt;树结合在一起，形成   &lt;code&gt;render&lt;/code&gt;树&lt;/li&gt;
  &lt;li&gt;layout布局 render渲染&lt;/li&gt;
  &lt;li&gt;遇到   &lt;code&gt;script&lt;/code&gt;标签，阻塞，调用   &lt;code&gt;js&lt;/code&gt;解析器解析   &lt;code&gt;js&lt;/code&gt;代码，可能会修改   &lt;code&gt;DOM&lt;/code&gt;树，也可能会修改   &lt;code&gt;CSSOM&lt;/code&gt;树&lt;/li&gt;
  &lt;li&gt;将   &lt;code&gt;DOM&lt;/code&gt;树和   &lt;code&gt;CSSOM&lt;/code&gt;树结合在一起，形成   &lt;code&gt;render&lt;/code&gt;树&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;layout&lt;/code&gt;布局    &lt;code&gt;render&lt;/code&gt;渲染（重排重绘）&lt;/li&gt;
  &lt;li&gt;
   &lt;p&gt;    &lt;code&gt;script&lt;/code&gt;标签的属性&lt;/p&gt;
   &lt;ul&gt;
    &lt;li&gt;async 异步 谁先回来谁就先解析，不阻塞&lt;/li&gt;
    &lt;li&gt;defer 异步 按照先后顺序（defer）解析，不阻塞&lt;/li&gt;
    &lt;li&gt;script标签放在body下，放置多次重排重绘，能够操作dom&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
 &lt;blockquote&gt;性能优化策略：&lt;/blockquote&gt;
 &lt;ul&gt;
  &lt;li&gt;需要阻塞的样式使用   &lt;code&gt;link&lt;/code&gt;引入，不需要的使用   &lt;code&gt;style&lt;/code&gt;标签(具体是否需要阻塞看业务场景)&lt;/li&gt;
  &lt;li&gt;图片比较多的时候，一定要使用懒加载，图片是最需要优化的，   &lt;code&gt;webpack4&lt;/code&gt;中也要配置图片压缩，能极大压缩图片大小，对于新版本浏览器可以使用   &lt;code&gt;webp格式图片&lt;/code&gt;   &lt;a href="https://baike.baidu.com/item/webp%E6%A0%BC%E5%BC%8F/4077671?fr=aladdin" rel="nofollow noreferrer"&gt;webP详解&lt;/a&gt;，图片优化对性能提升最大。&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;webpack4&lt;/code&gt;配置 代码分割，提取公共代码成单独模块。方便缓存&lt;/li&gt;
&lt;/ul&gt;
 &lt;pre&gt;  &lt;code&gt;    /*
    runtimeChunk 设置为 true, webpack 就会把 chunk 文件名全部存到一个单独的 chunk 中，
    这样更新一个文件只会影响到它所在的 chunk 和 runtimeChunk，避免了引用这个 chunk 的文件也发生改变。
    */
    runtimeChunk: true, 
    splitChunks: {
      chunks: &amp;apos;all&amp;apos;  // 默认 entry 的 chunk 不会被拆分, 配置成 all, 就可以了
    }
  }
    //因为是单入口文件配置，所以没有考虑多入口的情况，多入口是应该分别进行处理。&lt;/code&gt;&lt;/pre&gt;
 &lt;ul&gt;
  &lt;li&gt;对于需要事件驱动的   &lt;code&gt;webpack4&lt;/code&gt;配置懒加载的，可以看这篇   &lt;a href="https://segmentfault.com/a/1190000018535749"&gt;webpack4优化教程&lt;/a&gt;,写得非常全面&lt;/li&gt;
  &lt;li&gt;一些原生   &lt;code&gt;javaScript&lt;/code&gt;的   &lt;code&gt;DOM&lt;/code&gt;操作等优化会在下面总结&lt;/li&gt;
&lt;/ul&gt;
 &lt;h4&gt;六、  &lt;code&gt;TCP&lt;/code&gt;的四次挥手，断开连接&lt;/h4&gt;
 &lt;hr&gt;&lt;/hr&gt;
 &lt;h4&gt;终结篇：性能只是 load 时间或者 DOMContentLoaded 时间的问题吗？&lt;/h4&gt;
 &lt;ul&gt;  &lt;li&gt;
   &lt;p&gt;    &lt;code&gt;RAIL&lt;/code&gt;&lt;/p&gt;
   &lt;ul&gt;
    &lt;li&gt;
     &lt;code&gt;Responce&lt;/code&gt; 响应，研究表明，100ms内对用户的输入操作进行响应，通常会被人类认为是立即响应。时间再长，操作与反应之间的连接就会中断，人们就会觉得它的操作有延迟。例如：当用户点击一个按钮，如果100ms内给出响应，那么用户就会觉得响应很及时，不会察觉到丝毫延迟感。&lt;/li&gt;
    &lt;li&gt;
     &lt;code&gt;Animaton&lt;/code&gt; 现如今大多数设备的屏幕刷新频率是60Hz，也就是每秒钟屏幕刷新60次；因此网页动画的运行速度只要达到60FPS，我们就会觉得动画很流畅。&lt;/li&gt;
    &lt;li&gt;
     &lt;code&gt;Idle&lt;/code&gt; RAIL规定，空闲周期内运行的任务不得超过50ms，当然不止RAIL规定，W3C性能工作组的Longtasks标准也规定了超过50毫秒的任务属于长任务，那么50ms这个数字是怎么得来的呢？浏览器是单线程的，这意味着同一时间主线程只能处理一个任务，如果一个任务执行时间过长，浏览器则无法执行其他任务，用户会感觉到浏览器被卡死了，因为他的输入得不到任何响应。为了达到100ms内给出响应，将空闲周期执行的任务限制为50ms意味着，即使用户的输入行为发生在空闲任务刚开始执行，浏览器仍有剩余的50ms时间用来响应用户输入，而不会产生用户可察觉的延迟。&lt;/li&gt;
    &lt;li&gt;
     &lt;code&gt;Load&lt;/code&gt;如果不能在1秒钟内加载网页并让用户看到内容，用户的注意力就会分散。用户会觉得他要做的事情被打断，如果10秒钟还打不开网页，用户会感到失望，会放弃他们想做的事，以后他们或许都不会再回来。&lt;/li&gt;
&lt;/ul&gt;
   &lt;blockquote&gt;如何使网页更丝滑？&lt;/blockquote&gt;
   &lt;ul&gt;
    &lt;li&gt;
     &lt;p&gt;使用requestAnimationFrame&lt;/p&gt;
     &lt;ul&gt;      &lt;li&gt;即便你能保证每一帧的总耗时都小于16ms，也无法保证一定不会出现丢帧的情况，这取决于触发JS执行的方式。假设使用 setTimeout 或 setInterval 来触发JS执行并修改样式从而导致视觉变化；那么会有这样一种情况，因为setTimeout 或 setInterval没有办法保证回调函数什么时候执行，它可能在每一帧的中间执行，也可能在每一帧的最后执行。所以会导致即便我们能保障每一帧的总耗时小于16ms，但是执行的时机如果在每一帧的中间或最后，最后的结果依然是没有办法每隔16ms让屏幕产生一次变化，也就是说，即便我们能保证每一帧总体时间小于16ms，但如果使用定时器触发动画，那么由于定时器的触发时机不确定，所以还是会导致动画丢帧。现在整个Web只有一个API可以解决这个问题，那就是requestAnimationFrame，它可以保证回调函数稳定的在每一帧最开始触发。&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
    &lt;li&gt;
     &lt;p&gt;避免      &lt;code&gt;FSL &lt;/code&gt;&lt;/p&gt;
     &lt;ul&gt;      &lt;li&gt;
       &lt;p&gt;先执行        &lt;code&gt;JS&lt;/code&gt;，然后在        &lt;code&gt;JS&lt;/code&gt;中修改了样式从而导致样式计算，然后样式的改动触发了布局、绘制、合成。但        &lt;code&gt;JavaScript&lt;/code&gt;可以强制浏览器将布局提前执行，这就叫 强制同步布局        &lt;code&gt;FSL&lt;/code&gt;。&lt;/p&gt;
       &lt;pre&gt;        &lt;code&gt;  //读取offsetWidth的值会导致重绘
 const newWidth = container.offsetWidth;
   
  //设置width的值会导致重排，但是for循环内部
  代码执行速度极快，当上面的查询操作导致的重绘
  还没有完成，下面的代码又会导致重排，而且这个重
  排会强制结束上面的重绘，直接重排，这样对性能影响
  非常大。所以我们一般会在循环外部定义一个变量，这里
  面使用变量代替container.offsetWidth;
 boxes[i].style.width = newWidth + &amp;apos;px&amp;apos;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
    &lt;li&gt;使用     &lt;code&gt;transform&lt;/code&gt;属性去操作动画，这个属性是由合成器单独处理的，所以使用这个属性可以避免布局与绘制。&lt;/li&gt;
    &lt;li&gt;使用     &lt;code&gt;translateZ(0)&lt;/code&gt;开启图层，减少重绘重排。特别在移动端，尽量使用     &lt;code&gt;transform&lt;/code&gt;代替     &lt;code&gt;absolute&lt;/code&gt;。创建图层的最佳方式是使用will-change，但某些不支持这个属性的浏览器可以使用3D 变形（transform: translateZ(0)）来强制创建一个新层。&lt;/li&gt;
    &lt;li&gt;有兴趣的可以看看这篇文字      &lt;a href="https://juejin.im/post/5c860282e51d45531330e10e#heading-12" rel="nofollow noreferrer"&gt;前端页面优化&lt;/a&gt;
&lt;/li&gt;
    &lt;li&gt;样式的切换最好提前定义好     &lt;code&gt;class&lt;/code&gt;，通过     &lt;code&gt;class&lt;/code&gt;的切换批量修改样式，避免多次重绘重排&lt;/li&gt;
    &lt;li&gt;可以先切换     &lt;code&gt;display:none&lt;/code&gt;再修改样式&lt;/li&gt;
    &lt;li&gt;多次的     &lt;code&gt;append &lt;/code&gt;操作可以先插入到一个新生成的元素中，再一次性插入到页面中。&lt;/li&gt;
    &lt;li&gt;代码复用，函数柯里化，封装高阶函数，将多次复用代码封装成普通函数（俗称方法），     &lt;code&gt;React&lt;/code&gt;中封装成高阶组件，     &lt;code&gt;ES6&lt;/code&gt;中可以使用继承，     &lt;code&gt;TypeScript&lt;/code&gt;中接口继承，类继承，接口合并，类合并。&lt;/li&gt;
    &lt;li&gt;强力推荐阅读:     &lt;a href="http://es6.ruanyifeng.com/#docs/promise" rel="nofollow noreferrer"&gt;阮一峰ES6教程&lt;/a&gt;
&lt;/li&gt;
    &lt;li&gt;以及     &lt;a href="https://ts.xcatliu.com/introduction/what-is-typescript.html" rel="nofollow noreferrer"&gt;什么是TypeScript以及入门&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;
 &lt;blockquote&gt;以上都是根据本人的知识点总结得出，后期还会有  &lt;code&gt;React&lt;/code&gt;的性能优化方案等出来，路过点个赞收藏收藏~，欢迎提出问题补充~&lt;/blockquote&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>javascript node.js typescript css html5</category>
      <guid isPermaLink="true">https://itindex.net/detail/59441-%E5%89%8D%E7%AB%AF-%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96-%E5%AE%8C%E5%85%A8</guid>
      <pubDate>Thu, 11 Apr 2019 00:06:56 CST</pubDate>
    </item>
    <item>
      <title>从 0 到 1 再到 100, 搭建、编写、构建一个前端项目</title>
      <link>https://itindex.net/detail/59009-%E5%BB%BA%E4%B8%80-%E5%89%8D%E7%AB%AF-%E9%A1%B9%E7%9B%AE</link>
      <description>&lt;h1&gt;从 0 到 1 再到 100, 搭建、编写、构建一个前端项目&lt;/h1&gt;
 &lt;h2&gt;1. 选择现成的项目模板还是自己搭建项目骨架&lt;/h2&gt;
 &lt;p&gt;搭建一个前端项目的方式有两种：选择现成的项目模板、自己搭建项目骨架。&lt;/p&gt;
 &lt;p&gt;选择一个现成项目模板是搭建一个项目最快的方式，模板已经把基本的骨架都搭建好了，你只需要向里面填充具体的业务代码，就可以通过内置的工具与命令构建代码、部署到服务器等。&lt;/p&gt;
 &lt;p&gt;一般来说，一个现成的项目模板会预定义一定的目录结构、书写方式，在编写项目代码时需要遵循相应的规范；也会内置必要的工具，比如   &lt;a href="http://editorconfig.org" rel="nofollow noreferrer"&gt;.editorconfig&lt;/a&gt;、  &lt;a href="https://github.com/eslint/eslint" rel="nofollow noreferrer"&gt;eslint&lt;/a&gt;、  &lt;a href="https://github.com/stylelint/stylelint" rel="nofollow noreferrer"&gt;stylelint&lt;/a&gt;、  &lt;a href="https://github.com/prettier/prettier" rel="nofollow noreferrer"&gt;prettier&lt;/a&gt;、  &lt;a href="https://github.com/typicode/husky" rel="nofollow noreferrer"&gt;husky&lt;/a&gt;、  &lt;a href="https://github.com/okonet/lint-staged" rel="nofollow noreferrer"&gt;lint-staged&lt;/a&gt; 等；也会内置必要的命令（  &lt;code&gt;package.json | scripts&lt;/code&gt;），比如   &lt;code&gt;本地开发：npm run dev&lt;/code&gt;、  &lt;code&gt;本地预览：npm run start&lt;/code&gt;、  &lt;code&gt;构建：npm run build&lt;/code&gt;、  &lt;code&gt;部署：npm run deploy&lt;/code&gt; 等。&lt;/p&gt;
 &lt;p&gt;社区比较好的项目模板：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="https://github.com/react-boilerplate/react-boilerplate" rel="nofollow noreferrer"&gt;react-boilerplate&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://github.com/ant-design/ant-design-pro" rel="nofollow noreferrer"&gt;ant-design-pro&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://github.com/PanJiaChen/vue-element-admin" rel="nofollow noreferrer"&gt;vue-element-admin&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://github.com/kriasoft/react-starter-kit" rel="nofollow noreferrer"&gt;react-starter-kit&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://github.com/facebook/create-react-app" rel="nofollow noreferrer"&gt;create-react-app&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;
   &lt;a href="https://github.com/senntyou/lila/tree/master/packages/create-lila-app" rel="nofollow noreferrer"&gt;create-lila-app&lt;/a&gt;（我自己用的，哈哈）&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;这些模板的使用又分为两种：使用   &lt;code&gt;git&lt;/code&gt; 直接克隆到本地、使用命令行创建。&lt;/p&gt;
 &lt;p&gt;（使用现有模板构建的项目，可以跳过第 2 ～ 7 步）&lt;/p&gt;
 &lt;h3&gt;1.1 使用   &lt;code&gt;git&lt;/code&gt; 直接克隆到本地&lt;/h3&gt;
 &lt;p&gt;这是一种真正意义上的模板，可以直接到模板项目的   &lt;code&gt;github&lt;/code&gt; 主页，就能看到整个骨架，比如   &lt;a href="https://github.com/react-boilerplate/react-boilerplate" rel="nofollow noreferrer"&gt;react-boilerplate&lt;/a&gt;、  &lt;a href="https://github.com/ant-design/ant-design-pro" rel="nofollow noreferrer"&gt;ant-design-pro&lt;/a&gt;、  &lt;a href="https://github.com/PanJiaChen/vue-element-admin" rel="nofollow noreferrer"&gt;vue-element-admin&lt;/a&gt;、  &lt;a href="https://github.com/kriasoft/react-starter-kit" rel="nofollow noreferrer"&gt;react-starter-kit&lt;/a&gt;。&lt;/p&gt;
 &lt;p&gt;以   &lt;code&gt;react-boilerplate&lt;/code&gt; 为例：&lt;/p&gt;
 &lt;p&gt;克隆到本地：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;git clone --depth=1 https://github.com/react-boilerplate/react-boilerplate.git &amp;lt;你的项目名字&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;切换到目录下：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;cd &amp;lt;你的项目名字&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;一般来说，接下来运行   &lt;code&gt;npm run install&lt;/code&gt; 安装项目的依赖后，就可以运行；有些模板可能有内置的初始化命令，比如   &lt;code&gt;react-boilerplate&lt;/code&gt;：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;npm run setup&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;启动应用：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;npm start&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;这时，就可以在浏览器中预览应用了。&lt;/p&gt;
 &lt;h3&gt;1.2 使用命令行创建&lt;/h3&gt;
 &lt;p&gt;这种方式需要安装相应的命令，然后由命令来创建项目。&lt;/p&gt;
 &lt;p&gt;以   &lt;code&gt;create-react-app&lt;/code&gt; 为例：&lt;/p&gt;
 &lt;p&gt;安装命令：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;npm install -g create-react-app&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;创建项目：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;create-react-app my-app&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;运行应用：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;cd my-app
npm start&lt;/code&gt;&lt;/pre&gt;
 &lt;h3&gt;1.3 自己搭建项目骨架&lt;/h3&gt;
 &lt;p&gt;如果你需要定制化，可以选择自己搭建项目的骨架，但这需要开发者对构建工具如   &lt;code&gt;webpack&lt;/code&gt;、  &lt;code&gt;npm&lt;/code&gt;、  &lt;code&gt;node&lt;/code&gt; 及其生态等有相当的了解与应用，才能完美的把控整个项目。&lt;/p&gt;
 &lt;p&gt;下面将会一步一步的说明如何搭建一个定制化的项目骨架。&lt;/p&gt;
 &lt;h2&gt;2. 选择合适的规范来写代码&lt;/h2&gt;
 &lt;p&gt;  &lt;code&gt;js&lt;/code&gt; 模块化的发展大致有这样一个过程   &lt;code&gt;iife =&amp;gt; commonjs/amd =&amp;gt; es6&lt;/code&gt;，而在这几个规范中：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;
   &lt;code&gt;iife&lt;/code&gt;:    &lt;code&gt;js&lt;/code&gt; 原生支持，但一般不会直接使用这种规范写代码&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;amd&lt;/code&gt;:    &lt;a href="https://github.com/requirejs/requirejs" rel="nofollow noreferrer"&gt;requirejs&lt;/a&gt; 定义的加载规范，但随着构建工具的出现，便一般不会用这种规范写代码&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;commonjs&lt;/code&gt;:    &lt;code&gt;node&lt;/code&gt; 的模块加载规范，一般会用这种规范写    &lt;code&gt;node&lt;/code&gt; 程序&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;es6&lt;/code&gt;:    &lt;code&gt;ECMAScript2015&lt;/code&gt; 定义的模块加载规范，需要转码后浏览器才能运行&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;这里推荐使用   &lt;code&gt;es6&lt;/code&gt; 的模块化规范来写代码，然后用工具转换成   &lt;code&gt;es5&lt;/code&gt; 的代码，并且   &lt;code&gt;es6&lt;/code&gt; 的代码可以使用   &lt;a href="https://en.wikipedia.org/wiki/Tree_shaking" rel="nofollow noreferrer"&gt;Tree shaking&lt;/a&gt; 功能。&lt;/p&gt;
 &lt;p&gt;参考：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="https://en.wikipedia.org/wiki/Immediately-invoked_function_expression" rel="nofollow noreferrer"&gt;IIFE(Immediately-invoked function expression)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://en.wikipedia.org/wiki/Tree_shaking" rel="nofollow noreferrer"&gt;Tree shaking&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://webpack.js.org/guides/tree-shaking/" rel="nofollow noreferrer"&gt;webpack - tree-shaking&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://blog.csdn.net/haodawang/article/details/77199980" rel="nofollow noreferrer"&gt;webpack 如何优雅的使用tree-shaking（摇树优化）&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;3. 选择合适的构建工具&lt;/h2&gt;
 &lt;p&gt;对于前端项目来说，构建工具一般都选用   &lt;a href="https://github.com/webpack/webpack" rel="nofollow noreferrer"&gt;webpack&lt;/a&gt;，  &lt;code&gt;webpack&lt;/code&gt; 提供了强大的功能和配置化运行。如果你不喜欢复杂的配置，可以尝试   &lt;a href="https://github.com/parcel-bundler/parcel" rel="nofollow noreferrer"&gt;parcel&lt;/a&gt;。&lt;/p&gt;
 &lt;p&gt;参考：&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;   &lt;a href="https://segmentfault.com/a/1190000016409719"&gt;webpack 之外的另一种选择：parcel&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
 &lt;h2&gt;4. 确定是单页面应用（SPA）还是多页面应用&lt;/h2&gt;
 &lt;p&gt;因为单页面应用与多页面应用在构建的方式上有很大的不同，所以需要从项目一开始就确定，使用哪种模式来构建项目。&lt;/p&gt;
 &lt;h3&gt;4.1 多页面应用&lt;/h3&gt;
 &lt;p&gt;传统多页面是由后端控制一个   &lt;code&gt;url&lt;/code&gt; 对应一个   &lt;code&gt;html&lt;/code&gt; 文件，页面之间的跳转需要根据后端给出的   &lt;code&gt;url&lt;/code&gt; 跳转到新的   &lt;code&gt;html&lt;/code&gt; 上。比如：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;http://www.example.com/page1 -&amp;gt; path/to/page1.html
http://www.example.com/page2 -&amp;gt; path/to/page2.html
http://www.example.com/page3 -&amp;gt; path/to/page3.html&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;这种方式的应用，项目里会有多个入口文件，搭建项目的时候就需要对这种多入口模式进行封装。另外，也可以选择一些封装的多入口构建工具，如   &lt;a href="https://github.com/senntyou/lila" rel="nofollow noreferrer"&gt;lila&lt;/a&gt;。&lt;/p&gt;
 &lt;h3&gt;4.2 单页面应用&lt;/h3&gt;
 &lt;p&gt;  &lt;a href="https://en.wikipedia.org/wiki/Single-page_application" rel="nofollow noreferrer"&gt;单页面应用（single page application）&lt;/a&gt;，就是只有一个页面的应用，页面的刷新和内部子页面的跳转完全由   &lt;code&gt;js&lt;/code&gt; 来控制。&lt;/p&gt;
 &lt;p&gt;一般单页面应用都有以下几个特点：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;本地路由，由    &lt;code&gt;js&lt;/code&gt; 定义路由、根据路由渲染页面、控制页面的跳转&lt;/li&gt;
  &lt;li&gt;所有文件只会加载一次，最大限度重用文件，并且极大提升加载速度&lt;/li&gt;
  &lt;li&gt;按需加载，只有真正使用到页面的时候，才加载相应的文件&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;这种方式的应用，项目里只有一个入口文件，便无需封装。&lt;/p&gt;
 &lt;p&gt;参考：&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;   &lt;a href="https://segmentfault.com/a/1190000015297908"&gt;单页面应用（SPA）、按需加载&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
 &lt;h2&gt;5. 选择合适的前端框架与 UI 库&lt;/h2&gt;
 &lt;p&gt;一般在搭建项目的时候就需要定下前端框架与 UI 库，因为如果后期想更换前端框架和 UI 库，代价是很大的。&lt;/p&gt;
 &lt;p&gt;比较现代化的前端框架：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="https://github.com/facebook/react" rel="nofollow noreferrer"&gt;react&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://github.com/vuejs/vue" rel="nofollow noreferrer"&gt;vue&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://github.com/angular/angular" rel="nofollow noreferrer"&gt;angular&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;一些不错的组合：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;
   &lt;a href="https://github.com/jquery/jquery" rel="nofollow noreferrer"&gt;jquery&lt;/a&gt; +    &lt;a href="https://github.com/twbs/bootstrap" rel="nofollow noreferrer"&gt;bootstrap&lt;/a&gt;：比较经典的&lt;/li&gt;
  &lt;li&gt;
   &lt;a href="https://github.com/facebook/react" rel="nofollow noreferrer"&gt;react&lt;/a&gt; +    &lt;a href="https://github.com/ant-design/ant-design" rel="nofollow noreferrer"&gt;ant-design&lt;/a&gt;、   &lt;a href="https://github.com/mui-org/material-ui" rel="nofollow noreferrer"&gt;material-ui&lt;/a&gt;、   &lt;a href="https://github.com/Semantic-Org/Semantic-UI" rel="nofollow noreferrer"&gt;Semantic-UI&lt;/a&gt;：   &lt;code&gt;react&lt;/code&gt; 的组合&lt;/li&gt;
  &lt;li&gt;
   &lt;a href="https://github.com/vuejs/vue" rel="nofollow noreferrer"&gt;vue&lt;/a&gt; +    &lt;a href="https://github.com/ElemeFE/element" rel="nofollow noreferrer"&gt;element&lt;/a&gt;、   &lt;a href="https://github.com/iview/iview" rel="nofollow noreferrer"&gt;iview&lt;/a&gt;、   &lt;a href="https://github.com/airyland/vux" rel="nofollow noreferrer"&gt;vux&lt;/a&gt;、   &lt;a href="https://github.com/ElemeFE/mint-ui" rel="nofollow noreferrer"&gt;mint-ui&lt;/a&gt;：   &lt;code&gt;vue&lt;/code&gt; 的组合&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;参考：&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;   &lt;a href="https://segmentfault.com/a/1190000016334838"&gt;前端最受欢迎的 UI 框架&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
 &lt;h2&gt;6. 定好目录结构&lt;/h2&gt;
 &lt;p&gt;一个好的目录结构对一个好的项目而言是非常必要的。&lt;/p&gt;
 &lt;p&gt;一个好的目录结构应当具有以下的一些特点：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;解耦：代码尽量去耦合，这样代码逻辑清晰，也容易扩展&lt;/li&gt;
  &lt;li&gt;分块：按照功能对代码进行分块、分组，并能快捷的添加分块、分组&lt;/li&gt;
  &lt;li&gt;编辑器友好：需要更新功能时，可以很快的定位到相关文件，并且这些文件应该是很靠近的，而不至于到处找文件&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;比较推荐的目录结构：&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;em&gt;多页面应用&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;|-- src/ 源代码目录

    |-- page1/ page1 页面的工作空间（与这个页面相关的文件都放在这个目录下）
        |-- index.html html 入口文件
        |-- index.js js 入口文件
        |-- index.(css|less|scss) 样式入口文件
        |-- html/ html 片段目录
        |-- (css|less|scss)/ 样式文件目录
        |-- mock/ 本地 json 数据模拟
        |-- images/ 图片文件目录
        |-- components/ 组件目录（如果基于 react, vue 等组件化框架）
        |-- ...
        
    |-- sub-dir/ 子目录
        |-- page2/ page2 页面的工作空间（内部结构参考 page1）
            |-- ...
        
    |-- ...
    
|-- html/ 公共 html 片段
|-- less/ 公共 less 目录
|-- components/ 公共组件目录
|-- images/ 公共图片目录
|-- mock/ 公共 api-mock 文件目录
|-- ...&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;em&gt;单页面应用&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;|-- src/ 源代码目录
    |-- page1/ page1 页面的工作空间
        |-- index.js 入口文件
        |-- services/ service 目录
        |-- models/ model 目录
        |-- mock/ 本地 json 数据模拟
        |-- images/ 图片文件目录
        |-- components/ 组件目录（如果基于 react, vue 等组件化框架）
        |-- ...
        
    |-- module1/ 子目录
        |-- page2/ page2 页面的工作空间（内部结构参考 page1）
        
    |-- ...
    
|-- images/ 公共图片目录
|-- mock/ 公共 api-mock 文件目录
|-- components/ 公共组件目录   
|-- ... &lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;参考：&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;   &lt;a href="https://segmentfault.com/a/1190000015816534"&gt;目录结构优化&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
 &lt;h2&gt;7. 搭建一个好的脚手架&lt;/h2&gt;
 &lt;p&gt;搭建一个好的脚手架，能够更好的编写代码、构建项目等。&lt;/p&gt;
 &lt;p&gt;可以查看   &lt;a href="https://segmentfault.com/a/1190000016481132"&gt;搭建自己的前端脚手架&lt;/a&gt; 了解一些基本的脚手架文件与工具。&lt;/p&gt;
 &lt;p&gt;比如：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;|-- /                              项目根目录
    |-- src/                       源代码目录
    |-- package.json               npm 项目文件
    |-- README.md                  项目说明文件
    |-- CHANGELOG.md               版本更新记录
    |-- .gitignore                 git 忽略配置文件
    |-- .editorconfig              编辑器配置文件
    |-- .npmrc                     npm 配置文件
    |-- .npmignore                 npm 忽略配置文件
    |-- .eslintrc                  eslint 配置文件
    |-- .eslintignore              eslint 忽略配置文件
    |-- .stylelintrc               stylelint 配置文件
    |-- .stylelintignore           stylelint 忽略配置文件
    |-- .prettierrc                prettier 配置文件
    |-- .prettierignore            prettier 忽略配置文件
    
    |-- .babelrc                   babel 配置文件
    |-- webpack.config.js          webpack 配置文件
    |-- rollup.config.js           rollup 配置文件
    |-- gulpfile.js                gulp 配置文件
    
    |-- test/                      测试目录
    |-- docs/                      文档目录
    |-- jest.config.js             jest 配置文件
    |-- .gitattributes             git 属性配置&lt;/code&gt;&lt;/pre&gt;
 &lt;ul&gt;
  &lt;li&gt;
   &lt;code&gt;.editorconfig&lt;/code&gt;: 用这个文件来统一不同编辑器的一些配置，比如    &lt;code&gt;tab&lt;/code&gt; 转 2 个空格、自动插入空尾行、去掉行尾的空格等，   &lt;a href="http://editorconfig.org" rel="nofollow noreferrer"&gt;http://editorconfig.org&lt;/a&gt;
&lt;/li&gt;
  &lt;li&gt;
   &lt;a href="https://github.com/eslint/eslint" rel="nofollow noreferrer"&gt;eslint&lt;/a&gt;、   &lt;a href="https://github.com/stylelint/stylelint" rel="nofollow noreferrer"&gt;stylelint&lt;/a&gt;、   &lt;a href="https://github.com/prettier/prettier" rel="nofollow noreferrer"&gt;prettier&lt;/a&gt;: 规范化代码风格、优化代码格式等&lt;/li&gt;
  &lt;li&gt;
   &lt;a href="https://github.com/typicode/husky" rel="nofollow noreferrer"&gt;husky&lt;/a&gt;、   &lt;a href="https://github.com/okonet/lint-staged" rel="nofollow noreferrer"&gt;lint-staged&lt;/a&gt;: 在    &lt;code&gt;git&lt;/code&gt; 提交之前对代码进行审查，否则不予提交&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;:    &lt;a href="https://docs.gitlab.com/ee/ci/" rel="nofollow noreferrer"&gt;gitlab ci&lt;/a&gt; 持续集成服务&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;参考：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="https://segmentfault.com/a/1190000016481132"&gt;搭建自己的前端脚手架&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://segmentfault.com/a/1190000015858432"&gt;怎样提升代码质量&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://segmentfault.com/a/1190000015403363"&gt;CSS 模块化&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://segmentfault.com/a/1190000016422897"&gt;css 的弱化与 js 的强化&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://segmentfault.com/a/1190000015297352"&gt;本地化接口模拟、前后端并行开发&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;=================================================&lt;/p&gt;
 &lt;p&gt;到这里为止，一个基本的项目骨架就算搭建好了。&lt;/p&gt;
 &lt;h2&gt;8. 使用版本控制系统管理源代码（git）&lt;/h2&gt;
 &lt;p&gt;项目搭建好后，需要一个版本控制系统来管理源代码。&lt;/p&gt;
 &lt;p&gt;比较常用的版本管理工具有   &lt;a href="https://git-scm.com/" rel="nofollow noreferrer"&gt;git&lt;/a&gt;、  &lt;a href="http://subversion.apache.org/" rel="nofollow noreferrer"&gt;svn&lt;/a&gt;，现在一般都用   &lt;code&gt;git&lt;/code&gt;。&lt;/p&gt;
 &lt;p&gt;一般开源的项目可以托管到   &lt;a href="http://github.com" rel="nofollow noreferrer"&gt;http://github.com&lt;/a&gt;，私人的项目可以托管到   &lt;a href="https://gitee.com" rel="nofollow noreferrer"&gt;https://gitee.com&lt;/a&gt;、  &lt;a href="https://coding.net/" rel="nofollow noreferrer"&gt;https://coding.net/&lt;/a&gt;，而企业的项目则需要自建版本控制系统了。&lt;/p&gt;
 &lt;p&gt;自建版本控制系统主要有   &lt;a href="https://gitlab.com/" rel="nofollow noreferrer"&gt;gitlab&lt;/a&gt;、  &lt;a href="https://github.com/gogs/gogs" rel="nofollow noreferrer"&gt;gogs&lt;/a&gt;、  &lt;a href="https://github.com/go-gitea/gitea" rel="nofollow noreferrer"&gt;gitea&lt;/a&gt;：  &lt;code&gt;gitlab&lt;/code&gt; 是由商业驱动的，比较稳定，社区版是免费的，一般建议选用这个；  &lt;code&gt;gogs, gitea&lt;/code&gt; 是开源的项目，还不太稳定，期待进一步的更新。&lt;/p&gt;
 &lt;p&gt;所以，  &lt;code&gt;git&lt;/code&gt; +   &lt;code&gt;gitlab&lt;/code&gt; 是不错的配合。&lt;/p&gt;
 &lt;h2&gt;9. 编写代码&lt;/h2&gt;
 &lt;p&gt;编写代码时，  &lt;code&gt;js&lt;/code&gt; 选用   &lt;code&gt;es6&lt;/code&gt; 的模块化规范来写（如果喜欢用   &lt;a href="https://github.com/Microsoft/TypeScript" rel="nofollow noreferrer"&gt;TypeScript&lt;/a&gt;，需要加上   &lt;a href="https://github.com/TypeStrong/ts-loader" rel="nofollow noreferrer"&gt;ts-loader&lt;/a&gt;），样式可以用   &lt;a href="http://lesscss.org/" rel="nofollow noreferrer"&gt;less&lt;/a&gt;、  &lt;a href="http://sass-lang.com/" rel="nofollow noreferrer"&gt;scss&lt;/a&gt;、  &lt;code&gt;css&lt;/code&gt; 来写。&lt;/p&gt;
 &lt;p&gt;写   &lt;code&gt;js&lt;/code&gt; 模块文件时，注释可以使用   &lt;a href="http://usejsdoc.org/" rel="nofollow noreferrer"&gt;jsdoc&lt;/a&gt; 的规范来写，如果配置相应的工具，可以将这些注释导出接口文档。&lt;/p&gt;
 &lt;p&gt;因为脚手架里有   &lt;a href="https://github.com/typicode/husky" rel="nofollow noreferrer"&gt;husky&lt;/a&gt;、  &lt;a href="https://github.com/okonet/lint-staged" rel="nofollow noreferrer"&gt;lint-staged&lt;/a&gt; 的配合，所以每次提交的代码都会进行代码审查与格式优化，如果不符合规范，则需要把不规范的代码进行修改，然后才能提交到代码仓库中。&lt;/p&gt;
 &lt;p&gt;比如   &lt;code&gt;console.log(haha.hehe);&lt;/code&gt; 这段代码就会遇到错误，不予提交：&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://segmentfault.com/img/bVbj9Q6?w=907&amp;h=555" title="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;这个功能定义在   &lt;code&gt;package.json&lt;/code&gt; 中：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;{
  &amp;quot;devDependencies&amp;quot;: {             工具依赖
    &amp;quot;babel-eslint&amp;quot;: &amp;quot;^8.2.6&amp;quot;,
    &amp;quot;eslint&amp;quot;: &amp;quot;^4.19.1&amp;quot;,
    &amp;quot;husky&amp;quot;: &amp;quot;^0.14.3&amp;quot;,
    &amp;quot;lint-staged&amp;quot;: &amp;quot;^7.2.0&amp;quot;,
    &amp;quot;prettier&amp;quot;: &amp;quot;^1.14.0&amp;quot;,
    &amp;quot;stylelint&amp;quot;: &amp;quot;^9.3.0&amp;quot;,
    &amp;quot;eslint-config-airbnb&amp;quot;: &amp;quot;^17.0.0&amp;quot;,
    &amp;quot;eslint-config-prettier&amp;quot;: &amp;quot;^2.9.0&amp;quot;,
    &amp;quot;eslint-plugin-babel&amp;quot;: &amp;quot;^5.1.0&amp;quot;,
    &amp;quot;eslint-plugin-import&amp;quot;: &amp;quot;^2.13.0&amp;quot;,
    &amp;quot;eslint-plugin-jsx-a11y&amp;quot;: &amp;quot;^6.1.0&amp;quot;,
    &amp;quot;eslint-plugin-prettier&amp;quot;: &amp;quot;^2.6.2&amp;quot;,
    &amp;quot;eslint-plugin-react&amp;quot;: &amp;quot;^7.10.0&amp;quot;,
    &amp;quot;stylelint-config-prettier&amp;quot;: &amp;quot;^3.3.0&amp;quot;,
    &amp;quot;stylelint-config-standard&amp;quot;: &amp;quot;^18.2.0&amp;quot;
  },
  &amp;quot;scripts&amp;quot;: {                     可以添加更多命令
    &amp;quot;precommit&amp;quot;: &amp;quot;npm run lint-staged&amp;quot;,
    &amp;quot;prettier&amp;quot;: &amp;quot;prettier --write \&amp;quot;./**/*.{js,jsx,css,less,sass,scss,md,json}\&amp;quot;&amp;quot;,
    &amp;quot;eslint&amp;quot;: &amp;quot;eslint .&amp;quot;,
    &amp;quot;eslint:fix&amp;quot;: &amp;quot;eslint . --fix&amp;quot;,
    &amp;quot;stylelint&amp;quot;: &amp;quot;stylelint \&amp;quot;./**/*.{css,less,sass,scss}\&amp;quot;&amp;quot;,
    &amp;quot;stylelint:fix&amp;quot;: &amp;quot;stylelint \&amp;quot;./**/*.{css,less,sass,scss}\&amp;quot; --fix&amp;quot;,
    &amp;quot;lint-staged&amp;quot;: &amp;quot;lint-staged&amp;quot;
  },
  &amp;quot;lint-staged&amp;quot;: {                 对提交的代码进行检查与矫正
    &amp;quot;**/*.{js,jsx}&amp;quot;: [
      &amp;quot;eslint --fix&amp;quot;,
      &amp;quot;prettier --write&amp;quot;,
      &amp;quot;git add&amp;quot;
    ],
    &amp;quot;**/*.{css,less,sass,scss}&amp;quot;: [
      &amp;quot;stylelint --fix&amp;quot;,
      &amp;quot;prettier --write&amp;quot;,
      &amp;quot;git add&amp;quot;
    ],
    &amp;quot;**/*.{md,json}&amp;quot;: [
      &amp;quot;prettier --write&amp;quot;,
      &amp;quot;git add&amp;quot;
    ]
  }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;ul&gt;
  &lt;li&gt;如果你想禁用这个功能，可以把    &lt;code&gt;scripts&lt;/code&gt; 中    &lt;code&gt;&amp;quot;precommit&amp;quot;&lt;/code&gt; 改成    &lt;code&gt;&amp;quot;//precommit&amp;quot;&lt;/code&gt;
&lt;/li&gt;
  &lt;li&gt;如果你想自定    &lt;code&gt;eslint&lt;/code&gt; 检查代码的规范，可以修改    &lt;code&gt;.eslintrc, .eslintrc.js&lt;/code&gt; 等配置文件&lt;/li&gt;
  &lt;li&gt;如果你想自定    &lt;code&gt;stylelint&lt;/code&gt; 检查代码的规范，可以修改    &lt;code&gt;.stylelintrc, .stylelintrc.js&lt;/code&gt; 等配置文件&lt;/li&gt;
  &lt;li&gt;如果你想忽略某些文件不进行代码检查，可以修改    &lt;code&gt;.eslintignore, .stylelintignore&lt;/code&gt; 配置文件&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;参考：&lt;/p&gt;
 &lt;ul&gt;  &lt;li&gt;   &lt;a href="https://segmentfault.com/a/1190000016481132"&gt;搭建自己的前端脚手架&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
 &lt;h2&gt;10. 组件化&lt;/h2&gt;
 &lt;p&gt;当项目拥有了一定量的代码之后，就会发现，有些代码是很多页面共用的，于是把这些代码提取出来，封装成一个组件，供各个地方使用。&lt;/p&gt;
 &lt;p&gt;当拥有多个项目的时候，有些组件需要跨项目使用，一种方式是复制代码到其他项目中，但这种方式会导致组件代码很难维护，所以，一般是用另一种方式：组件化。&lt;/p&gt;
 &lt;p&gt;组件化就是将组件独立成一个项目，然后在其他项目中安装这个组件，才能使用。&lt;/p&gt;
 &lt;p&gt;一般组件化会配合私有 npm 仓库一起用。&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;|-- project1/ 项目1
    |-- package.json
    
|-- project2/ 项目2
    |-- package.json    

|-- component1/ 组件1
    |-- package.json

|-- component2/ 组件2
    |-- package.json&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;在   &lt;code&gt;project1&lt;/code&gt; 中安装   &lt;code&gt;component1， component2&lt;/code&gt; 组件：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;# package.json
{
  &amp;quot;dependencies&amp;quot;: {
    &amp;quot;component1&amp;quot;: &amp;quot;^0.0.1&amp;quot;,
    &amp;quot;component2&amp;quot;: &amp;quot;^0.0.1&amp;quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;pre&gt;  &lt;code&gt;import compoennt1 from &amp;apos;compoennt1&amp;apos;;
import compoennt2 from &amp;apos;compoennt2&amp;apos;;&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;如果想要了解怎样写好一个组件（  &lt;code&gt;npm package&lt;/code&gt;），可以参考   &lt;a href="https://segmentfault.com/a/1190000017064659"&gt;从 1 到完美，写一个 js 库、node 库、前端组件库&lt;/a&gt;。&lt;/p&gt;
 &lt;p&gt;参考：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="https://segmentfault.com/a/1190000015297823"&gt;组件化&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://segmentfault.com/a/1190000015297864"&gt;私有 npm 仓库&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://segmentfault.com/a/1190000017064659"&gt;从 1 到完美，写一个 js 库、node 库、前端组件库&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;11. 测试&lt;/h2&gt;
 &lt;p&gt;测试的目的在于能以最少的人力和时间发现潜在的各种错误和缺陷，这在项目更新、重构等的过程中尤其重要，因为每当更改一些代码后，你并不知道这些代码有没有问题、会不会影响其他的模块。如果有了测试，运行一遍测试用例，就知道更改的代码有没有问题、会不会产生影响。&lt;/p&gt;
 &lt;p&gt;一般前端测试分以下几种：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;单元测试：模块单元、函数单元、组件单元等的单元块的测试&lt;/li&gt;
  &lt;li&gt;集成测试：接口依赖（ajax）、I/O 依赖、环境依赖（localStorage、IndexedDB）等的上下文的集成测试&lt;/li&gt;
  &lt;li&gt;样式测试：对样式的测试&lt;/li&gt;
  &lt;li&gt;E2E 测试：端到端测试，也就是在实际生产环境测试整个应用&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;一般会用到下面的一些工具：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="https://github.com/facebook/jest" rel="nofollow noreferrer"&gt;jest&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://github.com/airbnb/enzyme" rel="nofollow noreferrer"&gt;enzyme&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://github.com/cypress-io/cypress" rel="nofollow noreferrer"&gt;cypress&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://github.com/SeleniumHQ/selenium" rel="nofollow noreferrer"&gt;selenium&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://github.com/GoogleChrome/puppeteer" rel="nofollow noreferrer"&gt;puppeteer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;另外，可以参考   &lt;a href="https://www.jianshu.com/p/1b99af371e66" rel="nofollow noreferrer"&gt;聊聊前端开发的测试&lt;/a&gt;。&lt;/p&gt;
 &lt;h2&gt;12. 构建&lt;/h2&gt;
 &lt;p&gt;一般单页面应用的构建会有   &lt;code&gt;npm run build&lt;/code&gt; 的命令来构建项目，然后会输出一个   &lt;code&gt;html&lt;/code&gt; 文件，一些   &lt;code&gt;js/css/images ...&lt;/code&gt; 文件，然后把这些文件部署到服务器就可以了。&lt;/p&gt;
 &lt;p&gt;多页面应用的构建要复杂一些，因为是多入口的，所以一般会封装构建工具，然后通过参数传入多个入口：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;npm run build -- page1 page2 dir1/* dir2/all --env test/prod&lt;/code&gt;&lt;/pre&gt;
 &lt;ul&gt;
  &lt;li&gt;
   &lt;code&gt;page1, page2&lt;/code&gt; 确定构建哪些页面；   &lt;code&gt;dir1/*, dir2/all&lt;/code&gt; 某个目录下所有的页面；   &lt;code&gt;all, *&lt;/code&gt; 整个项目所有的页面&lt;/li&gt;
  &lt;li&gt;有时候可能还会针对不同的服务器环境（比如测试机、正式机）做出不同的构建，可以在后面加参数&lt;/li&gt;
  &lt;li&gt;
   &lt;code&gt;--&lt;/code&gt; 用来分割    &lt;code&gt;npm&lt;/code&gt; 本身的参数与脚本参数，参考    &lt;a href="https://docs.npmjs.com/cli/run-script.html" rel="nofollow noreferrer"&gt;npm - run-script&lt;/a&gt; 了解详情&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;多页面应用会导出多个   &lt;code&gt;html&lt;/code&gt; 文件，需要注意这些导出的   &lt;code&gt;html&lt;/code&gt; 不要相冲突了。&lt;/p&gt;
 &lt;p&gt;当然，也可以用一些已经封装好的工具，如   &lt;a href="https://github.com/senntyou/lila" rel="nofollow noreferrer"&gt;lila&lt;/a&gt;。&lt;/p&gt;
 &lt;h2&gt;13. 部署&lt;/h2&gt;
 &lt;p&gt;在构建好项目之后，就可以部署到服务器了。&lt;/p&gt;
 &lt;p&gt;传统的方式，可以用   &lt;code&gt;ftp, sftp&lt;/code&gt; 等工具，手动传到服务器，但这种方式比较笨拙，不够自动化。&lt;/p&gt;
 &lt;p&gt;自动化的，可以用一些工具部署到服务器，如   &lt;a href="https://github.com/gulpjs/gulp" rel="nofollow noreferrer"&gt;gulp&lt;/a&gt;、  &lt;a href="https://github.com/teambition/gulp-ssh" rel="nofollow noreferrer"&gt;gulp-ssh&lt;/a&gt;，当然也可以用一些封装的工具，如   &lt;a href="https://github.com/senntyou/md-sync" rel="nofollow noreferrer"&gt;md-sync&lt;/a&gt;、  &lt;a href="https://github.com/senntyou/lila" rel="nofollow noreferrer"&gt;lila&lt;/a&gt; 等&lt;/p&gt;
 &lt;p&gt;以   &lt;code&gt;md-sync&lt;/code&gt; 为例：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;npm install md-sync --save-dev&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;  &lt;code&gt;md-sync.config.js&lt;/code&gt; 配置文件：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;module.exports = [
  {
    src: &amp;apos;./build/**/*&amp;apos;,
    remotePath: &amp;apos;remotePath&amp;apos;,
    server: {
      ignoreErrors: true,
      sshConfig: {
        host: &amp;apos;host&amp;apos;,
        username: &amp;apos;username&amp;apos;,
        password: &amp;apos;password&amp;apos;
      }
    },
  },
  {
    src: &amp;apos;./build/**/*.html&amp;apos;,
    remotePath: &amp;apos;remotePath2&amp;apos;,
    server: {
      ignoreErrors: true,
      sshConfig: {
        host: &amp;apos;host&amp;apos;,
        username: &amp;apos;username&amp;apos;,
        password: &amp;apos;password&amp;apos;
      }
    },
  },
];&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;在   &lt;code&gt;package.json&lt;/code&gt; 的   &lt;code&gt;scripts&lt;/code&gt; 配置好命令：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;&amp;quot;scripts&amp;quot;: {
  &amp;quot;deploy&amp;quot;: &amp;quot;md-sync&amp;quot;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;pre&gt;  &lt;code&gt;npm run deploy&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;另外，一般大型项目会使用持续集成 +   &lt;code&gt;shell&lt;/code&gt; 命令（如   &lt;code&gt;rsync&lt;/code&gt;）部署。&lt;/p&gt;
 &lt;h2&gt;14. 持续集成测试、构建、部署&lt;/h2&gt;
 &lt;p&gt;一般大型工程的的构建与测试都会花很长的时间，在本地做这些事情的话就不太实际，这就需要做持续集成测试、构建、部署了。&lt;/p&gt;
 &lt;p&gt;持续集成工具用的比较多的：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="https://jenkins.io/" rel="nofollow noreferrer"&gt;jenkins&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://docs.gitlab.com/ee/ci/" rel="nofollow noreferrer"&gt;gitlab ci&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;  &lt;code&gt;jenkins&lt;/code&gt; 是通用型的工具，可以与   &lt;a href="https://github.com" rel="nofollow noreferrer"&gt;github&lt;/a&gt;、  &lt;a href="https://bitbucket.org/" rel="nofollow noreferrer"&gt;bitbucket&lt;/a&gt;、  &lt;a href="https://about.gitlab.com/" rel="nofollow noreferrer"&gt;gitlab&lt;/a&gt; 等代码托管服务配合使用，优点是功能强大、插件多、社区活跃，但缺点是配置复杂、使用难度较高。&lt;/p&gt;
 &lt;p&gt;  &lt;code&gt;gitlab ci&lt;/code&gt; 是   &lt;a href="https://about.gitlab.com/" rel="nofollow noreferrer"&gt;gitlab&lt;/a&gt; 内部自带的持续集成功能，优点是使用简单、配置简单，但缺点是不及   &lt;code&gt;jenkins&lt;/code&gt; 功能强大、绑定   &lt;code&gt;gitlab&lt;/code&gt; 才能使用。&lt;/p&gt;
 &lt;p&gt;以   &lt;code&gt;gitlab&lt;/code&gt; 为例（任务定义在   &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; 中）：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;stages:
  - install
  - test
  - build
  - deploy

# 安装依赖
install:
  stage: install
  only:
    - dev
    - master
  script:
    - npm install

# 运行测试用例
test:
  stage: test
  only:
    - dev
    - master
  script:
    - npm run test

# 编译
build:
  stage: build
  only:
    - dev
    - master
  script:
    - npm run clean
    - npm run build

# 部署服务器
deploy:
  stage: deploy
  only:
    - dev
    - master
  script:
    - npm run deploy&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;以上配置表示只要在   &lt;code&gt;dev&lt;/code&gt; 或   &lt;code&gt;master&lt;/code&gt; 分支有代码推送，就会进行持续集成，依次运行：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;code&gt;npm install&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;code&gt;npm run test&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;code&gt;npm run clean&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;code&gt;npm run build&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;code&gt;npm run deploy&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;最终完成部署。如果中间某个命令失败了，将停止接下的命令的运行，并将错误报告给你。&lt;/p&gt;
 &lt;p&gt;这些操作都在远程机器上完成。&lt;/p&gt;
 &lt;p&gt;=================================================&lt;/p&gt;
 &lt;p&gt;到这里为止，基本上完成了一个项目的搭建、编写、构建。&lt;/p&gt;
 &lt;h2&gt;15. 清理服务器上过期文件&lt;/h2&gt;
 &lt;p&gt;现在前端的项目基本上都会用   &lt;code&gt;webpack&lt;/code&gt; 打包代码，并且文件名（  &lt;code&gt;html&lt;/code&gt; 文件除外）都是   &lt;code&gt;hash&lt;/code&gt; 化的，如果需要清除过期的文件而又不想把服务器上文件全部删掉然后重新构建、部署，可以使用   &lt;a href="https://github.com/senntyou/sclean" rel="nofollow noreferrer"&gt;sclean&lt;/a&gt; 来清除过期文件。&lt;/p&gt;
 &lt;h2&gt;16. 收集前端错误反馈&lt;/h2&gt;
 &lt;p&gt;当用户在用线上的程序时，怎么知道有没有出 bug；如果出 bug 了，报的是什么错；如果是 js 报错，怎么知道是那一行运行出了错？&lt;/p&gt;
 &lt;p&gt;所以，在程序运行时捕捉   &lt;code&gt;js&lt;/code&gt; 脚本错误，并上报到服务器，是非常有必要的。&lt;/p&gt;
 &lt;p&gt;这里就要用到   &lt;code&gt;window.onerror&lt;/code&gt; 了：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;window.onerror = (errorMessage, scriptURI, lineNumber, columnNumber, errorObj) =&amp;gt; {
  const data = {
    title: document.getElementsByTagName(&amp;apos;title&amp;apos;)[0].innerText,
    errorMessage,
    scriptURI,
    lineNumber,
    columnNumber,
    detailMessage: (errorObj &amp;amp;&amp;amp; errorObj.message) || &amp;apos;&amp;apos;,
    stack: (errorObj &amp;amp;&amp;amp; errorObj.stack) || &amp;apos;&amp;apos;,
    userAgent: window.navigator.userAgent,
    locationHref: window.location.href,
    cookie: window.document.cookie,
  };

  post(&amp;apos;url&amp;apos;, data); // 上报到服务器
};&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;线上的   &lt;code&gt;js&lt;/code&gt; 脚本都是压缩过的，需要用   &lt;code&gt;sourcemap&lt;/code&gt; 文件与   &lt;a href="https://github.com/mozilla/source-map" rel="nofollow noreferrer"&gt;source-map&lt;/a&gt; 查看原始的报错堆栈信息，可以参考   &lt;a href="https://segmentfault.com/a/1190000016987829"&gt;细说 js 压缩、sourcemap、通过 sourcemap 查找原始报错信息&lt;/a&gt; 了解详细信息。&lt;/p&gt;
 &lt;p&gt;参考：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="https://segmentfault.com/a/1190000016852780"&gt;前端如何高效的与后端协作开发&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://segmentfault.com/a/1190000016987829"&gt;细说 js 压缩、sourcemap、通过 sourcemap 查找原始报错信息&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;后续&lt;/h2&gt;
 &lt;p&gt;更多博客，查看   &lt;a href="https://github.com/senntyou/blogs" rel="nofollow noreferrer"&gt;https://github.com/senntyou/blogs&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;作者：  &lt;a href="https://github.com/senntyou" rel="nofollow noreferrer"&gt;深予之 (@senntyou)&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;版权声明：自由转载-非商用-非衍生-保持署名（  &lt;a href="https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh" rel="nofollow noreferrer"&gt;创意共享3.0许可证&lt;/a&gt;）&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>node.js html css javascript 前端</category>
      <guid isPermaLink="true">https://itindex.net/detail/59009-%E5%BB%BA%E4%B8%80-%E5%89%8D%E7%AB%AF-%E9%A1%B9%E7%9B%AE</guid>
      <pubDate>Tue, 27 Nov 2018 14:27:55 CST</pubDate>
    </item>
    <item>
      <title>浏览器输入url到发起http请求所经历的过程</title>
      <link>https://itindex.net/detail/58974-%E6%B5%8F%E8%A7%88%E5%99%A8-url-http</link>
      <description>&lt;h2&gt;用户输入url&lt;/h2&gt;
 &lt;p&gt;当用户输入url，操作系统会将输入事件传递到浏览器中，在这过程中，浏览器可能会做一些预处理，比如 Chrome 会根据历史统计来预估所输入字符对应的网站，例如输入goog，根据之前的历史发现 90% 的概率会访问「www.google.com 」，因此就会在输入回车前就马上开始建立 TCP 链接甚至渲染了。&lt;/p&gt;
 &lt;p&gt;接着是输入url之后，点击回车，这时浏览器会对 URL 进行检查，首先判断协议，如果是 http 就按照 Web 来处理，另外还会对这个 URL 进行安全检查&lt;/p&gt;
 &lt;p&gt;安全检查完成之后，在浏览器内核中会先查看缓存，然后设置 UA 等 HTTP 信息，接着调用不同平台下网络请求的方法。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;注意：&lt;/strong&gt;  &lt;br /&gt;浏览器和浏览器内核是不同的概念，浏览器指的是 Chrome、Firefox，而浏览器内核则是 Blink、Gecko，浏览器内核只负责渲染，GUI 及网络连接等跨平台工作则是浏览器实现的&lt;/p&gt;
 &lt;h2&gt;http网络请求&lt;/h2&gt;
 &lt;p&gt;通过 DNS 查询 IP；  &lt;br /&gt;通过 Socket 发送数据&lt;/p&gt;
 &lt;h2&gt;dns查询ip&lt;/h2&gt;
 &lt;p&gt;DNS，英文是Domain Name System，中文叫域名系统，是Internet的一项服务，他将域名和IP地址相互映射的一个分布式数据库&lt;/p&gt;
 &lt;p&gt;假设用户在浏览器中输入的是www.google.com，大概过程：&lt;/p&gt;
 &lt;p&gt;如果输入的是域名，则需要进行dns查询，将域名解析成ip；&lt;/p&gt;
 &lt;p&gt;进行DNS查询的主机或软件叫做DNS解析器，用户使用的工作站或电脑都属于解析器。域名解析就是利用DNS解析器得到对应IP过程，解析器会向域名服务器进行查询处理。&lt;/p&gt;
 &lt;p&gt;主要过程如下：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;从浏览器缓存中查找域名www.google.com的IP地址&lt;/li&gt;
  &lt;li&gt;在浏览器缓存中没找到，就在操作系统缓存中查找，这一步中也会查找本机的hosts看看有没有对应的域名映射（当然已经缓存在系统DNS缓存中了）&lt;/li&gt;
  &lt;li&gt;在系统中也没有的话，就到你的路由器来查找，因为路由器一般也会有自己的DNS缓存&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;如果以上都没有找到，则继续往下向dns域名服务器查询&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;用户电脑的解析器向LDNS（也就是Local   DNS，互联网服务提供商ISP），发起域名解析请求，查询www.google.com的IP地址，这是一个递归查找过程&lt;/li&gt;
  &lt;li&gt;在缓存没有命中的情况下，LDNS向根域名服务器.查询www.google.com的IP地址，LDNS的查询过程是一个迭代查询的过程&lt;/li&gt;
  &lt;li&gt;根告诉LDNS，我不知道www.google.com对应的IP，但是我知道你可以问com域的授权服务器，这个域归他管&lt;/li&gt;
  &lt;li&gt;LDNS向com的授权服务器问www.google.com对应的IP地址&lt;/li&gt;
  &lt;li&gt;com告诉LDNS，我不知道www.google.com对应的IP，但是我知道你可以问google.com域的授权服务器，这个域归他管&lt;/li&gt;
  &lt;li&gt;LDNS向google.com的授权服务器问www.google.com对应的IP地址&lt;/li&gt;
  &lt;li&gt;google.com查询自己的ZONE文件（也称区域文件记录），找到了www.google.com对应的IP地址，返回给LDNS&lt;/li&gt;
  &lt;li&gt;LDNS本地缓存一份记录，把结果返回给用户电脑的解析器&lt;/li&gt;
  &lt;li&gt;在这之后，用户电脑的解析器拿到结果后，缓存在自己操作系统DNS缓存中，同时返回给浏览器，浏览器依旧会缓存一段时间。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;  &lt;strong&gt;注意&lt;/strong&gt;，  &lt;br /&gt;域名查询时有可能是经过了CDN调度器的（如果有cdn存储功能的话）&lt;/p&gt;
 &lt;p&gt;而且，需要知道dns解析是很耗时的，因此如果解析域名过多，会让首屏加载变得过慢，可以考虑dns-prefetch优化&lt;/p&gt;
 &lt;h2&gt;tcp/ip请求&lt;/h2&gt;
 &lt;p&gt;有了 IP 地址，就可以通过 Socket API 来发送数据了，这时可以选择 TCP 或 UDP 协议。&lt;/p&gt;
 &lt;p&gt;http本质是tcp协议。&lt;/p&gt;
 &lt;p&gt;TCP是一种面向有连接的传输层协议。他可以保证两端（发送端和接收端）通信主机之间的通信可达。他能够处理在传输过程中丢包、传输顺序乱掉等异常情况；此外他还能有效利用宽带，缓解网络拥堵。&lt;/p&gt;
 &lt;p&gt;建立TCP连接一开始都要经过三次握手：&lt;/p&gt;
 &lt;p&gt;第一次握手，请求建立连接，发送端发送连接请求报文  &lt;br /&gt;第二次握手，接收端收到发送端发过来的报文，可知发送端现在要建立联机。然后接收端会向发送端发送一个报文&lt;/p&gt;
 &lt;p&gt;第三次握手，发送端收到了发送过来的报文，需要检查一下返回的内容是否是正确的；若正确的话，发送端再次发送确认包&lt;/p&gt;
 &lt;p&gt;在TCP连接建立完成之后就可以发送HTTP请求了。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;注意&lt;/strong&gt;  &lt;br /&gt;浏览器对同一个域名有连接数限制，大部分是 6，http1.0中往往一个资源下载就需要对应一个tcp/ip请求，而像 HTTP 2.0 协议尽管只使用一个 TCP 连接来传输数据，但性能反而更好，而且还能实现请求优先级。&lt;/p&gt;
 &lt;p&gt;参考文章：  &lt;br /&gt;  &lt;a href="http://fex.baidu.com/blog/2014/05/what-happen/" rel="nofollow noreferrer"&gt;http://fex.baidu.com/blog/201...&lt;/a&gt;  &lt;br /&gt;  &lt;a href="https://blog.csdn.net/dojiangv/article/details/51794535" rel="nofollow noreferrer"&gt;https://blog.csdn.net/dojiang...&lt;/a&gt;  &lt;br /&gt;  &lt;a href="https://segmentfault.com/a/1190000013662126#articleHeader17"&gt;https://segmentfault.com/a/11...&lt;/a&gt;&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>html css javascript</category>
      <guid isPermaLink="true">https://itindex.net/detail/58974-%E6%B5%8F%E8%A7%88%E5%99%A8-url-http</guid>
      <pubDate>Sun, 18 Nov 2018 16:33:45 CST</pubDate>
    </item>
    <item>
      <title>获取 DOM 元素的绝对位置</title>
      <link>https://itindex.net/detail/58288-dom-%E5%85%83%E7%B4%A0-%E7%BB%9D%E5%AF%B9%E4%BD%8D%E7%BD%AE</link>
      <description>&lt;p&gt;在操作页面滚动和动画时经常会获取 DOM 元素的绝对位置，
例如   &lt;a href="http://harttle.land/2018/04/22/get-dom-layout.html"&gt;本文&lt;/a&gt; 左侧的悬浮导航，当页面滚动到它以前会正常地渲染到文档流中，
当页面滚动超过了它的位置，就会始终悬浮在左侧。&lt;/p&gt;

 &lt;p&gt;本文会详述各种获取   &lt;strong&gt;DOM 元素绝对位置&lt;/strong&gt; 的方法以及对应的兼容性。
关于如何获取   &lt;strong&gt;DOM 元素高度和滚动高度&lt;/strong&gt;，请参考
  &lt;a href="http://harttle.land/2016/04/24/client-height-width.html"&gt;视口的宽高与滚动高度&lt;/a&gt; 一文。&lt;/p&gt;



 &lt;h1&gt;概述&lt;/h1&gt;

 &lt;p&gt;这些是本文涉及的 API 对应的文档和标准，供查阅：&lt;/p&gt;

 &lt;table&gt;
  
      &lt;tr&gt;
         &lt;th&gt;API&lt;/th&gt;
         &lt;th&gt;用途&lt;/th&gt;
         &lt;th&gt;文档&lt;/th&gt;
         &lt;th&gt;标准&lt;/th&gt;
    &lt;/tr&gt;
  
  
      &lt;tr&gt;
         &lt;td&gt;    &lt;code&gt;offsetTop&lt;/code&gt;&lt;/td&gt;
         &lt;td&gt;相对定位容器的位置&lt;/td&gt;
         &lt;td&gt;    &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop"&gt;MDN&lt;/a&gt;&lt;/td&gt;
         &lt;td&gt;    &lt;a href="https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsettop"&gt;CSSOM View Module&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;    &lt;code&gt;clientTop&lt;/code&gt;&lt;/td&gt;
         &lt;td&gt;上边框宽度&lt;/td&gt;
         &lt;td&gt;    &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/clientTop"&gt;MDN&lt;/a&gt;&lt;/td&gt;
         &lt;td&gt;    &lt;a href="https://drafts.csswg.org/cssom-view/#dom-element-clienttop"&gt;CSSOM View Module&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;    &lt;code&gt;.getBoundingClientRect()&lt;/code&gt;&lt;/td&gt;
         &lt;td&gt;元素大小和相对视口的位置&lt;/td&gt;
         &lt;td&gt;    &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect"&gt;MDN&lt;/a&gt;&lt;/td&gt;
         &lt;td&gt;    &lt;a href="https://drafts.csswg.org/cssom-view/#dom-element-getboundingclientrect"&gt;CSSOM View Module&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;    &lt;code&gt;.getClientRects()&lt;/code&gt;&lt;/td&gt;
         &lt;td&gt;所有子 CSS 盒子的大小和位置&lt;/td&gt;
         &lt;td&gt;    &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/getClientRects"&gt;MDN&lt;/a&gt;&lt;/td&gt;
         &lt;td&gt;    &lt;a href="https://drafts.csswg.org/cssom-view/#dom-element-getclientrects"&gt;CSSOM View Module&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;    &lt;code&gt;.getComputedStyle()&lt;/code&gt;&lt;/td&gt;
         &lt;td&gt;应用所有样式表和计算之后的 CSS 属性&lt;/td&gt;
         &lt;td&gt;    &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle"&gt;MDN&lt;/a&gt;&lt;/td&gt;
         &lt;td&gt;    &lt;a href="https://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/css.html#CSS-CSSview-getComputedStyle"&gt;DOM Level 2 Style&lt;/a&gt;     &lt;a href="https://drafts.csswg.org/cssom/#dom-window-getcomputedstyle"&gt;CSSOM&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  
&lt;/table&gt;

 &lt;h1&gt;offsetTop/offsetLeft&lt;/h1&gt;

 &lt;p&gt;  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop"&gt;HTMLElement.offsetTop&lt;/a&gt; 用来获取当前元素（不包括上边框）
相对于定位容器（positioning container）的位置。也就是说，&lt;/p&gt;

 &lt;ul&gt;
    &lt;li&gt;如果所有祖先元素都是静态定位    &lt;code&gt;position:static;&lt;/code&gt;（这是默认的情况），   &lt;code&gt;offsetTop&lt;/code&gt; 表示与文档最上方的高度差（文档最上方可能已经滚出视口，这个高度可能大于视口高度）。&lt;/li&gt;
    &lt;li&gt;如果存在绝对定位的祖先元素    &lt;code&gt;position:absolute/fixed&lt;/code&gt;，   &lt;code&gt;offsetTop&lt;/code&gt; 就会相对于这个元素。因此为了获取相对于文档最上方的高度差，需要递归地调用：&lt;/li&gt;
&lt;/ul&gt;

 &lt;div&gt;  &lt;div&gt;   &lt;pre&gt;    &lt;code&gt;function getOffsetTop(el){
    return el.offsetParent
        ? el.offsetTop + getOffsetTop(el.offsetParent)
        : el.offsetTop
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

 &lt;p&gt;  &lt;code&gt;el.offsetParent&lt;/code&gt; 是当前元素的定位容器（positioning container），
如果当前元素没有绝对定位的祖先节点，这个属性的值就是   &lt;code&gt;null&lt;/code&gt;。&lt;/p&gt;

 &lt;p&gt;兼容性和限制：几乎所有浏览器都支持该属性。如果元素被隐藏它的值就是 0，但在 IE9 下没有影响。&lt;/p&gt;

 &lt;h1&gt;clientTop/clientLeft&lt;/h1&gt;

 &lt;p&gt;不要被名字误导，  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/clientTop"&gt;Element.clientTop&lt;/a&gt; 是指当前元素的   &lt;strong&gt;上边框的宽度&lt;/strong&gt; 的整数值。
总是等于   &lt;code&gt;getComputedStyle()&lt;/code&gt; 返回的   &lt;code&gt;border-top-width&lt;/code&gt; 属性的四舍五入为整数后的值。&lt;/p&gt;

 &lt;p&gt;为什么呢？在 DOM 术语中，client 总是指除边框（border）外的渲染盒子（内边距+内容大小）。
offset 总是指包含边框的渲染盒子（边框+内边距+内容大小），
  &lt;code&gt;clientTop&lt;/code&gt; 即为这两者的 Top 之差，即边框宽度。盒子的概念请参考：
  &lt;a href="http://harttle.land/2015/05/28/css-display.html"&gt;CSS Display 属性与盒模型&lt;/a&gt;&lt;/p&gt;

 &lt;p&gt;兼容性和限制：同 offsetTop/offsetLeft&lt;/p&gt;

 &lt;h1&gt;.getBoundingClientRect()&lt;/h1&gt;

 &lt;p&gt;  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect"&gt;Element.getBoundingClientRect()&lt;/a&gt; 用于获取元素的大小，以及相对于视口（viewport）的位置，
返回一个   &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMRect"&gt;DOMRect&lt;/a&gt; 对象。&lt;/p&gt;

 &lt;div&gt;  &lt;div&gt;   &lt;pre&gt;    &lt;code&gt;&amp;gt; document.querySelector(&amp;apos;span&amp;apos;).getBoundingClientRect()
DOMRect {x: 2.890625, y: 218.890625, width: 1264, height: 110, top: 218.890625, …}
bottom: 328.890625
height: 110
left: 2.890625
right: 1266.890625
top: 218.890625
width: 1264
x: 2.890625
y: 218.890625
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

 &lt;p&gt;如果要获取相对于文档左上角的位置，需要在上述   &lt;code&gt;top&lt;/code&gt; 和   &lt;code&gt;left&lt;/code&gt; 的基础上再加滚动位置。
如下代码来自 MDN，可兼容几乎所有浏览器：&lt;/p&gt;

 &lt;div&gt;  &lt;div&gt;   &lt;pre&gt;    &lt;code&gt;// For scrollX
(((t = document.documentElement) || (t = document.body.parentNode))
  &amp;amp;&amp;amp; typeof t.scrollLeft == &amp;apos;number&amp;apos; ? t : document.body).scrollLeft
// For scrollY
(((t = document.documentElement) || (t = document.body.parentNode))
  &amp;amp;&amp;amp; typeof t.scrollTop == &amp;apos;number&amp;apos; ? t : document.body).scrollTop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

 &lt;p&gt;兼容性和限制：同样是 CSSOM View Module 的特性，但几乎兼容所有浏览器，可参考   &lt;a href="https://caniuse.com/#feat=getboundingclientrect"&gt;https://caniuse.com/#feat=getboundingclientrect&lt;/a&gt;
IE 下窗口的左上角可能不是 0,0，  &lt;a href="https://stackoverflow.com/questions/10230715/why-getboundingclientrect-gives-different-values-in-ie-and-firefox?utm_medium=organic&amp;utm_source=google_rich_qa&amp;utm_campaign=google_rich_qa"&gt;在 IE9 可以这样把它设置为 0,0&lt;/a&gt;：&lt;/p&gt;

 &lt;div&gt;  &lt;div&gt;   &lt;pre&gt;    &lt;code&gt;&amp;lt;meta http-equiv=&amp;quot;x-ua-compatible&amp;quot; content=&amp;quot;ie=edge&amp;quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

 &lt;h1&gt;.getClientRects()&lt;/h1&gt;

 &lt;p&gt;  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/getClientRects"&gt;Element.getClientRects()&lt;/a&gt; 用来获得 DOM 元素中的所有
  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model"&gt;CSS 盒模型&lt;/a&gt; 对应的   &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMRect"&gt;DOMRect&lt;/a&gt; 组成的集合。&lt;/p&gt;

 &lt;p&gt;如果是一个块级元素，返回的集合中应该只有一个元素，即这个块的大小和位置。
但如果是一个行内元素（或者 SVG 内的元素），则会返回其中每个 CSS 盒子。比如一个普通的被默认折行的   &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;：&lt;/p&gt;

 &lt;div&gt;  &lt;div&gt;   &lt;pre&gt;    &lt;code&gt;&amp;gt; document.querySelector(&amp;apos;span&amp;apos;).getClientRects()
DOMRectList {0: DOMRect, 1: DOMRect, 2: DOMRect, length: 5}
0: DOMRect {x: 2.890625, y: 262.890625, width: 1264, height: 22, top: 262.890625, …}
1: DOMRect {x: 2.890625, y: 284.890625, width: 1264, height: 22, top: 284.890625, …}
2: DOMRect {x: 2.890625, y: 306.890625, width: 768,  height: 22, top: 306.890625, …}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

 &lt;p&gt;这个   &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; 有三行，其中第三行的长度不足一行，每次折行都形成了一个新的 CSS 盒子。&lt;/p&gt;

 &lt;p&gt;兼容性和限制：在 IE8 及以下会返回 IE 独有的   &lt;code&gt;TextRectangle&lt;/code&gt; 对象（而不是   &lt;code&gt;ClientRect&lt;/code&gt;），
这个对象不具有   &lt;code&gt;width&lt;/code&gt; 和   &lt;code&gt;height&lt;/code&gt; 属性，而且无法给它设置属性。参考：
  &lt;a href="https://webplatform.github.io/docs/dom/HTMLElement/getClientRects/"&gt;https://webplatform.github.io/docs/dom/HTMLElement/getClientRects/&lt;/a&gt;&lt;/p&gt;

 &lt;h1&gt;.getComputedStyle()&lt;/h1&gt;

 &lt;p&gt;  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle"&gt;Window.getComputedStyle()&lt;/a&gt; 可以得到一个元素的所有计算后的 CSS 属性。
对于简单的绝对定位元素，可以通过这个 API 返回的   &lt;code&gt;top&lt;/code&gt;，  &lt;code&gt;left&lt;/code&gt; 等属性值获取元素的位置。
例如：&lt;/p&gt;

 &lt;div&gt;  &lt;div&gt;   &lt;pre&gt;    &lt;code&gt;let btn = document.querySelector(&amp;apos;#btn-scroll-up&amp;apos;)
let {top, left} = getComputedStyle(btn)
console.log(&amp;apos;top:&amp;apos;, top, &amp;apos;left:&amp;apos;, left)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

 &lt;p&gt;  &lt;code&gt;.getComputedStyle()&lt;/code&gt; 还有一个有用的用法，获取伪元素的大小和位置等样式信息：&lt;/p&gt;

 &lt;div&gt;  &lt;div&gt;   &lt;pre&gt;    &lt;code&gt;// 以下代码来自： https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
var h3 = document.querySelector(&amp;apos;h3&amp;apos;); 
var result = getComputedStyle(h3, &amp;apos;:after&amp;apos;).content;
console.log(&amp;apos;the generated content is: &amp;apos;, result); // returns &amp;apos; rocks!&amp;apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

 &lt;p&gt;兼容性和限制：  &lt;code&gt;.getComputedStyle()&lt;/code&gt; 几乎兼容所有浏览器，可参考   &lt;a href="https://caniuse.com/#search=getComputedStyle"&gt;https://caniuse.com/#search=getComputedStyle&lt;/a&gt;。
但它返回的值是 CSS 属性，用它获取绝对位置时要注意值的类型。
例如   &lt;code&gt;left&lt;/code&gt; 可能是   &lt;code&gt;13px&lt;/code&gt; 这样的绝对值，也可能是   &lt;code&gt;auto&lt;/code&gt; 这样的 CSS 关键字。&lt;/p&gt;

 &lt;h1&gt;总结&lt;/h1&gt;

 &lt;ul&gt;
    &lt;li&gt;获取 DOM 元素相对于文档的位置，可以直接使用    &lt;code&gt;offsetTop&lt;/code&gt;；&lt;/li&gt;
    &lt;li&gt;获取 DOM 元素相对于视口的位置，可以使用    &lt;code&gt;.getBoundingClientRect()&lt;/code&gt;；&lt;/li&gt;
    &lt;li&gt;获取 SVG 元素或行内元素的 CSS 盒子（比如用来做文本高亮时），可以使用    &lt;code&gt;.getClientRects()&lt;/code&gt;；&lt;/li&gt;
    &lt;li&gt;获取绝对定位元素、伪元素的渲染后 CSS 属性，可以使用    &lt;code&gt;.getComputedStyle()&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>DOM HTML CSS</category>
      <guid isPermaLink="true">https://itindex.net/detail/58288-dom-%E5%85%83%E7%B4%A0-%E7%BB%9D%E5%AF%B9%E4%BD%8D%E7%BD%AE</guid>
      <pubDate>Sun, 22 Apr 2018 08:00:00 CST</pubDate>
    </item>
    <item>
      <title>网站开发中的字体设置</title>
      <link>https://itindex.net/detail/58033-%E7%BD%91%E7%AB%99-%E5%BC%80%E5%8F%91-%E5%AD%97%E4%BD%93</link>
      <description>&lt;p&gt;字体的选择，是网页开发的关键因素之一。合适的字体，对网页的美观度（或可读性）有着举足轻重的影响。由于字体设置在代码实现上非常的简单，导致了大多数开发人员都没有重视。在前端、设计分工协助的状态下很容易导致字体设置成为三不管的状态。&lt;/p&gt;
 &lt;h2&gt;衬线体和无衬线体&lt;/h2&gt;
 &lt;p&gt;在西文（英文）字体中，最简单的字体分类方式是将字体分为衬线体（serif）与无衬线体（sans-serif）。其中sans在法语中的意思是“没有”。衬线体与无无衬线体的区分方式非常的简单，只需要判断文字的笔画开始部分或结束部分是否有装饰细节即可，如下图：&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" height="169" src="https://www.biaodianfu.com/wp-content/uploads/2018/02/serif-sans-serif.png" width="538"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;在印刷品的正文中，衬线体用的比较多。而在屏幕显示中更多的会采用无衬线体。主要原因是油墨印刷时，将油墨印刷到纸张上时，在没有非常精确的控制好油墨量时，非常容易造成文字变粗或变细，从而导致颜色太深或太淡，在阅读时产生疲惫。如果采用有棱角的衬线字体，可以使得文字笔画的开始或结束更加容易识别到，阅读效率会更高。而在电脑屏幕上，由于不涉及到油墨问题，衬线体在笔划上有过多的点缀很容易造成视觉疲劳。&lt;/p&gt;
 &lt;p&gt;另外，为了使得标题与正文形成差异，一般在使用与正文相反的字体。如在印刷品中标题采用无衬线体，由于标题要比一般的文字大或者粗，且不会大面积出现，所以采用无衬线体不会影响到阅读。同理，屏幕上的标题也不会大面积出现，采用衬线体也不会带来视觉疲劳。&lt;/p&gt;
 &lt;h2&gt;网页中的字体渲染&lt;/h2&gt;
 &lt;p&gt;在衬线体和非衬线体的介绍中谈到了字体的渲染，而字体的渲染又与各个操作系统有非常大的关联，为了更好的掌握字体在计算机屏幕上的应用，这里再来学习下字体渲染的相关知识。&lt;/p&gt;
 &lt;h3&gt;理想形状与三代渲染策略&lt;/h3&gt;
 &lt;p&gt;  &lt;img alt="" height="262" src="https://www.biaodianfu.com/wp-content/uploads/2018/02/font-rendering.png" width="527"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;理想形状&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;理想形状，如上图所示，指的是使用矢量图形描述出来的形状。当文字需要在屏幕上显示时，字体形状需要用一定数量的像素栅格来呈现。你可能已经注意到了，理想形状示意图里的字母e并不能和灰色的网格（可以理解为像素点）对应起来，尤其是曲线的边缘，只占了网格的一部分。理想的形状与实际呈现的现状受单位面积内的像素点影响，原理上像素密度越密，呈现效果与理想形状越接近。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;黑白渲染&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;黑白渲染是最早人们使用的渲染技术，这种渲染方式只使用黑白两种颜色来表达文字的形状。这种方法也被称为二值渲染（bi-level rendering）。目前打印机就仍在使用这种方法，由于打印机的高输出分辨率，打印的结果能很好地再现原图。但是在屏幕上，有限的像素（屏幕通常是72dpi，而印刷时通常使用300dpi。即印刷品的像素密度是屏幕的4倍）无法很好地传递字体形状的微妙之处。虽然我们无法分辨单个像素，但是肉眼仍可觉察到弧形轮廓线上的毛刺。即锯齿。这时字体渲染技术还处在初级阶段。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;灰度渲染&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;在上世纪90年代中期，操作系统开始采用非常巧妙的渲染手段。尽管屏幕的分辨率非常低，但是操作系统可以控制每个像素的明暗。这就可以在栅格化图像中存储更多信息。在灰度渲染模式下，处于字形边界上的像素变成灰色。该像素亮度取决于自身被理想字体形状所覆盖的面积比值所决定。这样，字体轮廓看起来就更平滑，字体设计的细节也得以再现。字体在屏幕上看起不仅清晰——而且还能体现字体本身特征及风格。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" height="263" src="https://www.biaodianfu.com/wp-content/uploads/2018/02/subpixel-rendering.png" width="527"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;亚像素渲染&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;亚像素渲染的重要特征是引入彩色像素。在液晶显示屏中，一个像素是由红绿蓝三个紧密排列的亚像素构成的，它们决定了这一像素的颜色和亮度。因为这些子像素非常小，以至于人眼无法察觉到他们是一个个独立的颜色点。与单纯的灰度渲染相比，水平方向的分辨率翻了三倍。竖笔的位置及粗细就可表现的更为精确，文本外观也就更为清晰。&lt;/p&gt;
 &lt;p&gt;参考链接：  &lt;a href="https://www.smashingmagazine.com/2012/04/a-closer-look-at-font-rendering/"&gt;https://www.smashingmagazine.com/2012/04/a-closer-look-at-font-rendering/&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;点阵字体与轮廓字体&lt;/h3&gt;
 &lt;p&gt;点阵字体（Bitmap Fonts）和轮廓字体（Outline Font）的区别其实和图片格式中的png8和png24的的区别很类似，点阵字体都是实色，没有过渡色，边缘锐利，而轮廓字体有过渡色，边缘也比较平滑。点阵字体类似上面的黑白渲染。我们日常使用的字体大部分为轮廓字体，在Windows操作系统中，宋体会在12px~17px的时候按照点阵方式呈现，但是起本质上还是轮廓字体只不过宋体内置了点阵信息而已。&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;点阵字体：本质上是点阵图片的集合。渲染极快，显示效果稳定，容易创建，在小字号、多笔画时渲染效果较好。视觉效果较差，不适合缩放。&lt;/li&gt;
  &lt;li&gt;轮廓字体：是向量图的集合，用 Bézier 曲线描述字形，适合缩放。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;常见的轮廓式字体格式可分为：PostScript、TrueType和OpenType。&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;PostScript由Adobe 开发，用三次 Bézier 曲线描述字形。私有 hinting，价格昂贵。质量高，适合打印专业质量的印刷出版物。又细分为Type1/Type3/CID 等类型。扩展名是.ps&lt;/li&gt;
  &lt;li&gt;TrueType是Apple 为对抗 Adobe 的 Type1 与 Microsoft 共同开发，用二次 Bézier 曲线描述字形，渲染较快。可内置点阵字体。在 Mac OS X 和 Windows 中是最常见的字体格式。扩展名是.ttf&lt;/li&gt;
  &lt;li&gt;OpenType源于Microsoft独自开发的TrueType Open，后 Adobe 加入开发，增加对 PostScript 轮廓的支持。是TrueType的升级版，最明显的一个好处就是可以在把PostScript字体嵌入到TrueType的软件中。
   &lt;ul&gt;
    &lt;li&gt;包含TureType字体的OpenType文件后缀名为.ttf&lt;/li&gt;
    &lt;li&gt;包含PostScript字体的OpenType文件缀名为.otf&lt;/li&gt;
    &lt;li&gt;包含两者的，后缀名为.ttc&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;总结：轮廓式字体的格式对网页呈现的影响并不是很大，仅做了解即可。&lt;/p&gt;
 &lt;h4&gt;不同操作系统的渲染区别&lt;/h4&gt;
 &lt;p&gt;了解完了三种字体渲染策略，我们来看一下各种操作系统对渲染方式的选择。首先要了解的是苹果与微软针对字体渲染的不同理念：苹果认为，字体渲染应尽可能还原字体的设计，即使代价是造成些许模糊。微软认为，字符的形状应和像素契合，以防止模糊，提高可读性，即便扭曲了字体的构造。技术上说，两者的主要区别是：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;Windows 默认是使用很重的 hinting（字体微调），直到 DirectWrite开始才禁用 horizontal hinting（水平微调）；而 Mac OS X 完全不用 hinting 信息，只在 vertical（垂直）方向做一些 autohint（自动调整）&lt;/li&gt;
  &lt;li&gt;Windows 关闭小字号的 antialiasing（反锯齿），直到 DirectWrite 才启用大字号的 vertical antialiasing（垂直方向反锯齿）；而 Mac OS X 默认要到非常小的字体才会关闭 antialiasing（反锯齿），大部分情况下都是启用的。&lt;/li&gt;
  &lt;li&gt;Windows 在 DirectWrite 之前没有subpixel positioning（亚像素定位）支持，而 Mac OS X 一直有，当然这个只影响间距。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;在Windows系统下，使用什么渲染技术取决于使用什么样的字体以及应用程序的设置。Windows系统有两套图形文字渲染接口，一个是GDI，另一个是Windows Vista之后推出的  &lt;a href="https://zh.wikipedia.org/wiki/DirectWrite"&gt;DirectWrite&lt;/a&gt;，用于取代老的GDI。严格来说，微软自己的亚像素渲染技术有另一个名字——  &lt;a href="https://msdn.microsoft.com/zh-cn/library/ms749295(v=vs.110).aspx"&gt;ClearType&lt;/a&gt;，这个技术与两套图形文字渲染接口是被包含的关系。&lt;/p&gt;
 &lt;p&gt;简单地说：Mac OS X 的字体渲染强调忠实字体设计，最大化保留字体的外形。边缘平滑是为了更好地传递字体设计中的曲线等细节，而小字号时显得模糊也是在此方针下的妥协。而 Windows 的字体渲染强调文字的锐利和清晰。在操作系统介面和网页正文等小字号的地方比较清晰，但大幅牺牲字体的原貌。&lt;/p&gt;
 &lt;p&gt;要想在Windows上是哟个Mac OS的渲染方式，可安装  &lt;a href="http://www.mactype.net/"&gt;MacType&lt;/a&gt;软件。&lt;/p&gt;
 &lt;p&gt;另外在iPhone或者安卓手机上找一个网页打开截屏，图片拿到电脑上不断放大后，你会发现手机上的字体渲染并没有使用亚像素渲染。最优可能的原因是减少CPU的使用。&lt;/p&gt;
 &lt;p&gt;同样，不同的渲染方式对网页呈现的影响并不是很大，仅做了解即可。&lt;/p&gt;
 &lt;h3&gt;英文字体分类&lt;/h3&gt;
 &lt;p&gt;英文字体的分类方式有很多中，在《写给大家看的设计书》这本书中，将英文字体主要分为了6类：&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" height="728" src="https://www.biaodianfu.com/wp-content/uploads/2018/02/type-catefory.png" width="560"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;Oldstyle：倾斜衬线+粗细过渡（对角线强调线），适合阅读。&lt;/li&gt;
  &lt;li&gt;Modern：水平衬线+剧烈的粗细过渡（垂直强调线），冷酷高雅，不太适合正文。&lt;/li&gt;
  &lt;li&gt;Slab Serif：Modern的变形版，水平衬线+粗细过渡变小或没有。有较好的可读性，常在儿童书籍中使用。&lt;/li&gt;
  &lt;li&gt;Sans Serif：无衬线+无粗细变化（无强调线）&lt;/li&gt;
  &lt;li&gt;Script：书法笔或者书法刷写出来的字&lt;/li&gt;
  &lt;li&gt;Decorative：装饰性字体。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;参考链接：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="https://www.fusionforward.com/6-common-font-categories/"&gt;https://www.fusionforward.com/6-common-font-categories/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://tympanus.net/codrops/2012/03/07/understanding-and-using-type-categories-in-web-design/"&gt;https://tympanus.net/codrops/2012/03/07/understanding-and-using-type-categories-in-web-design/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;h3&gt;中文字体分类&lt;/h3&gt;
 &lt;p&gt;同样，中文字体也有非常多的分类方法，这里简单的将中文字体分为如下四类：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;对比 Modulated（宋体、仿宋等所谓的中文「衬线体」）&lt;/li&gt;
  &lt;li&gt;等线 Monolinear（黑体）&lt;/li&gt;
  &lt;li&gt;书写 Handwritten（楷书、草书等书法字体）&lt;/li&gt;
  &lt;li&gt;图案 Graphic（偏几何图形的字体）&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;我们最常使用的是宋体和黑体：&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" height="335" src="https://www.biaodianfu.com/wp-content/uploads/2018/02/song-hei.png" width="500"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;传统型宋体：竖线粗、横线细、书写至结束的地方有一个类似三角形，名为“麟”的装饰&lt;/li&gt;
  &lt;li&gt;传统型黑体：横线和竖线宽度几乎相同的字体。&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;网页中的字体设置&lt;/h2&gt;
 &lt;p&gt;在网页中设置时，优先要考虑的是可读性，所以一般正文或长段的文字都采用无衬线字体，另外在标题上基本上会采用与正文有强烈对比的字体（也可以是字号和颜色的高对比度）。另外在网页中进行字体设置时最先需要考虑的是该字体是否在用户的操作系统中存在，如果没有，替代字体是什么？即设置安全字体。&lt;/p&gt;
 &lt;h3&gt;CSS中的字体设置项&lt;/h3&gt;
 &lt;p&gt;与字体有关的 CSS 属性，通常有以下几个：font-family、font-style、font-weight、font-size、line-height、letter-spacing、word-spacing、text-align、text-decoration。&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;font-family：用于定义字体，通过给定的顺序来选择，更详细的资料请看：   &lt;a href="http://www.w3school.com.cn/css/pr_font_font-family.asp"&gt;font-family&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;font-style：用于定义字体的样式，包括正常、斜体、倾斜等，对应的属性值为：normal(文本正常显示)、italic(文本斜体显示, 为单独设计的斜体字体)、oblique(文本倾斜显示，由普通字体变形而成)。&lt;/li&gt;
  &lt;li&gt;font-weight：用于定义文字的粗细，详细的属性值请看：    &lt;a href="http://www.w3school.com.cn/css/pr_font_weight.asp"&gt;font-weight&lt;/a&gt; 数值-样式名对照表如下：
   &lt;ul&gt;
    &lt;li&gt;100 – Thin&lt;/li&gt;
    &lt;li&gt;200 – Extra Light (Ultra Light)&lt;/li&gt;
    &lt;li&gt;300 – Light&lt;/li&gt;
    &lt;li&gt;400 – Normal&lt;/li&gt;
    &lt;li&gt;500 – Medium&lt;/li&gt;
    &lt;li&gt;600 – Semi Bold (Demi Bold)&lt;/li&gt;
    &lt;li&gt;700 – Bold&lt;/li&gt;
    &lt;li&gt;800 – Extra Bold (Ultra Bold)&lt;/li&gt;
    &lt;li&gt;900 – Black (Heavy)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
  &lt;li&gt;font-size：设置字体大小。&lt;/li&gt;
  &lt;li&gt;line-height：用于设置文字中的行间距，合适的行间距对用户阅读带来良好体验。同时还可以用于垂直布局单行文字。&lt;/li&gt;
  &lt;li&gt;letter-spacing：设置文字之间的字间距，使文字之间的距离增大或者减小。&lt;/li&gt;
  &lt;li&gt;word-spacing：用于调整单词的间距。&lt;/li&gt;
  &lt;li&gt;text-align：用来对齐文字，例如左对齐、右对齐、居中对齐等。&lt;/li&gt;
  &lt;li&gt;text-decoration：用来修饰一段文本，例如添加下划线等。常对 a 标签使用这个属性消除其默认的下划线。   &lt;a name="toc-17"&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;font 属性是设置 font-style, font-variant, font-weight, font-size, line-height 和 font-family属性的简写，详细资料请看：   &lt;a href="http://www.w3school.com.cn/css/pr_font_font.asp"&gt;CSS font 属性&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;h3&gt;操作系统字体区别&lt;/h3&gt;
 &lt;p&gt;操作系统所包含字体不只和系统预装的字体有关，还和系统上安装哪些软件有关，微软操作系统下，详细的系统和一些软件包含的字体可以查看这个索引：  &lt;a href="http://www.microsoft.com/typography/fonts/product.aspx"&gt;Microsoft typography&lt;/a&gt; ，Mac系统可以查看这个索引：  &lt;a href="http://en.wikipedia.org/wiki/List_of_Mac_OS_X_fonts"&gt;List of typefaces included with OS X&lt;/a&gt;。以下为各操作系统所在的中文字体：&lt;/p&gt;
 &lt;p&gt;Windows操作系统：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;黑体：SimHei&lt;/li&gt;
  &lt;li&gt;宋体：SimSun&lt;/li&gt;
  &lt;li&gt;新宋体：NSimSun&lt;/li&gt;
  &lt;li&gt;仿宋：FangSong&lt;/li&gt;
  &lt;li&gt;楷体：KaiTi&lt;/li&gt;
  &lt;li&gt;仿宋GB2312：FangSongGB2312&lt;/li&gt;
  &lt;li&gt;楷体GB2312：KaiTiGB2312&lt;/li&gt;
  &lt;li&gt;微软雅黑：Microsoft YaHei （Windows 7开始提供）&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;如果用户装了MicroSoft Office，还会多出一些字体：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;隶书：LiSu&lt;/li&gt;
  &lt;li&gt;幼圆：YouYuan&lt;/li&gt;
  &lt;li&gt;华文细黑：STXihei&lt;/li&gt;
  &lt;li&gt;华文楷体：STKaiti&lt;/li&gt;
  &lt;li&gt;华文宋体：STSong&lt;/li&gt;
  &lt;li&gt;华文中宋：STZhongsong&lt;/li&gt;
  &lt;li&gt;华文仿宋：STFangsong&lt;/li&gt;
  &lt;li&gt;方正舒体：FZShuTi&lt;/li&gt;
  &lt;li&gt;方正姚体：FZYaoti&lt;/li&gt;
  &lt;li&gt;华文彩云：STCaiyun&lt;/li&gt;
  &lt;li&gt;华文琥珀：STHupo&lt;/li&gt;
  &lt;li&gt;华文隶书：STLiti&lt;/li&gt;
  &lt;li&gt;华文行楷：STXingkai&lt;/li&gt;
  &lt;li&gt;华文新魏：STXinwei&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;OS X操作系统：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;冬青黑体: Hiragino Sans GB （SNOW LEOPARD开始提供）&lt;/li&gt;
  &lt;li&gt;华文细黑：STHeiti Light （又名STXihei）&lt;/li&gt;
  &lt;li&gt;华文黑体：STHeiti&lt;/li&gt;
  &lt;li&gt;华文楷体：STKaiti&lt;/li&gt;
  &lt;li&gt;华文宋体：STSong&lt;/li&gt;
  &lt;li&gt;华文仿宋：STFangsong&lt;/li&gt;
  &lt;li&gt;苹方：PingFang（OS X El Capitan开始提供）&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;Linux操作系统：（每个发行版都有些差别）&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;文泉驿点阵宋体&lt;/li&gt;
  &lt;li&gt;文泉驿正黑&lt;/li&gt;
  &lt;li&gt;文泉驿微米黑&lt;/li&gt;
&lt;/ul&gt;
 &lt;h3&gt;font-family的设置&lt;/h3&gt;
 &lt;p&gt;在设置font-family是为了保障在页面上能够合适的呈现，通常需要考虑各种操作系统。如下是我整理的font-family。&lt;/p&gt;
 &lt;p&gt;font-family: system, -apple-system, BlinkMacSystemFont, “Segoe UI”, “Roboto”, “Droid Sans”, “Ubuntu”,”Oxygen”, “Cantarell”, “Helvetica Neue”,Arial, “Hiragino Sans GB”, “PingFang SC”,”Heiti SC”, “Microsoft YaHei UI”, “Microsoft YaHei”, “Source Han Sans”, “Noto Sans CJK SC” , “WenQuanYi Micro Hei”,sans-serif, “Apple Color Emoji”,”Segoe UI Emoji”,”Segoe UI Symbol”;&lt;/p&gt;
 &lt;p&gt;这个列表非常的长，这里来讲解什么意思：&lt;/p&gt;
 &lt;p&gt;第一组：映射系统 UI 字体&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;system ：将来有可能成为标准，-apple- 为过渡阶段的厂商前缀&lt;/li&gt;
  &lt;li&gt;-apple-system：macOS 和 iOS 平台的 Safari 指向 San Francisco，更老版本的 macOS 指向 Neue Helvetica 和 Lucida Grande&lt;/li&gt;
  &lt;li&gt;BlinkMacSystemFont：为 macOS Chrome 应用系统 UI 字体，与上面等同&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;第二组：定义英文字体&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;“Segoe UI”：面向 Windows 和 Windows Phone&lt;/li&gt;
  &lt;li&gt;“Roboto”：Android 及 较新的 Chrome OS&lt;/li&gt;
  &lt;li&gt;“Droid Sans”：面向老版本 Android&lt;/li&gt;
  &lt;li&gt;“Ubuntu”：Ubuntu操作系统&lt;/li&gt;
  &lt;li&gt;“Oxygen”：KED桌面字体&lt;/li&gt;
  &lt;li&gt;“Cantarell”：GNOME桌面字体&lt;/li&gt;
  &lt;li&gt;“Helvetica Neue”：El Capitan 之前的 macOS 系统 UI 字体&lt;/li&gt;
  &lt;li&gt;Arial：Windows自带字体&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;第三组：定义中文字体&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;“Hiragino Sans GB”：冬青黑体（苹果操作系统）&lt;/li&gt;
  &lt;li&gt;“PingFang SC”：苹方（苹果操作系统）&lt;/li&gt;
  &lt;li&gt;“Heiti SC”：黑体-简（苹果操作系统）&lt;/li&gt;
  &lt;li&gt;“Microsoft YaHei UI”：微软雅黑（行间距比普通版小一点）&lt;/li&gt;
  &lt;li&gt;“Microsoft YaHei”：微软雅黑&lt;/li&gt;
  &lt;li&gt;“Source Han Sans”：思源黑体（Android系统）&lt;/li&gt;
  &lt;li&gt;“Noto Sans CJK SC”：思源黑体别名&lt;/li&gt;
  &lt;li&gt;“WenQuanYi Micro Hei”：文泉驿微米黑（Linux系统）&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;第四组：字体回退&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;sans-serif：不是某个字体的名称，而是一种在前面叙述的字体都无效时而最终选用的字体，称为浏览器通用字体，它取决于你所用的浏览器默认的通用字体是什么，可能是“Arial”，也有可能是“Helvetica”。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;第五组：定义emoji表情或符号&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;“Apple Color Emoji”,&lt;/li&gt;
  &lt;li&gt;“Segoe UI Emoji”,&lt;/li&gt;
  &lt;li&gt;“Segoe UI Symbol”;&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;在设置font-family是，需要特别注意的点：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;英文字体应该在中文字体之前：绝大部分中文字体里包含英文字母（但是基本上都很丑）&lt;/li&gt;
  &lt;li&gt;Mac字体要放在Win前面：大部分Mac用户会去安装Windows字体，反之就很少。&lt;/li&gt;
&lt;/ul&gt;
 &lt;h3&gt;CSS3中的@font-face&lt;/h3&gt;
 &lt;p&gt;@font-face是CSS3中的一个模块，他主要是把自己定义的Web字体嵌入到你的网页中著作权归作者所有。在 CSS3 之前，web 设计师必须使用已在用户计算机上安装好的字体。通过 CSS3，web 设计师可以使用他们喜欢的任意字体。&lt;/p&gt;
 &lt;p&gt;@font-face的语法规则：&lt;/p&gt; &lt;pre&gt;@font-face {
    font-family: &amp;lt;YourWebFontName&amp;gt;;
    src: &amp;lt;source&amp;gt; [&amp;lt;format&amp;gt;][,&amp;lt;source&amp;gt; [&amp;lt;format&amp;gt;]]*;
    [font-weight: &amp;lt;weight&amp;gt;];
    [font-style: &amp;lt;style&amp;gt;];
}&lt;/pre&gt; &lt;p&gt;取值说明&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;YourWebFontName:此值指的就是你自定义的字体名称，最好是使用你下载的默认字体，他将被引用到你的Web元素中的font-family。如“font-family:”YourWebFontName”;”&lt;/li&gt;
  &lt;li&gt;source:此值指的是你自定义的字体的存放路径，可以是相对路径也可以是绝路径；&lt;/li&gt;
  &lt;li&gt;format：此值指的是你自定义的字体的格式，主要用来帮助浏览器识别，其值主要有以下几种类型：truetype,opentype,truetype-aat,embedded-opentype,avg等；&lt;/li&gt;
  &lt;li&gt;weight和style:这两个值大家一定很熟悉，weight定义字体是否为粗体，style主要定义字体样式，如斜体。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;@font-face法语目前在大部分浏览器上都能支持，但是存在不同的系统和浏览器支持不同的字体类型：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;TureTpe(.ttf)格式：.ttf字体是Windows和Mac的最常见的字体，是一种RAW格式，因此他不为网站优化,支持这种字体的浏览器有IE9+,Firefox3.5+,Chrome4+,Safari3+,Opera10+,iOS Mobile Safari4.2+&lt;/li&gt;
  &lt;li&gt;OpenType(.otf)格式：.otf字体被认为是一种原始的字体格式，其内置在TureType的基础上，所以也提供了更多的功能,支持这种字体的浏览器有5+,Chrome4.0+,Safari3.1+,Opera10.0+,iOS Mobile Safari4.2+&lt;/li&gt;
  &lt;li&gt;Web Open Font Format(.woff)格式：.woff字体是Web字体中最佳格式，他是一个开放的TrueType/OpenType的压缩版本，同时也支持元数据包的分离,支持这种字体的浏览器有IE9+,Firefox3.5+,Chrome6+,Safari3.6+,Opera11.1+&lt;/li&gt;
  &lt;li&gt;Web Open Font Format 2.0（.woff2）格式，相比woff最大的优化应该是加强了字体的压缩比。目前支持的浏览器最新的Chrome和Firefox。&lt;/li&gt;
  &lt;li&gt;Embedded Open Type(.eot)格式：.eot字体是IE专用字体，可以从TrueType创建此格式字体,支持这种字体的浏览器有IE4+&lt;/li&gt;
  &lt;li&gt;SVG(.svg)格式：.svg字体是基于SVG字体渲染的一种格式,支持这种字体的浏览器有Chrome4+,Safari3.1+,Opera10.0+,iOS Mobile Safari3.2+&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;字体文件格式转化工具：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="https://everythingfonts.com/"&gt;https://everythingfonts.com/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://font-spider.org/"&gt;http://font-spider.org/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;根据上面的信息@font-face中我们至少需要.woff、.eot两种格式字体，甚至还需要.svg等字体达到更多种浏览版本的支持。&lt;/p&gt;
 &lt;p&gt;为了使@font-face达到更多的浏览器支持，  &lt;a href="http://paulirish.com/"&gt;Paul Irish&lt;/a&gt;写了一个独特的@font-face语法叫  &lt;a href="http://paulirish.com/2009/bulletproof-font-face-implementation-syntax/"&gt;Bulletproof @font-face&lt;/a&gt;:&lt;/p&gt; &lt;pre&gt;@font-face {
    font-family: &amp;apos;YourWebFontName&amp;apos;;
    src: url(&amp;apos;YourWebFontName.eot?&amp;apos;) format(&amp;apos;eot&amp;apos;);/*IE*/
    src:url(&amp;apos;YourWebFontName.woff&amp;apos;) format(&amp;apos;woff&amp;apos;), url(&amp;apos;YourWebFontName.ttf&amp;apos;) format(&amp;apos;truetype&amp;apos;);/*non-IE*/
}&lt;/pre&gt; &lt;p&gt;为了让各多的浏览器支持，也可以写成：&lt;/p&gt; &lt;pre&gt;@font-face {
    font-family: &amp;apos;YourWebFontName&amp;apos;;
    src: url(&amp;apos;YourWebFontName.eot&amp;apos;); /* IE9 Compat Modes */
    src: url(&amp;apos;YourWebFontName.eot?#iefix&amp;apos;) format(&amp;apos;embedded-opentype&amp;apos;), /* IE6-IE8 */
        url(&amp;apos;YourWebFontName.woff&amp;apos;) format(&amp;apos;woff&amp;apos;), /* Modern Browsers */
        url(&amp;apos;YourWebFontName.ttf&amp;apos;)  format(&amp;apos;truetype&amp;apos;), /* Safari, Android, iOS */
        url(&amp;apos;YourWebFontName.svg#YourWebFontName&amp;apos;) format(&amp;apos;svg&amp;apos;); /* Legacy iOS */
}&lt;/pre&gt; &lt;p&gt;@font-face的功能虽然很强大，但是在使用的时候还是会存在问题。目前主要遇到的问题是中文字体太大。相较于英文字体只需要字、标点、英文字母，中文有上万个不同的文字，字体文件通常十几M，这样大的文字直接应用在网页上将会大大的影响网页的性能，所以@font-face在中文网站上使用到的非常的少。对于少量的使用（比如使用中文Logo），通常会制作精简版的字体。&lt;/p&gt;
 &lt;p&gt;另外，目前有两家公司提供中文 WebFont 云托管服务，他们能够压缩与转码字体：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="http://www.youziku.com"&gt;http://www.youziku.com&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://cn.justfont.com"&gt;http://cn.justfont.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;h3&gt;font-size字体大小的选择&lt;/h3&gt;
 &lt;p&gt;  &lt;strong&gt;字体大小的单位&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;在 CSS 中，最常用的描述字体大小的单位有两个：em、px。通常认为 em 为相对大小单位，px 为绝对大小单位。但从实际应用中来讲，px 像素其实也是一种相对大小单位。例如，在一块15寸分辨率为 800×600 像素的屏幕上，10px 大小的文字，要比一块10寸分辨率 1024×768 像素的屏幕上的 10px 大小的文字显得更大一些。&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;strong&gt;px&lt;/strong&gt;：像素单位，10px 表示10个像素大小，在现在的网页设计中，常被用来表示字体大小。很方便很直观，但是有一些弊端。对于可用性不太友好，因为是“绝对”单位，所以有些浏览器（早期）的字体放大缩小功能失效。浏览器的默认字体大小为 16px ，早期的网页，由于屏幕分辨率比较低，通常采用12px作为网页正文的标准字体大小。但是在现在，感觉有点偏小，比较长的文章来说，浏览者看起来费劲。&lt;/li&gt;
  &lt;li&gt;   &lt;strong&gt;em&lt;/strong&gt;：相对大小，它表示的字体大小不固定，根据基础字体大小进行相对大小的处理。浏览器默认的字体大小为 16px，如果你对一段文字指定 1em，那么表现出来的就是 16px大小，2em 就是 32px 大小。相对大小单位有很广泛的用途，由于它的相对性，所以对跨平台跨设备的字体大小处理上有得天独厚的优势，同时对于响应式的布局设计也有很大的帮助。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;更多信息请查看：  &lt;a href="https://www.biaodianfu.com/css-font-size.html"&gt;https://www.biaodianfu.com/css-font-size.html&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;字体大小的选择&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;通过上面的单位介绍，对于 px 单位中，举得例子都是 12px、14px、16px、18px等等，为啥不是11px、15px？这涉及到一个锯齿的问题，特别是在早期的显示器中，往往不能很好的处理文字的锯齿问题，而使用单数的像素，极有可能造成锯齿，所以默认的通常使用偶数大小。Windows 自带的点阵宋体从 Vista 开始只提供 12、14、16 px 这三个大小的点阵，而 13、15、17 px 时用的是小一号的点阵（即每个字占的空间大了 1 px，但点阵没变） 。对于13、15、17px的宋体，其大小与其小一号一样，只是间距多了1px。所以在Photoshop中所使用的13、15、17px宋体并不能在web上正常还原，设计时应避免使用13、15、17px的宋体。推荐的字体大小：正文16px，标题22px。&lt;/p&gt;
 &lt;h2&gt;总结&lt;/h2&gt;
 &lt;p&gt;字体设置涉及到的知识点非常的庞大，整理的时候只涉及到了皮毛，前端开发人员和设计人员可以好好的再进行深入研究。&lt;/p&gt;
 &lt;p&gt;The post   &lt;a href="https://www.biaodianfu.com/css-font.html" rel="nofollow"&gt;网站开发中的字体设置&lt;/a&gt; appeared first on   &lt;a href="https://www.biaodianfu.com" rel="nofollow"&gt;标点符&lt;/a&gt;.&lt;/p&gt;
 &lt;div&gt;
  &lt;p&gt;Related posts:&lt;/p&gt;  &lt;ol&gt;
   &lt;li&gt;    &lt;a href="https://www.biaodianfu.com/google-crawl-sched.html" rel="bookmark" title="Google Search Appliance &amp;#20027;&amp;#26426;&amp;#36127;&amp;#36733;&amp;#35745;&amp;#21010;"&gt;Google Search Appliance 主机负载计划 &lt;/a&gt;&lt;/li&gt;
   &lt;li&gt;    &lt;a href="https://www.biaodianfu.com/serve-keymatch.html" rel="bookmark" title="Google Search Appliance &amp;#20851;&amp;#38190;&amp;#23383;&amp;#21305;&amp;#37197;"&gt;Google Search Appliance 关键字匹配 &lt;/a&gt;&lt;/li&gt;
   &lt;li&gt;    &lt;a href="https://www.biaodianfu.com/web-font.html" rel="bookmark" title="Web&amp;#24320;&amp;#21457;&amp;#20013;&amp;#30340;&amp;#23383;&amp;#20307;&amp;#35774;&amp;#32622;"&gt;Web开发中的字体设置 &lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;  &lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>产品设计 程序开发 CSS 前端技术 字体</category>
      <guid isPermaLink="true">https://itindex.net/detail/58033-%E7%BD%91%E7%AB%99-%E5%BC%80%E5%8F%91-%E5%AD%97%E4%BD%93</guid>
      <pubDate>Fri, 09 Feb 2018 07:59:49 CST</pubDate>
    </item>
    <item>
      <title>现代浏览器性能优化-CSS篇</title>
      <link>https://itindex.net/detail/57837-%E7%8E%B0%E4%BB%A3-%E6%B5%8F%E8%A7%88%E5%99%A8-%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96</link>
      <description>&lt;p&gt;我来填坑了，CSS篇终于写出来了，如果你没看过前面的JS篇，可以  &lt;a href="https://github.com/GeoffZhu/geoffzhu.github.io/issues/2"&gt;在这里观看&lt;/a&gt;。&lt;/p&gt;
 &lt;blockquote&gt;众所周知，CSS的加载会阻塞浏览器渲染或是引起浏览器重绘，目前业界普遍推荐把CSS放到  &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;中，防止在CSS还没加载完，DOM就已经绘制出来了，造成CSS加载完成后的重绘。那在现代浏览器中我们有没有办法提高首屏渲染速度那？&lt;/blockquote&gt;
 &lt;p&gt;你是不是经常在第一次打开某个网站的时候看到这种情况，本来的页面是这样的  &lt;br /&gt;  &lt;img alt="" src="https://segmentfault.com/img/remote/1460000012643588?w=1574&amp;h=698" title=""&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;实际上刚加载出来的是这样的  &lt;br /&gt;  &lt;img alt="" src="https://segmentfault.com/img/remote/1460000012643589" title=""&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;字体文件没加载出来，或者加载的太慢了&lt;/p&gt;
 &lt;h2&gt;理解CSS解析过程&lt;/h2&gt;
 &lt;p&gt;以下面这段HTML为例，解释一遍CSS加载解析的过程。&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;!-- headStyle.css中存在字体文件webfont.woff2 --&amp;gt;
  &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/headStyle.css&amp;quot;&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;p&amp;gt;Text&amp;lt;/p&amp;gt;
  &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/bodyEndStyle.css&amp;quot;&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;浏览器自上而下读取HTML文档，当发现headStyle.css的时候，停止Parser HTML，开始下载headStyle.css，解析headStyle.css的过程中发现字体文件webfont.woff2，开始下载webfont.woff2，并继续解析css生成CSSStyleSheet。解析完毕后，继续Parser HTML，当发现p标签时，会将p标签结合当前的CSSStyleSheet展示出来，此时用户屏幕中已经有p标签的内容了。当浏览器发现bodyEndStyle.css时，就会下载headStyle.css，解析CSS，然后更新CSSStyleSheet，这时会引起一次重绘。当字体下载完毕的时候也会引起一次重绘。&lt;/p&gt;
 &lt;p&gt;这个过程中，有两个非常严重的问题。一、如果headStyle.css文件很大，浏览器需要解析很多行CSS后才能还有个字体文件需要下载，其实此时已经很晚了，字体下载时间稍长一点，就会出现我前面截图提到的问题。二、bodyEndStyle.css中如果存在p标签对应的样式，那p标签的样式会在bodyEndStyle.css解析完成后，改变一次样式，很影响体验。&lt;/p&gt;
 &lt;p&gt;如何解决这些问题那？其中也会用到一些JS篇中提到的点，如果没看过，建议先看看。&lt;/p&gt;
 &lt;h2&gt;优化核心依旧是减少下载时间&lt;/h2&gt;
 &lt;p&gt;JS篇中的预先解析DNS（dns-prefetch）依旧适用，提前解析CSS文件所在域名的DNS。&lt;/p&gt;
 &lt;h4&gt;Preload&lt;/h4&gt;
 &lt;p&gt;因为CSS已经在head中，我们不需要为css加preload属性了，但是css中用到的字体文件，一定要在所有css之前proload上。&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;&amp;lt;link rel=&amp;quot;preload&amp;quot; href=&amp;quot;/webfont.woff2&amp;quot; as=&amp;quot;font&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;h4&gt;首页CSS内联，非必要CSS异步加载&lt;/h4&gt;
 &lt;p&gt;首页用到的CSS内联写在  &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;中，其余CSS均采用异步加载，可以采用这种自己实现的加载CSS的方法，在合适的需要时加载需要的css&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;function LoadStyle(url) {
  try {
    document.createStyleSheet(url)
  } catch(e) {
    var cssLink = document.createElement(&amp;apos;link&amp;apos;);
    cssLink.rel = &amp;apos;stylesheet&amp;apos;;
    cssLink.type = &amp;apos;text/css&amp;apos;;
    cssLink.href = url;
    var head = document.getElementsByTagName(&amp;apos;head&amp;apos;)[0];
    head.appendChild(cssLink)
  }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;如果你使用webpack，那就更轻松了，使用import函数，大致如下&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;// 在a.js模块中直接引入css
import &amp;apos;style.css&amp;apos;&lt;/code&gt;&lt;/pre&gt;
 &lt;pre&gt;  &lt;code&gt;// 在需要a.js模块的地方
improt(&amp;apos;path-of-a.js&amp;apos;).then(module =&amp;gt; {})&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;webpack打包后，其实是把style.css打包进了a.js，在异步加载a.js的时候，会将style.css中的代码插入  &lt;code&gt;haed&lt;/code&gt;标签中。&lt;/p&gt;
 &lt;h2&gt;终极完美结构&lt;/h2&gt;
 &lt;pre&gt;  &lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;
  &amp;lt;title&amp;gt;Faster&amp;lt;/title&amp;gt;
  &amp;lt;link rel=&amp;quot;dns-prefetch&amp;quot; href=&amp;quot;//cdn.cn/&amp;quot;&amp;gt;

  &amp;lt;link rel=&amp;quot;preload&amp;quot; href=&amp;quot;//cdn.cn/webfont.woff2&amp;quot; as=&amp;quot;font&amp;quot;&amp;gt;
  &amp;lt;link rel=&amp;quot;preload&amp;quot; href=&amp;quot;//cdn.cn/Page1-A.js&amp;quot; as=&amp;quot;script&amp;quot;&amp;gt;
  &amp;lt;link rel=&amp;quot;preload&amp;quot; href=&amp;quot;//cdn.cn/Page1-B.js&amp;quot; as=&amp;quot;script&amp;quot;&amp;gt;
  
  &amp;lt;link rel=&amp;quot;prefetch&amp;quot; href=&amp;quot;//cdn.cn/Page2.js&amp;quot;&amp;gt;
  &amp;lt;link rel=&amp;quot;prefetch&amp;quot; href=&amp;quot;//cdn.cn/Page3.js&amp;quot;&amp;gt;
  &amp;lt;link rel=&amp;quot;prefetch&amp;quot; href=&amp;quot;//cdn.cn/Page4.js&amp;quot;&amp;gt;

  &amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;
    /* 首页用到的CSS内联 */
  &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;//cdn.cn/Page1-A.js&amp;quot; defer&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;//cdn.cn/Page1-B.js&amp;quot; defer&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;在  &lt;a href="https://segmentfault.com/blogs#"&gt;JS篇&lt;/a&gt;)中，我已经解释过这套结构中JS的执行顺序了，本篇只是加入了CSS和字体。至此，我心中终极完美的页面HTML结构就是这样了。&lt;/p&gt;
 &lt;p&gt;如果你对异步加载CSS的方案感兴趣，欢迎留言与我讨论！&lt;/p&gt;
 &lt;h2&gt;扩展阅读&lt;/h2&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="https://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/#Webkit_CSS_parser"&gt;浏览器的工作原理&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://www.jianshu.com/p/24ffa6d45087"&gt;关于Preload, 你应该知道些什么？&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://juejin.im/post/58e8acf10ce46300585a7a42"&gt;Preload，Prefetch 和它们在 Chrome 之中的优先级&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>性能优化 javascript css html</category>
      <guid isPermaLink="true">https://itindex.net/detail/57837-%E7%8E%B0%E4%BB%A3-%E6%B5%8F%E8%A7%88%E5%99%A8-%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96</guid>
      <pubDate>Fri, 29 Dec 2017 19:00:56 CST</pubDate>
    </item>
    <item>
      <title>页面架构HTML+CSS ●▽● 各种布局各种实现</title>
      <link>https://itindex.net/detail/56867-%E9%A1%B5%E9%9D%A2-%E6%9E%B6%E6%9E%84-html</link>
      <description>&lt;h1&gt;CSS Reset&lt;/h1&gt;
 &lt;h2&gt;1.作用&lt;/h2&gt;
 &lt;p&gt;（1）清除浏览器默认样式  &lt;br /&gt;（2）全局样式定义&lt;/p&gt;
 &lt;h2&gt;2.特别注意&lt;/h2&gt;
 &lt;p&gt;（1）项目开发初期就定义好  &lt;br /&gt;（2）  &lt;code&gt;reset.css&lt;/code&gt; 在引入的时候一定要放在第一位  &lt;br /&gt;（3）不同的产品  &lt;code&gt;reset.css&lt;/code&gt;不一样&lt;/p&gt;
 &lt;h2&gt;3.table合并边框间距&lt;/h2&gt;
 &lt;pre&gt;  &lt;code&gt;table {
  border-collapse: collapse; // 合并边框
  border-spacing: 0; //边框间距。当 `border-collapse` 值为 `seperate` 时生效

}
&lt;/code&gt;&lt;/pre&gt;
 &lt;h2&gt;4.一个并不完整也并不通用的reset.css样例&lt;/h2&gt;
 &lt;pre&gt;  &lt;code&gt;    html,body,h1,h2,h3,h4,h5,h6,div,dl,dt,dd,ul,ol,li,p,blockquote,pre,hr,figure,table,caption,th,td,form,fieldset,legend,input,button,textarea,menu{margin:0;padding:0;}
    header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:block;}
    table{border-collapse:collapse;border-spacing:0;}
    caption,th{text-align:left;font-weight:normal;}
    html,body,fieldset,img,iframe,abbr{border:0;}
    i,cite,em,var,address,dfn{font-style:normal;}
    [hidefocus],summary{outline:0;}
    li{list-style:none;}
    h1,h2,h3,h4,h5,h6,small{font-size:100%;}
    sup,sub{font-size:83%;}
    pre,code,kbd,samp{font-family:inherit;}
    q:before,q:after{content:none;}
    textarea{overflow:auto;resize:none;}
    label,summary{cursor:default;}
    a,button{cursor:pointer;}
    h1,h2,h3,h4,h5,h6,em,strong,b{font-weight:normal;}
    del,ins,u,s,a,a:hover{text-decoration:none;}
    body,textarea,input,button,select,keygen,legend{font:12px/1.14 arial,simsun;color:#333;outline:0;}
    body{background:#fff;}
    a,a:hover{color:#333;}&lt;/code&gt;&lt;/pre&gt;
 &lt;h1&gt;布局解决方案&lt;/h1&gt;
 &lt;h2&gt;居中布局&lt;/h2&gt;
 &lt;h3&gt;1.水平居中&lt;/h3&gt;
 &lt;p&gt;父元素和子元素宽度未知。&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;&amp;lt;div class=&amp;quot;parent&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;child&amp;quot;&amp;gt;child&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;要达到的效果是这样：  &lt;br /&gt;  &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://segmentfault.com/img/bVMh18?w=588&amp;h=121" title="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h4&gt;方法一：flex + justify-content&lt;/h4&gt;
 &lt;p&gt;主要代码：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;.parent { 
  display: flex;
  justify-content: center;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;没啥好解释，直接看   &lt;a href="https://jsfiddle.net/DarcyAn/tz62nf4L/"&gt;神奇的flex实现栗子&lt;/a&gt; 吧 (~￣▽￣)~&lt;/p&gt;
 &lt;h4&gt;方法二：absolute + transform&lt;/h4&gt;
 &lt;p&gt;主要代码：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;.parent { position: relative; }
.child { 
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;原理是：  &lt;code&gt;left: 50%;&lt;/code&gt;在子元素的左侧添加了一段距离，这段距离是父元素宽度的50%，接着因为translateX(50%) 设置百分比时的参照物是自身宽度，所以向左偏移了自身宽度的50%，就居中啦  ╮(‵▽′)╭ &lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/0nrw7s4w/"&gt;动动小手看看栗子&lt;/a&gt;&lt;/p&gt;
 &lt;h4&gt;方法三：inline-block + text-align&lt;/h4&gt;
 &lt;p&gt;主要代码：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;.parent { text-align: center; }
.child { display: inline-block; }&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;这种方法有一个问题是：  &lt;code&gt;parent&lt;/code&gt;设置了  &lt;code&gt;text-align: center;&lt;/code&gt;后， 因为这个属性可继承，会导致  &lt;code&gt;child&lt;/code&gt;中的文字也会居中，而这个效果是我们未必需要的，所以我们很多时候需要在  &lt;code&gt;.child&lt;/code&gt;中加一句   &lt;code&gt;text-align: left;&lt;/code&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/e8ns3qnx/"&gt;自己看看栗子&lt;/a&gt;&lt;/p&gt;
 &lt;h4&gt;方法四：table + margin&lt;/h4&gt;
 &lt;p&gt;主要代码：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;.child { display: table; margin: 0 auto; }&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;table的特点：宽度为内容宽度 的  &lt;strong&gt;块状元素&lt;/strong&gt;，所以也可以用  &lt;code&gt;margin: 0 auto;&lt;/code&gt;居中。&lt;/p&gt;
 &lt;p&gt;优点：只设置子元素样式就可以了，不需关心父元素。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/c0krtduf/"&gt;看看栗子&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;不喜欢这第四个方案，table是辣么有语义的一个样式，为什么随便把人家变成table (￣.￣)&lt;/p&gt;
 &lt;h3&gt;2.垂直居中&lt;/h3&gt;
 &lt;p&gt;父元素和子元素高度未知。&lt;/p&gt;
 &lt;p&gt;意欲达到的效果：&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://segmentfault.com/img/bVMh5R?w=117&amp;h=317" title="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h4&gt;方法一：flex+ align-items&lt;/h4&gt;
 &lt;pre&gt;  &lt;code&gt;.parent {
  display: flex;
  align-items: center;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;同  &lt;strong&gt;水平居中&lt;/strong&gt;的方法一&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/d3zrvz4q/"&gt;栗子&lt;/a&gt;&lt;/p&gt;
 &lt;h4&gt;方法二：absolute + transform&lt;/h4&gt;
 &lt;pre&gt;  &lt;code&gt;.parent { position: relative; }
.child {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;同  &lt;strong&gt;水平居中&lt;/strong&gt;的方法二&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/btx0ueox/"&gt;栗子&lt;/a&gt;&lt;/p&gt;
 &lt;h4&gt;方法三：table-cell + vertical-align&lt;/h4&gt;
 &lt;pre&gt;  &lt;code&gt;.parent {
  display: table-cell;
  vertical-align: middle;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;vertical-align 可以作用在   &lt;code&gt;inline&lt;/code&gt;元素，  &lt;code&gt;inline-table&lt;/code&gt;元素，以及  &lt;code&gt;table-cell&lt;/code&gt;元素上。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/xz1879vk/"&gt;栗子&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;3.水平垂直居中&lt;/h3&gt;
 &lt;p&gt;父元素和子元素宽高都未知。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://segmentfault.com/img/bVMh7w?w=313&amp;h=314" title="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h4&gt;方法一：flex + justify-content + align-items&lt;/h4&gt;
 &lt;pre&gt;  &lt;code&gt;.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;综合了  &lt;strong&gt;水平居中&lt;/strong&gt;和  &lt;strong&gt;垂直居中&lt;/strong&gt;的方法一&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/cyyphynb/"&gt;栗子&lt;/a&gt;&lt;/p&gt;
 &lt;h4&gt;方法二： absolute + transform&lt;/h4&gt;
 &lt;pre&gt;  &lt;code&gt;.parent { position: relative; }
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;综合了  &lt;strong&gt;水平居中&lt;/strong&gt;和  &lt;strong&gt;垂直居中&lt;/strong&gt;的方法二&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/2rb78s87/"&gt;栗子&lt;/a&gt;&lt;/p&gt;
 &lt;h4&gt;方法三：[inline-block + text-align] + [table-cell + vertical-align]&lt;/h4&gt;
 &lt;pre&gt;  &lt;code&gt;.parent {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}
.child {
  display: inline-block;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/h9o8batt/"&gt;栗子&lt;/a&gt;&lt;/p&gt;
 &lt;h2&gt;多列布局&lt;/h2&gt;
 &lt;h3&gt;1.一列定宽 + 一列自适应&lt;/h3&gt;
 &lt;p&gt;  &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://segmentfault.com/img/bVMk9w?w=599&amp;h=175" title="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;&amp;lt;div class=&amp;quot;parent&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;p&amp;gt;left&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;right&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;right&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;right&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;h4&gt;方法1：float + margin&lt;/h4&gt;
 &lt;pre&gt;  &lt;code&gt;.left {float: left; width: 100px;}
.right { margin-left: 120px;} //有20px是间距&lt;/code&gt;&lt;/pre&gt;
 &lt;h4&gt;方法2：（对方法一的改进）float + margin + (fix)&lt;/h4&gt;
 &lt;p&gt;因为方法1在低版本浏览器有兼容性问题，所以改进一下。&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;// 首先在right外面加了right-fix这个div
&amp;lt;div class=&amp;quot;parent&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;p&amp;gt;left&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;right-fix&amp;quot;&amp;gt; 
    &amp;lt;div class=&amp;quot;right&amp;quot;&amp;gt;
      &amp;lt;p&amp;gt;right&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt;right&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;CSS改动：&lt;/p&gt;
 &lt;p&gt;STEP1：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;// .left 和 .right 设置暂时不变
.right-fix {float: right; width: 100%;}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;效果为：（注意：我们把right-fix设置为白色背景，只是为了方便观察。）&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://segmentfault.com/img/bVMlz7?w=459&amp;h=124" title="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;STEP2：&lt;/p&gt;
 &lt;p&gt;可以看到，由于right-fix宽度为100%，所以跑到了left下面一行。想要回到同一行，需要给right-fix设置一个负的margin-left值-100px。&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;.right-fix { margin-left: -100px; }&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;关于为什么设置了  &lt;code&gt;margin-left: 100px;&lt;/code&gt;就可以使得回到同一行呢？是因为设置了负的margin-left值之后，浏览器计算right-fix元素的宽度后，会加上-100px，也就是减掉100px，这也就是left的宽度，所以left 与 right-fix 加起来没有超过整行的宽度。  &lt;br /&gt;想要进一步了解负的margin值可以参考这篇文章：  &lt;a href="http://www.cnblogs.com/2050/archive/2012/08/13/2636467.html#2457812"&gt;CSS布局奇淫巧计之-强大的负边距&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;效果如图：&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://segmentfault.com/img/bVMlA8?w=522&amp;h=88" title="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;STEP3：&lt;/p&gt;
 &lt;p&gt;不幸的是，因为html文档中right-fix处于left后面，所以left被right-fix遮住了，实际应用中right-fix虽然没有背景色，但是我们还是不会希望它覆盖在left上面。&lt;/p&gt;
 &lt;p&gt;所以，我们需要提高 left 的层级。如何提高呢？由于设置了position: relative;的元素层级要高于普通元素，所以加上这样一条：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;.left{ position: relative; }&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;具体可以参考张鑫旭写的一篇讲解  &lt;code&gt;position:relative;&lt;/code&gt;很详细的文章：  &lt;a href="http://www.zhangxinxu.com/wordpress/2011/08/css%E7%9B%B8%E5%AF%B9%E5%AE%9A%E4%BD%8Drelative%E7%BB%9D%E5%AF%B9%E5%AE%9A%E4%BD%8Dabsolute%E7%B3%BB%E5%88%97%EF%BC%88%E5%9B%9B%EF%BC%89/"&gt;CSS 相对/绝对(relative/absolute)定位系列（四）&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;最终达到我们要的效果：&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://segmentfault.com/img/bVMlBL?w=519&amp;h=89" title="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/t7xjwujj/"&gt;到jsfiddle中自己试试去&lt;/a&gt;&lt;/p&gt;
 &lt;h4&gt;方法3：float + overflow&lt;/h4&gt;
 &lt;pre&gt;  &lt;code&gt;.left{
  width: 100px;
  margin-right: 20px;
}
.right {
  overflow: hidden;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;原理是：设置了overflow:hidden; 之后，会触发BFC模式，而BFC模式内部的布局不受外部影响，所以不会受浮动影响，不会围绕left而是跑到left右边去了。&lt;/p&gt;
 &lt;h4&gt;方法4：table&lt;/h4&gt;
 &lt;pre&gt;  &lt;code&gt;.parent{
  display: table;
  width: 100%;
  table-layout: fixed; //加速table渲染，实现了布局优先
}
.left, .right {
  display: table-cell;
}
.left {
  width: 100px;
  padding-right: 20px;//因为table-cell不能设margin，所以设置padding来加间距
}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;根据table的特性,left设置了100px后，right就占了剩余宽度。&lt;/p&gt;
 &lt;h4&gt;方法5：flex&lt;/h4&gt;
 &lt;pre&gt;  &lt;code&gt;.parent{ display: flex; }
.left{ width: 100px; margin-right: 20px; }
.right{ flex: 1; }&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;So easy.&lt;/p&gt;
 &lt;h3&gt;2.多列定宽 + 一列自适应&lt;/h3&gt;
 &lt;p&gt;再加一列定宽就行啦 o(≧v≦)o&lt;/p&gt;
 &lt;h3&gt;3.不定宽 + 一列自适应&lt;/h3&gt;
 &lt;p&gt;  &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://segmentfault.com/img/bVMlDY?w=427&amp;h=131" title="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;不定宽&lt;/strong&gt;意思是：  &lt;br /&gt;1.可以随意更改宽度：比如改为100px，200px，同时不需要更改其他样式也可以做到两列自适应布局。  &lt;br /&gt;2.或不设置宽度而是由里面子元素的宽度决定。&lt;/p&gt;
 &lt;p&gt;以下方法对应 [一列定宽+一列自适应] 中的方法&lt;/p&gt;
 &lt;p&gt;方法1： float + margin ？&lt;/p&gt;
 &lt;p&gt;不好意思，做不到。&lt;/p&gt;
 &lt;p&gt;方法2： float + margin +（fix） ？&lt;/p&gt;
 &lt;p&gt;不好意思，也做不到。&lt;/p&gt;
 &lt;p&gt;方法3： float + overflow ？&lt;/p&gt;
 &lt;p&gt;阔以！  &lt;strong&gt;right的样式没有依赖于width的宽度。&lt;/strong&gt;代码量也少，很棒棒哦！&lt;/p&gt;
 &lt;p&gt;方法4：table&lt;/p&gt;
 &lt;p&gt;阔以！  &lt;strong&gt;right的样式没有依赖于width的宽度，即不关心width的宽度。&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;方法5：flex&lt;/p&gt;
 &lt;p&gt;强大的flex当然可以~（傲娇脸 ）&lt;/p&gt;
 &lt;h3&gt;4.两列不定宽 + 一列自适应&lt;/h3&gt;
 &lt;p&gt;没错，跟你想的一样，加一列不定宽的就行了，样式都一样 ㄟ( ▔, ▔ )ㄏ&lt;/p&gt;
 &lt;h3&gt;5.等分布局&lt;/h3&gt;
 &lt;p&gt;  &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://segmentfault.com/img/bVMlFE?w=544&amp;h=326" title="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;C + G = 4*（W + G）   &lt;br /&gt;以下例子假设间距G = 20px&lt;/p&gt;
 &lt;p&gt;结构：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;&amp;lt;div class=&amp;quot;parent&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;column&amp;quot;&amp;gt;&amp;lt;p&amp;gt;1&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;column&amp;quot;&amp;gt;&amp;lt;p&amp;gt;2&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;column&amp;quot;&amp;gt;&amp;lt;p&amp;gt;3&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;column&amp;quot;&amp;gt;&amp;lt;p&amp;gt;4&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;方法1：float&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;.parent{ margin-left: -20px; }//就是上面公式中等号左边的G
.column{
  float: left;
  width: 25%;
  padding-left: 20px;//这里要注意，因为我们用padding来表示间距，所以如果你是给p元素设置了background-color，会发现没有间距，p标签的width才是上图中的W
  box-sizing: border-box;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;方法2：table&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;&amp;lt;div class=&amp;quot;parent-fix&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;parent&amp;quot;&amp;gt;
      &amp;lt;div class=&amp;quot;column&amp;quot;&amp;gt;&amp;lt;p&amp;gt;1&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;column&amp;quot;&amp;gt;&amp;lt;p&amp;gt;2&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;column&amp;quot;&amp;gt;&amp;lt;p&amp;gt;3&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;column&amp;quot;&amp;gt;&amp;lt;p&amp;gt;4&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;pre&gt;  &lt;code&gt;.parent-fix{
  margin-left: -20px;
}
.parent {
  display: table;
  width: 100%;
}
.column {
  display: table-cell;
  padding-left: 20px;//因为单元格不能设置margin，所以间距只能用padding来做。
}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;因为table的width默认是随内容宽度变化的，所以需要手动设置  &lt;code&gt;width: 100%;&lt;/code&gt;。又因为明确设置了宽度的元素就没办法用将margin设为负值的方式增加20px宽度了，所以需要在外面加一个父元素  &lt;code&gt;parent-fix&lt;/code&gt;。  &lt;br /&gt;这里大家可以自己试试比较一下给  &lt;code&gt;parent-fix&lt;/code&gt;  &lt;strong&gt;设置width为100%&lt;/strong&gt;与  &lt;strong&gt;不设置width&lt;/strong&gt;时parent-fix实际宽度（用调试工具里的查看元素看）的区别来理解。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/o7czrt0o/"&gt;呐，jsfiddle示例在这&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;方法3：flex&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;.parent { display: flex; }
.column { flex: 1; } 
.column + .column { margin-left: 20px; }//好用的兄弟选择器 (｡・`ω´･)&lt;/code&gt;&lt;/pre&gt;
 &lt;h1&gt;上面这个等分布局这个整理完在另一篇CSS布局的文章里面给个链接&lt;/h1&gt;
 &lt;h3&gt;6.一列定宽+一列自适应（当其中较高的一列高度变化，另一列同步变化）&lt;/h3&gt;
 &lt;p&gt;右侧变高，左侧高度随之变化：&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="&amp;#21491;&amp;#20391;&amp;#21464;&amp;#39640;&amp;#65292;&amp;#24038;&amp;#20391;&amp;#39640;&amp;#24230;&amp;#38543;&amp;#20043;&amp;#21464;&amp;#21270;1" src="https://segmentfault.com/img/bVMo93?w=765&amp;h=276" title="&amp;#21491;&amp;#20391;&amp;#21464;&amp;#39640;&amp;#65292;&amp;#24038;&amp;#20391;&amp;#39640;&amp;#24230;&amp;#38543;&amp;#20043;&amp;#21464;&amp;#21270;1"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;↓↓&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="&amp;#21491;&amp;#20391;&amp;#21464;&amp;#39640;&amp;#65292;&amp;#24038;&amp;#20391;&amp;#39640;&amp;#24230;&amp;#38543;&amp;#20043;&amp;#21464;&amp;#21270;2" src="https://segmentfault.com/img/bVMpan?w=767&amp;h=200" title="&amp;#21491;&amp;#20391;&amp;#21464;&amp;#39640;&amp;#65292;&amp;#24038;&amp;#20391;&amp;#39640;&amp;#24230;&amp;#38543;&amp;#20043;&amp;#21464;&amp;#21270;2"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;方法1：table&lt;/p&gt;
 &lt;p&gt;table的列之间有天然等高的特性。&lt;/p&gt;
 &lt;p&gt;就是上面   &lt;strong&gt;1.一列定宽 + 一列自适应&lt;/strong&gt;中的  &lt;strong&gt;方法4：table&lt;/strong&gt;。&lt;/p&gt;
 &lt;p&gt;方法2：flex&lt;/p&gt;
 &lt;p&gt;flex也是天然的等高 &amp;lt;(￣︶￣)&amp;gt; 因为它默认的align-items为stretch，即在交叉轴上默认拉伸占满整个容器。&lt;/p&gt;
 &lt;p&gt;仍旧是上面  &lt;strong&gt;1.一列定宽 + 一列自适应&lt;/strong&gt;中的  &lt;strong&gt;方法5：flex&lt;/strong&gt;。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/kshefy4s/"&gt;简单到不好意思给栗子&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;方法3：float&lt;/p&gt;
 &lt;p&gt;仍旧是参照上面  &lt;strong&gt;1.一列定宽 + 一列自适应&lt;/strong&gt;中的  &lt;strong&gt;方法3：float + overflow&lt;/strong&gt;，float并没有天然等高，所以要在这个基础上做改动。&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;.left{
  width: 100px;
  margin-right: 20px;
}
.right {
  overflow: hidden;
}
//增加部分
.left, .right{
  padding-bottom: 9999px;//使得有背景色的部分变的很高
  margin-bottom: -9999px;//用负的margin抵消掉很高的padding，让高度变回left和right中较高的那部分的内容高度，以便parent用overflow: hidden;去隐藏掉超出部分
}
.parent {
  overflow: hidden;//隐藏掉超出边界的部分 
}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;其实left的实际高度并没有变，是一种伪等高，只是背景变高。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/8hyacvkg/"&gt;栗子&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;7.全等四宫格&lt;/h3&gt;
 &lt;p&gt;  &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://segmentfault.com/img/bVqUsZ" title="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;这是练习题，置几试试吧。&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;&amp;lt;div class=&amp;quot;parent&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;outer&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;column&amp;gt;1&amp;lt;/div&amp;gt;
    &amp;lt;div class=&amp;quot;column&amp;gt;2&amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;outer&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;column&amp;gt;3&amp;lt;/div&amp;gt;
    &amp;lt;div class=&amp;quot;column&amp;gt;4&amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;方法1：flex&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;.parent {
  display: flex;
  flex-wrap: wrap;
  align-content: space-between;
}
.outer {
  flex-basis: 100%;
  display: flex;
  justify-content: space-between;
}
&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/d1ndbpxn/"&gt;一颗仅供参考的栗子&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;方法2：float&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/twckmv31/"&gt;我的栗子&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;方法3：table&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/t1for4g0/"&gt;一个栗子不一定对&lt;/a&gt;&lt;/p&gt;
 &lt;h2&gt;全屏布局&lt;/h2&gt;
 &lt;h3&gt;1.定宽（px）+自适应&lt;/h3&gt;
 &lt;p&gt;  &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://segmentfault.com/img/bVMsBG?w=588&amp;h=428" title="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;只有主内容区 right 随内容滚动。&lt;/p&gt;
 &lt;p&gt;方法1.position&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;&amp;lt;div class=&amp;quot;parent&amp;quot;&amp;gt;
&amp;lt;div class=&amp;quot;top&amp;quot;&amp;gt;top&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;quot;left&amp;quot;&amp;gt;left&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;help-right&amp;quot;&amp;gt;right&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;quot;bottom&amp;quot;&amp;gt;bottom&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;pre&gt;  &lt;code&gt;html, body, .parent {height: 100%; overflow: hidden;}//为了让整个页面不滚动
.top {
  position: absolute;
  top: 0; 
  left: 0; right: 0; //注意这个很棒的设置！可以自动占满整行 ヾ(o◕∀◕)ﾉ 
  height: 100px;
}
.left {
  position: absolute;
  left: 0;
  top: 100px; bottom: 50px;
  width:200px;
}
.right {
  position: absolute;
  left: 200px; right: 0;
  top: 100px; bottom: 50px; //这也是上下占满除了top和bottom之外的所有高度
  overflow: auto;//让主内容区可以滚动
}
.help-right {//假装有很多内容
  width: 1000px;
  height: 1000px;
}
.bottom{
  position: absolute;
  bottom: 0; 
  left: 0; right: 0;
  height: 50px;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/50j3q2bg/"&gt;动手写写才记得住&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;方法2.flex&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;&amp;lt;div class=&amp;quot;parent&amp;quot;&amp;gt;
&amp;lt;div class=&amp;quot;top&amp;quot;&amp;gt;top&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;quot;middle&amp;quot;&amp;gt;
&amp;lt;div class=&amp;quot;left&amp;quot;&amp;gt;left&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;help-right&amp;quot;&amp;gt;right&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;quot;bottom&amp;quot;&amp;gt;bottom&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;pre&gt;  &lt;code&gt;html, body, .parent {height: 100%; overflow: hidden;}
.parent {display: flex; flex-direction: column;}
.top { height: 100px; }
.middle {flex: 1; display: flex;}
.left { width:200px; }
.right { flex: 1; overflow: auto; }
.help-right { width: 1000px; height: 1000px; }
.bottom{ height: 50px; }&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/txcfpsLy/"&gt;栗子&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;2.百分比定宽（%）+自适应&lt;/h3&gt;
 &lt;p&gt;方法1.position ， 方法2.flex ：&lt;/p&gt;
 &lt;p&gt;把原来的用px写的定宽改成百分比就可以了。是相对于body的高度和宽度来变化的。感觉top和bottom高度设置百分比不是很实用。&lt;/p&gt;
 &lt;h3&gt;3.自适应+自适应&lt;/h3&gt;
 &lt;p&gt;  &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://segmentfault.com/img/bVMsCj?w=583&amp;h=434" title="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;方法1.position&lt;/p&gt;
 &lt;p&gt;定宽的高度和宽度影响旁边栏的布局，所以实现不了  - 。-&lt;/p&gt;
 &lt;p&gt;方法2.flex&lt;/p&gt;
 &lt;p&gt;阔以实现，而且相当简单 ╮(╯▽╰)╭  把刚刚设置了高度和宽度的地方去掉就可以了  ∑(っ °Д °;)っ &lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://jsfiddle.net/DarcyAn/j1t84e9r/"&gt;惊人的栗子&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;方法3.Grid&lt;/p&gt;
 &lt;p&gt;阔以实现，但是因为还是W3C的草案，所以会经常变化，不稳定，而且浏览器支持也不好。&lt;/p&gt;
 &lt;h1&gt;响应式&lt;/h1&gt;
 &lt;h3&gt;想要达到的效果&lt;/h3&gt;
 &lt;p&gt;只写一个网站，在多个终端显示，在小屏幕上会隐藏部分元素。&lt;/p&gt;
 &lt;h3&gt;现在的情况&lt;/h3&gt;
 &lt;p&gt;在PC端浏览器中可以正常访问的网站，到了手机上之后，内容就会变得特别小。  &lt;br /&gt;原因：所有的移动设备都有一个viewport（视窗），这个视窗不是手机屏幕大小，而是一个虚拟的窗口，比如iPhone4的viewport宽度为980px（如下图所示）。显示的时候再按照比例将这980px的内容压缩显示到实际的屏幕宽度中。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://segmentfault.com/img/bVMsCT?w=667&amp;h=456" title="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h3&gt;所以为防止让页面缩小，在移动设备中，我们会做如下设置&lt;/h3&gt;
 &lt;pre&gt;  &lt;code&gt;&amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;
 width=device-width //让宽度等于设备宽度，因为不同的移动设备宽度不同 iphone4为320px
 ,initial-scale=1.0 //初始缩放1.0， 即不缩放，网站就不会被缩小了
 ,user-scalable=no //防止用户手动缩放
&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;h3&gt;设置结束之后，如何具体开发？&lt;/h3&gt;
 &lt;h4&gt;方法1.宽度尽量自适应，而不要用定宽。&lt;/h4&gt;
 &lt;h4&gt;方法2.用媒体查询 @media&lt;/h4&gt;
 &lt;pre&gt;  &lt;code&gt;@media screen and (max-width: 320px) {
  //最大宽度为320px，即视窗宽度小于等于320px
  div{..}
  .class-name{...}
}

@media screen and (min-width: 320px) and (max-width: 769px){
  //最小宽度为320px，最大宽度为769px，即视窗宽度大于320px，小于769px
}&lt;/code&gt;&lt;/pre&gt;
 &lt;h1&gt;响应式&lt;/h1&gt;
 &lt;h2&gt;目的&lt;/h2&gt;
 &lt;p&gt;减少卡顿  &lt;br /&gt;利于SEO  &lt;br /&gt;便于代码维护&lt;/p&gt;
 &lt;h2&gt;方法&lt;/h2&gt;
 &lt;h3&gt;1. 减少页面请求&lt;/h3&gt;
 &lt;h4&gt;减少css文件请求&lt;/h4&gt;
 &lt;p&gt;（1）多个css文件合并成一个  &lt;br /&gt;（2）少量css样式内联  &lt;br /&gt;（3）避免用import的方式引入css文件，因为每个import语句都会产生一个css请求，并且是同步的请求。&lt;/p&gt;
 &lt;h3&gt;2.减少资源文件大小&lt;/h3&gt;
 &lt;p&gt;（1）减少图片大小  &lt;br /&gt;选择合适的图片格式，小尺寸、半透明的用png，大尺寸、色彩绚丽用jpg（因为jpg会对图片进行压缩）  &lt;br /&gt;压缩图片&lt;/p&gt;
 &lt;p&gt;（2）css值缩写  &lt;br /&gt;margin，padding，border，font，border-radius等属性&lt;/p&gt;
 &lt;p&gt;（3）省略值为0 的单位&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;margin: 0 10px;
line-height: .5;
background-position: 50% 0;
&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;（4）颜色值最短表示&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;red
rgb(0,0,0)
rgba(0,0,0,0)
#000000
#000&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;（5）css选择器合并&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;.left, .right {...}&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;（6）文件压缩  &lt;br /&gt;用工具对文件进行自动压缩，去掉空格。&lt;/p&gt;
 &lt;h3&gt;3.提升页面性能&lt;/h3&gt;
 &lt;h4&gt;加载顺序&lt;/h4&gt;
 &lt;p&gt;css通常放在head中，而js通常放在body底部，因为js会阻碍其他资源加载。&lt;/p&gt;
 &lt;h4&gt;减少标签数量。&lt;/h4&gt;
 &lt;h4&gt;选择器长度&lt;/h4&gt;
 &lt;pre&gt;  &lt;code&gt;body .menu ul li a { ... } //太长了
.menu a { ... } //更好&lt;/code&gt;&lt;/pre&gt;
 &lt;h4&gt;避免耗性能属性&lt;/h4&gt;
 &lt;p&gt;比如：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;expression
filter
border-radius
box-shadow
gradients&lt;/code&gt;&lt;/pre&gt;
 &lt;h4&gt;给图片设置固定宽高，并且图片实际宽高与设置宽高相同，否则浏览器会回流设置多次宽高&lt;/h4&gt;
 &lt;h4&gt;所有表现用css实现&lt;/h4&gt;
 &lt;h3&gt;4.通过规范提高代码可读性，可维护性&lt;/h3&gt;
 &lt;p&gt;（1）规范：缩进，变量名等  &lt;br /&gt;（2）语义化：除了标签，css、id名最好也尽量有意义  &lt;br /&gt;（3）尽量避免Hack，一定要用也要统一的标识，比如IE7用*  &lt;br /&gt;（4）模块化：相关联的结构做成一个个模块，复用性更强  &lt;br /&gt;（5）添加注释&lt;/p&gt;
 &lt;h1&gt;规范与模块化&lt;/h1&gt;
 &lt;h2&gt;规范&lt;/h2&gt;
 &lt;p&gt;1.注释的文字两侧需加空格，防止因编码问题导致注释失效&lt;/p&gt;
 &lt;p&gt;2.为避免命名污染，可以给class加前缀，比如：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;g- 布局命名
m- 模块命名
&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;3.语义化命名&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;//结构化命名
top { ... }

//改用语义化命名
nav { ... }&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;4.属性的书写顺序&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://segmentfault.com/img/bVMwjz?w=848&amp;h=457" title="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h2&gt;模块化&lt;/h2&gt;
 &lt;h3&gt;什么是模块化&lt;/h3&gt;
 &lt;blockquote&gt;  &lt;ol&gt;
   &lt;li&gt;    &lt;p&gt;一系列相关联的结构组成的整体&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;    &lt;p&gt;带有一定的语义，而非表现&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/blockquote&gt;
 &lt;p&gt;比如，翻页器（或叫分页器paging）、轮播图。&lt;/p&gt;
 &lt;h3&gt;怎么做？&lt;/h3&gt;
 &lt;blockquote&gt;  &lt;ol&gt;
   &lt;li&gt;    &lt;p&gt;为模块分类命名（如.m-, .md-）&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;    &lt;p&gt;以一个主选择器开头（模块根节点）&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;    &lt;p&gt;使用以主选择器开头的后代选择器（模块子节点）&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/blockquote&gt;
 &lt;pre&gt;  &lt;code&gt;&amp;lt;div class=&amp;quot;m-nav&amp;quot;&amp;gt;
  &amp;lt;ul&amp;gt;
    &amp;lt;li class=&amp;quot;z-crt&amp;quot;&amp;gt;&amp;lt;a&amp;gt;链接&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a&amp;gt;链接&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;/ul&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;pre&gt;  &lt;code&gt;//根节点
.m-nav { ... }
//子节点
.m-nav ul{ ... }
.m-nav li{ ... }
.m-nav a{ ... }
.m-nav .z-crt a{ ... }/* 交互状态变化 */&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;若有一个模块只是比上述模块多了一个按钮，其余部分完全相同，怎么办？&lt;/p&gt;
 &lt;h3&gt;怎样扩展？&lt;/h3&gt;
 &lt;p&gt;为根节点加一个class就好了，这里我们加一个   &lt;code&gt;m-nav-1&lt;/code&gt;。&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;&amp;lt;div class=&amp;quot;m-nav m-nav-1&amp;quot;&amp;gt;
  &amp;lt;ul&amp;gt;
    &amp;lt;li class=&amp;quot;z-crt&amp;quot;&amp;gt;&amp;lt;a&amp;gt;链接&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a&amp;gt;链接&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;/ul&amp;gt;
  &amp;lt;a class=&amp;quot;btn&amp;quot;&amp;gt;我是新加的a标签&amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;pre&gt;  &lt;code&gt;//变化的部分在 .m-nav-1 这个新class中写
.m-nav-1 { ... }
.m-nav-1 a{ ... }
.m-nav-1 .btn{ ... }&lt;/code&gt;&lt;/pre&gt;
 &lt;h3&gt;网易的规范和代码库&lt;/h3&gt;
 &lt;p&gt;  &lt;a href="http://nec.netease.com/standard"&gt;规范页&lt;/a&gt;：包含了CSS规范、HTML规范和工程师规范&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://nec.netease.com/library"&gt;代码库&lt;/a&gt;：包含了常用的布局方式、常见模块和元件的实现以及一些bug、技巧等&lt;/p&gt;
 &lt;p&gt;——————  &lt;br /&gt;  &lt;em&gt;教是最好的学。&lt;/em&gt;&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>html css 页面布局 html5 css3</category>
      <guid isPermaLink="true">https://itindex.net/detail/56867-%E9%A1%B5%E9%9D%A2-%E6%9E%B6%E6%9E%84-html</guid>
      <pubDate>Fri, 21 Apr 2017 21:54:10 CST</pubDate>
    </item>
    <item>
      <title>css reset重置样式有那么重要吗？</title>
      <link>https://itindex.net/detail/54335-css-reset</link>
      <description>&lt;p&gt;在以前写html代码的时候，一般都会在head里添加重置样式reset.css，其内容如下：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;@charset &amp;quot;utf-8&amp;quot;;
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
    margin: 0;
    padding: 0;
    border: 0;
    outline: 0;
    font-size: 100%;

}
table {
    border-collapse:collapse;
    border-spacing:0;
}
fieldset, img {    border:0;}
address, caption, cite, code, dfn, em, strong, th, var {
    font-style:normal;
    font-weight:normal;
}
ol, ul { list-style:none; }
caption, th { text-align:left; }
h1, h2, h3, h4, h5, h6 {
    font-size:200%;
    font-weight:normal;
}
:focus { outline: 0;}
a{ text-decoration:none;}
a:hover img{ border:none;}

a:active{noOutline:expression(this.onFocus=this.blur());}

.clearfix:after {
    content: &amp;quot;.&amp;quot;;
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}
.clearfix {display: inline-block;}
 html .clearfix { height: 1%;}
.clearfix {display: block;}

*html img.png{
_background-image: expression(this.runtimeStyle.backgroundImage = &amp;quot;none&amp;quot;,this.runtimeStyle.filter = &amp;quot;progid:DXImageTransform.Microsoft.AlphaImageLoader(src=&amp;apos;&amp;quot; + this.src + &amp;quot;&amp;apos;, sizingMethod=&amp;apos;image&amp;apos;)&amp;quot;,this.src = &amp;quot;http://i0.itc.cn/20101019/848_0a785a7b_1118_4825_85dc_e8696988c94b_0.gif&amp;quot;);&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;}&lt;/p&gt;
 &lt;p&gt;但是最近在网上看了看网络文章，也感觉有些重置是没有用的。为什么呢？&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;重置的作用究竟是什么？&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;CSS reset的作用是让各个浏览器的CSS样式有一个统一的基准，而这个基准更多的就是“清零”！&lt;/p&gt;
 &lt;p&gt;有时候看到别人网站站的一些重置是这样的：&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;*{ margin:0; padding:0; }
&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;这样的写法是极不推荐的。  &lt;br /&gt;现在来看重置表发现：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;   &lt;p&gt;    &lt;code&gt;div&lt;/code&gt;标签默认有    &lt;code&gt;margin&lt;/code&gt;值吗？有    &lt;code&gt;padding&lt;/code&gt;值吗？怎么会想到应用    &lt;code&gt;div{margin:0; padding:0;}&lt;/code&gt;属性呢？答案肯定没有。&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;p&gt;    &lt;code&gt;dt&lt;/code&gt;标签有默认的    &lt;code&gt;margin&lt;/code&gt;与    &lt;code&gt;padding&lt;/code&gt;值就是    &lt;code&gt;0&lt;/code&gt;，什么还要使用呢？&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;p&gt;    &lt;code&gt;li&lt;/code&gt;标签默认有    &lt;code&gt;margin&lt;/code&gt;值吗？有    &lt;code&gt;padding&lt;/code&gt;值吗？没有！&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;p&gt;    &lt;code&gt;code&lt;/code&gt;标签是个属于    &lt;code&gt;inline&lt;/code&gt;水平的元素，居然也扯到    &lt;code&gt;margin&lt;/code&gt;与    &lt;code&gt;padding&lt;/code&gt;的重置，没有必要。&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;p&gt;    &lt;code&gt;fieldset&lt;/code&gt;, l    &lt;code&gt;egend&lt;/code&gt;这两个90年代的标签你的网站上使用了吗？使用概率不足1%的标签也拿来重置，也没必要。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;css真的重置也就那么几个常用的标签而已，你的页面一般都用到什么标签？&lt;/p&gt;
 &lt;pre&gt;  &lt;code&gt;body, dl, dd, h1, h2, h3, h4, h5, h6, p, form{margin:0;} 

 ol,ul{margin:0; padding:0;}
 &lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;这样的CSS reset才是高效的，简洁的，其他一些标签都可以去掉的，没有必要。&lt;/p&gt;
 &lt;p&gt;当然css重置的优点，缺点都不说了，估计心里都非常有数的，还是要根据实际项目来。&lt;/p&gt;
 &lt;p&gt;后来主管给我推荐了一款替代  &lt;code&gt;reset.css&lt;/code&gt;重置的替代方案，那就是用  &lt;code&gt;Normalize.css&lt;/code&gt;。在后面文章里把它的用法等再列出来。&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>css reset</category>
      <guid isPermaLink="true">https://itindex.net/detail/54335-css-reset</guid>
      <pubDate>Mon, 14 Sep 2015 21:02:19 CST</pubDate>
    </item>
    <item>
      <title>样式表的载入会延迟DOM载入事件</title>
      <link>https://itindex.net/detail/55580-%E6%A0%B7%E5%BC%8F%E8%A1%A8-%E5%BB%B6%E8%BF%9F-dom</link>
      <description>&lt;p&gt;绝大多数情况下我们总是让JavaScript在DOM载入后再开始执行。
不管是直接用 DOM API 实现还是使用 jQuery，最终都是  &lt;code&gt;DOMContentLoaded&lt;/code&gt;事件在起作用。
本文讨论一个我们习以为常却很少了解的问题：
  &lt;strong&gt;样式文件的载入会延迟脚本执行，以及   &lt;code&gt;DOMContentLoaded&lt;/code&gt;事件的触发。&lt;/strong&gt;&lt;/p&gt;

 &lt;h1&gt;DOMContentLoaded事件&lt;/h1&gt;

 &lt;p&gt;页面文档（DOM）完全加载并解析完毕之后，会触发  &lt;code&gt;DOMContentLoaded&lt;/code&gt;事件，
HTML文档不会等待样式文件，图片文件，Iframe页面的加载。
但DOM树已被创建，多数JavaScript已经操作DOM并完成功能了。&lt;/p&gt;

 &lt;blockquote&gt;
    &lt;p&gt;This (DOMContentLoaded) event fires after the HTML code has been fully retrieved from the server, the complete DOM tree has been created and scripts have access to all elements via the DOM API. –    &lt;a href="http://molily.de/domcontentloaded/"&gt;molily.de&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

 &lt;p&gt;然而在绝大多数场景下，样式文件的载入会延迟  &lt;code&gt;DOMContentLoaded&lt;/code&gt;事件的触发。
其实这样的行为正是开发者所希望的，为什么呢？&lt;/p&gt;

 &lt;blockquote&gt;
    &lt;p&gt;事实上，老版本的IE中   &lt;code&gt;DOMContentLoaded&lt;/code&gt;事件存在兼容性问题。
参见：   &lt;a href="http://harttle.com/2016/05/14/binding-document-ready-event.html"&gt;兼容所有浏览器的 DOM 载入事件&lt;/a&gt;。&lt;/p&gt;
&lt;/blockquote&gt;



 &lt;h1&gt;浏览器为何延迟DOMContentLoaded&lt;/h1&gt;

 &lt;p&gt;对于很多脚本而言，它们被编写时就希望在样式载入之后再开始执行。
JavaScript的作者往往会假设CSS规则已经生效，尤其是在进行一些显示相关的操作时，
比如需要得到DOM元素的位置和大小的场景。&lt;/p&gt;

 &lt;p&gt;事实上，在多数浏览器中  &lt;code&gt;DOMContentLoaded&lt;/code&gt;事件的触发会考虑到外部样式文件的载入，
以及在HTML中脚本标签和样式标签的相对位置。
如果脚本位于样式之后，浏览器通常会认为该脚本依赖于样式的渲染结果，
也就更倾向于延迟脚本的执行（直到样式渲染结束）。&lt;/p&gt;

 &lt;h1&gt;不同浏览器的行为&lt;/h1&gt;

 &lt;p&gt;既然浏览器有时会延迟  &lt;code&gt;DOMContentLoaded&lt;/code&gt;事件，
但是何时会延迟  &lt;code&gt;DOMContentLoaded&lt;/code&gt;事件，还取决于行内脚本还是外部脚本，以及脚本与样式标签的相对位置。
不同的浏览器渲染引擎也有不同的行为。
在  &lt;a href="http://molily.de/domcontentloaded/"&gt;http://molily.de/domcontentloaded/&lt;/a&gt;一文中对该问题有详尽的阐述和测试，
本文取其结论。&lt;/p&gt;

 &lt;p&gt;下表描述了各种情况下脚本是否会被延迟执行，进而延迟触发  &lt;code&gt;DOMContentLoaded&lt;/code&gt;事件。&lt;/p&gt;

 &lt;table&gt;
  
      &lt;tr&gt;
         &lt;th&gt;渲染引擎&lt;/th&gt;
         &lt;th&gt;样式表之前的脚本&lt;/th&gt;
         &lt;th&gt;样式表之后的外部脚本&lt;/th&gt;
         &lt;th&gt;样式表之后的行内脚本&lt;/th&gt;
    &lt;/tr&gt;
  
  
      &lt;tr&gt;
         &lt;td&gt;Presto (Opera)&lt;/td&gt;
         &lt;td&gt;否&lt;/td&gt;
         &lt;td&gt;否&lt;/td&gt;
         &lt;td&gt;否&lt;/td&gt;
    &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;Webkit (Safari, Chrome)&lt;/td&gt;
         &lt;td&gt;否&lt;/td&gt;
         &lt;td&gt;是&lt;/td&gt;
         &lt;td&gt;否&lt;/td&gt;
    &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;Gecko (Firefox)&lt;/td&gt;
         &lt;td&gt;否&lt;/td&gt;
         &lt;td&gt;是&lt;/td&gt;
         &lt;td&gt;是&lt;/td&gt;
    &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;Trident (MSIE)&lt;/td&gt;
         &lt;td&gt; &lt;/td&gt;
         &lt;td&gt;是&lt;/td&gt;
         &lt;td&gt;是&lt;/td&gt;
    &lt;/tr&gt;
  
&lt;/table&gt;

 &lt;h1&gt;HTML5标准及最佳实践&lt;/h1&gt;

 &lt;p&gt;其实  &lt;code&gt;DOMContentLoaded&lt;/code&gt;是Firefox中最先提出的，
此后JavaScript社区发现它确实比  &lt;code&gt;load&lt;/code&gt;事件（要求所有资源完全载入）更好，
于是Apple和Opera相继开始支持该事件。
但不同浏览器的实现方式有所区别，于是产生了上表所示的复杂情况。&lt;/p&gt;

 &lt;p&gt;在HTML5标准中情况有所好转：  &lt;code&gt;DOMContentLoaded&lt;/code&gt;是一个纯DOM事件，与样式表无关。
与此同时，HTML5要求：&lt;/p&gt;

 &lt;ul&gt;
    &lt;li&gt;脚本执行前，出现在当前   &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;之前的   &lt;code&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot;&amp;gt;&lt;/code&gt;必须完全载入。&lt;/li&gt;
    &lt;li&gt;脚本执行会阻塞DOM解析。&lt;/li&gt;
&lt;/ul&gt;

 &lt;p&gt;这样的话，假如脚本和样式一起放在HTML  &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;中，
DOM解析到  &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;标签时会阻塞DOM解析，开始如下操作：&lt;/p&gt;

 &lt;ol&gt;
    &lt;li&gt;获取当前   &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;的脚本文件；&lt;/li&gt;
    &lt;li&gt;获取并载入前面的所有   &lt;code&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot;&amp;gt;&lt;/code&gt;。&lt;/li&gt;
    &lt;li&gt;执行当前脚本文件。&lt;/li&gt;
&lt;/ol&gt;

 &lt;p&gt;这些操作完成之后才能继续进行DOM解析，解析完毕时再触发  &lt;code&gt;DOMContentLoaded&lt;/code&gt;事件。
如果将样式和脚本都放到  &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;中，会使浏览器在渲染  &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;前载入并执行所有样式和脚本。
页面的显示延迟会很高，多数情况下用户体验都很糟糕。
因此在HTML5标准的HTML页面中，最佳实践应当是：
  &lt;strong&gt;所有样式放在   &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;中；所有脚本放在   &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;最后。&lt;/strong&gt;&lt;/p&gt;

 &lt;blockquote&gt;
    &lt;p&gt;   &lt;a href="http://api.jquery.com/ready/"&gt;jQuery文档&lt;/a&gt;中也推荐这样的实践方式。&lt;/p&gt;
&lt;/blockquote&gt;

 &lt;h1&gt;参考阅读&lt;/h1&gt;

 &lt;ul&gt;
    &lt;li&gt;MDN    &lt;code&gt;load&lt;/code&gt; 事件：   &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Events/load"&gt;https://developer.mozilla.org/en-US/docs/Web/Events/load&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;MDN    &lt;code&gt;DOMContentLoaded&lt;/code&gt;事件：   &lt;a href="https://developer.mozilla.org/zh-CN/docs/Web/Events/DOMContentLoaded"&gt;https://developer.mozilla.org/zh-CN/docs/Web/Events/DOMContentLoaded&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>CSS DOM JavaScript 事件 Firefox</category>
      <guid isPermaLink="true">https://itindex.net/detail/55580-%E6%A0%B7%E5%BC%8F%E8%A1%A8-%E5%BB%B6%E8%BF%9F-dom</guid>
      <pubDate>Sun, 15 May 2016 08:00:00 CST</pubDate>
    </item>
    <item>
      <title>玩转HTML5移动APP页面（优化篇）</title>
      <link>https://itindex.net/detail/53307-html5-%E7%A7%BB%E5%8A%A8-app</link>
      <description>&lt;p&gt;承接上文《  &lt;a href="http://www.shejidaren.com/html5-animate-page.html"&gt;玩转HTML5移动APP页面（动效篇）&lt;/a&gt;》，上次说的是让页面动起来的一些小技巧。  &lt;br /&gt;
而页面动起来的根基是功能可用的页面，因此有必要分享一些优化细节的技巧和方向，熟悉掌握一些方法论还是会对页面开发大大提高效率的，并且也能防止疏忽缺漏。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="cover-01" height="360" src="http://images.shejidaren.com/wp-content/uploads/2015/04/034816e5f.jpg" width="630"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;====前方高能====&lt;/p&gt;
 &lt;h3&gt;（1） 动画雪碧图&lt;/h3&gt;
 &lt;p&gt;涉及的动画十分多，用的元素也十分多，请务必使用雪碧图（Sprite）！  &lt;br /&gt;
网上的工具有一些可以帮助你生成雪碧图的工具，例如  &lt;a href="http://www.99css.com/tag/cssgaga/" target="_blank"&gt;CssGaga&lt;/a&gt;，  &lt;a href="http://isux.tencent.com/alloyteam.github.io/gopng" target="_blank"&gt;GoPng&lt;/a&gt;等等，自动化构建工具Grunt和Gulp也提供了相应插件。  &lt;br /&gt;
特别地，如果单张雪碧图面积实在太大，可以拆分雪碧图，例如拆分成2-4张，因为现代浏览器都支持4-6个同源请求下载，若资源实在太多，也可以考虑把静态资源放在不同源域名下去请求，这里牺牲多几个请求换来图片同时加载比一张图片慢慢加载要好，当然，这需要具体情况去衡量。&lt;/p&gt;
 &lt;p&gt;顺便提一下，我写动画的一个小技巧是把每一页的动画分在一个import.css里面，然后最后在主样式中import进去，这样方便调试动画，也容易维护，例如：&lt;/p&gt;
 &lt;pre&gt;//style.css
@import url(&amp;quot;reset.import.css&amp;quot;);
@import url(&amp;quot;loading.import.css&amp;quot;);
@import url(&amp;quot;m-animate-1.import.css&amp;quot;);
@import url(&amp;quot;m-animate-2.import.css&amp;quot;);
@import url(&amp;quot;m-animate-3.import.css&amp;quot;);&lt;/pre&gt;
 &lt;p&gt;当然，import不是原生支持的，这里需要一些流程化工具让import的页面在输出之前经过组装-压缩的步骤。&lt;/p&gt;
 &lt;h3&gt;（2）图片压缩&lt;/h3&gt;
 &lt;p&gt;图片压缩是老生常谈，但是仍然有不少人忘记压缩，那可是活生生的带宽和流量的浪费啊…&lt;/p&gt;
 &lt;p&gt;压缩图片需要有好工具，有  &lt;a href="http://zhitu.tencent.com/" target="_blank"&gt;智图&lt;/a&gt;，  &lt;a href="https://tinypng.com/" target="_blank"&gt;TinyPNG&lt;/a&gt;，  &lt;a href="http://www.jpegmini.com/" target="_blank"&gt;JPEGmini&lt;/a&gt;等等。&lt;/p&gt;
 &lt;p&gt;依靠工具外，还有以下方式可以优化图片：&lt;/p&gt;
 &lt;p&gt;1.尽量避免用PNG24。如果图片色彩要求不高，请使用PNG8；  &lt;br /&gt;
2.使用新格式，WEBP和BPG等新格式的到来，在不用考虑兼容的情况下请大胆尝试；  &lt;br /&gt;
3.用SVG和ICONFONT代替简单的图标；  &lt;br /&gt;
4.用FUFU的  &lt;a href="http://isux.tencent.com/font-spider.html" target="_blank"&gt;字蛛&lt;/a&gt;来代替艺术字体切图。&lt;/p&gt;
 &lt;h3&gt;（3）多终端兼容&lt;/h3&gt;
 &lt;p&gt;多终端兼容是一切的根基，要知道有人拿着肾6+，有人拿着肾4，大则414×736，小则320×416（IPHONE4在SAFARI保留上下端导航），因此多终端兼容是十分必要的。  &lt;br /&gt;
曾经有一种派系为320派系，就是大部分页面都是320宽度，因此干脆直接用320的容器来包一切页面，那样也简单，然而IPHOEN6和IPHONE6+的出现简直是灭了这个派系。&lt;/p&gt;
 &lt;p&gt;那么到底要如何兼容呢？  &lt;br /&gt;
这里我分了三个时期来说说：  &lt;br /&gt;
A.设计初期。先审视设计稿，因为320派系的原因，大部分设计稿只考虑到IPHONE5来设计，因此很多背景元素是只有320px宽度（页面实际渲染宽度），例如下图。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="&amp;#29609;&amp;#36716;HTML5&amp;#31227;&amp;#21160;&amp;#39029;&amp;#38754;&amp;#65288;&amp;#20248;&amp;#21270;&amp;#31687;&amp;#65289;" height="521" src="http://images.shejidaren.com/wp-content/uploads/2015/04/034816MQF.jpg" width="439"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;那么，这时候就需要设计提供一个较长的延伸背景了，最好是可以重复的，用background-repeat可以减少图片大小。&lt;/p&gt;
 &lt;p&gt;B.设计中期。也就是具体的兼容方法，可以使用CSS3 Media Query和类覆盖。&lt;/p&gt;
 &lt;p&gt;1.CSS3 Media Query，按范围兼容机型。&lt;/p&gt;
 &lt;pre&gt;/*iphone6*/
@media only screen
and (min-device-width : 375px)
and (max-device-width : 667px)
and (orientation : portrait)
and (-webkit-min-device-pixel-ratio : 2)
{
.page6 .ele-building{top: 69px;}
.page6 .ele-runner{top: 100px;}
.page6 .ele-pophome{top: 16px;}
}&lt;/pre&gt;
 &lt;p&gt;2.类覆盖，这种方式适合直接为小屏或大屏做整体兼容。  &lt;br /&gt;
首先，为小屏（大屏）加一个识别类，这里小于420表示为小屏幕（IPHONE4有上下导航栏）：&lt;/p&gt;
 &lt;pre&gt;var bh = $(window).height();
// 480 - 64 = 416 iphone4
if(bh&amp;amp;lt;420){
$(&amp;apos;body&amp;apos;).addClass(&amp;apos;low-screen&amp;apos;);
}&lt;/pre&gt;
 &lt;p&gt;然后，对应识别类加上要变动的元素覆盖，例如：&lt;/p&gt;
 &lt;pre&gt;.page6 .ele-bg{top: 10px;}
.low-screen .page6 .ele-bg{top: 0px;}&lt;/pre&gt;
 &lt;p&gt;C.设计后期。这是最后一步，整体检查和体验，这里面会暴露一些问题，例如元素在IPHONE6P显得小了或者元素在IPHONE4挤不下了，可以来最后大招解决：&lt;/p&gt;
 &lt;p&gt;1.大屏适当用zoom:(倍率)或者transform:scale(倍率)来增大元素，实测失真根本看不出来，设计师也满意（毕竟不用多做一张图！）；  &lt;br /&gt;
2.小屏适当去掉一些元素，例如一些翻页提示，一些多余图标，可以让优雅降级，把它们 display:none掉。&lt;/p&gt;
 &lt;p&gt;有以上几步，基本就能兼容大部分机器了。兼容一直是个苦活，但是这是前端必修课，多练就会发觉其实也没有那么难嘛。&lt;/p&gt;
 &lt;h3&gt;（4）交互提示&lt;/h3&gt;
 &lt;p&gt;前面说了，加了音效就要加上音乐切换开关的按钮，不然会被用户骂死。还有其他，例如如果你的页面不能兼容横屏，请监听横屏状态，然后加上适当的横屏提示。&lt;/p&gt;
 &lt;p&gt;例如：&lt;/p&gt;
 &lt;pre&gt;// 横屏监听
var updateOrientation = function(){
if(window.orientation==&amp;apos;-90&amp;apos; || window.orientation==&amp;apos;90&amp;apos;){
$(&amp;apos;.landscape-wrap&amp;apos;).removeClass(&amp;apos;hide&amp;apos;);
console.log(&amp;apos;为了更好的体验，请将手机/平板竖过来！&amp;apos;);
}else{
$(&amp;apos;.landscape-wrap&amp;apos;).addClass(&amp;apos;hide&amp;apos;);
console.log(&amp;apos;竖屏状态&amp;apos;);
}
};
window.onorientationchange = updateOrientation;&lt;/pre&gt;
 &lt;p&gt;提示越多，界面越友好，有时候设计师会漏掉一些可能出现的页面情况。  &lt;br /&gt;
作为有态度的前端，请好好把关，让用户有好的体验。&lt;/p&gt;
 &lt;h3&gt;（5）分享接口&lt;/h3&gt;
 &lt;p&gt;H5做好了，要传播分享才能展示你的牛逼轰轰。  &lt;br /&gt;
然而分享其实是个坑，分享到微信、手Q等都有各种问题。&lt;/p&gt;
 &lt;p&gt;A.微信&lt;/p&gt;
 &lt;p&gt;旧微信会使用WeixinJSBridge来声明分享的缩略图、标题、正文等，比较方便。例如：  &lt;br /&gt;
  &lt;img alt="&amp;#29609;&amp;#36716;HTML5&amp;#31227;&amp;#21160;&amp;#39029;&amp;#38754;&amp;#65288;&amp;#20248;&amp;#21270;&amp;#31687;&amp;#65289;" height="287" src="http://images.shejidaren.com/wp-content/uploads/2015/04/0348166Q1.png" width="590"&gt;&lt;/img&gt;  &lt;br /&gt;
而最新的微信提供了新的微信SDK，需要在公众账号绑定所属域名之后调用SDK作分享，可以说分享功能会更加强大，坑也会更加少。&lt;/p&gt;
 &lt;p&gt;B.手Q&lt;/p&gt;
 &lt;p&gt;手Q支持声明meta标签的的分享方式，例如：  &lt;br /&gt;
  &lt;img alt="&amp;#29609;&amp;#36716;HTML5&amp;#31227;&amp;#21160;&amp;#39029;&amp;#38754;&amp;#65288;&amp;#20248;&amp;#21270;&amp;#31687;&amp;#65289;" height="96" src="http://images.shejidaren.com/wp-content/uploads/2015/04/034817fAl.png" width="590"&gt;&lt;/img&gt;  &lt;br /&gt;
而若在qq.com域名下也支持api的定义方式。&lt;/p&gt;
 &lt;p&gt;C.一般化分享&lt;/p&gt;
 &lt;p&gt;在默认兼容旧版微信、手Q或者各种浏览器，平台，可以用这样的方法：  &lt;br /&gt;
写h1做标题，p做内容，img做缩略图，只需要把h1隐藏掉就好，这里的缩略图最好要大于200x200px。&lt;/p&gt;
 &lt;p&gt;例如：  &lt;br /&gt;
  &lt;img alt="&amp;#29609;&amp;#36716;HTML5&amp;#31227;&amp;#21160;&amp;#39029;&amp;#38754;&amp;#65288;&amp;#20248;&amp;#21270;&amp;#31687;&amp;#65289;" height="120" src="http://images.shejidaren.com/wp-content/uploads/2015/04/034817G6h.png" width="590"&gt;&lt;/img&gt;  &lt;br /&gt;
当然，这样也有利于搜索引擎拉取信息。&lt;/p&gt;
 &lt;p&gt;分享的坑还有更多，例如不同浏览器例如QQ浏览器、Chrome也会有自己的默认拉取方式（部分截图作缩略图），需要多加测试优化。&lt;/p&gt;
 &lt;h3&gt;（5）SEO搜索引擎优化&lt;/h3&gt;
 &lt;p&gt;SEO（搜索引擎优化）的基本做法是把页面结构写好，这包括：&lt;/p&gt;
 &lt;p&gt;1.定义精确的网页标题。你的标题应该有概括性，能明确告知搜索引擎和用户你的网站大概内容和目的，可以是当前页面标题-所属类型-产品名，例如“全民来猜歌-年费黄钻-QQ空间”。&lt;/p&gt;
 &lt;p&gt;2.针对页面内容补充description和keywords的meta标签。你需要简短总结页面的主要目标，然后补充description，以及根据关键词补充keywords。&lt;/p&gt;
 &lt;p&gt;3.优化你的超链接和图片。包括优化超链接显示的文本，要具有语义性也要跟超链接的网页具有相关性，例如“空间主页”就不要链接到“www.qq.com”。同时，要补充”title”和”alt”属性，例如“&amp;lt;img src=’images/apple.jpg’ title=’苹果示例图’ alt=’苹果示例图’ /&amp;gt;”。&lt;/p&gt;
 &lt;p&gt;4.建立良好的网站导航和sitemap。网站需要有一个良好的导航，控制根目录和各子目录的关键，通过sitemap可以帮助网站主了解网站结构，也方便搜索引擎收录整个站点。&lt;/p&gt;
 &lt;p&gt;5.优化目录结构和URL。你的URL应该有语义性，简短易懂，例如http://www.apple.com/macbook-air/，而且每一层级都要有它对应的页面展示以及语义。&lt;/p&gt;
 &lt;p&gt;6.善用h1-h6的标题结构树。合理的标题可以强调文字，也能让搜索引擎更加了解到各标题的重要性，因此建立良好的标题树十分有意义。&lt;/p&gt;
 &lt;p&gt;7.不断致力于提供优质的内容。社交化分享是网站曝光最快的因素，因此不断提供了优质原创内容才能真正提高你的网站曝光权重。&lt;/p&gt;
 &lt;h3&gt;（6）无障碍&lt;/h3&gt;
 &lt;p&gt;无障碍的普及是一件好事，这让互联网真正地为所有人可用。因此我们也应该为之而努力，无障碍的根基是你页面强壮的语义性和结构性，具体可以参考《  &lt;a href="http://www.qq.com/demo/accessibility.htm" target="_blank"&gt;腾讯网无障碍说明&lt;/a&gt;》了解无障碍的优化手段。&lt;/p&gt;
 &lt;p&gt;最后，罗嗦了这么多，只是我自己的一些小经验，请轻拍砖，多交流。&lt;/p&gt;
 &lt;p&gt;腾讯ISUX (  &lt;a href="http://isux.tencent.com/play-with-html5-optimize.html" rel="nofollow" target="_blank"&gt;http://isux.tencent.com/play-with-html5-optimize.html&lt;/a&gt;)&lt;/p&gt;
 &lt;hr&gt;&lt;/hr&gt;Copyright ©2010-2014 ¦  &lt;a href="http://www.shejidaren.com/feed" target="_blank" title="RSS&amp;#35746;&amp;#38405;"&gt;RSS订阅&lt;/a&gt; ¦  &lt;a href="http://weibo.com/shejidaren888" target="_blank" title="&amp;#26032;&amp;#28010;&amp;#24494;&amp;#21338;"&gt;新浪微博&lt;/a&gt; ¦  &lt;a href="http://www.shejidaren.com/html5-app-page-optimize.html" target="_blank" title="&amp;#29609;&amp;#36716;HTML5&amp;#31227;&amp;#21160;APP&amp;#39029;&amp;#38754;&amp;#65288;&amp;#20248;&amp;#21270;&amp;#31687;&amp;#65289;"&gt;本文链接&lt;/a&gt; ¦  &lt;a href="http://www.shejidaren.com/html5-app-page-optimize.html#respond" target="_blank" title="&amp;#29609;&amp;#36716;HTML5&amp;#31227;&amp;#21160;APP&amp;#39029;&amp;#38754;&amp;#65288;&amp;#20248;&amp;#21270;&amp;#31687;&amp;#65289;&amp;#30340;&amp;#35780;&amp;#35770;"&gt;添加评论&lt;/a&gt;  &lt;br /&gt;交流：UI设计交流群：59300679，与500名设计师交流设计，分享素材。&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>HTML &amp; CSS 前端开发 HTML5</category>
      <guid isPermaLink="true">https://itindex.net/detail/53307-html5-%E7%A7%BB%E5%8A%A8-app</guid>
      <pubDate>Tue, 28 Apr 2015 12:10:42 CST</pubDate>
    </item>
    <item>
      <title>CSS &gt; 选择器优先级与效率优化</title>
      <link>https://itindex.net/detail/54106-css-%E9%80%89%E6%8B%A9-%E4%BC%98%E5%8C%96</link>
      <description>&lt;h1&gt;CSS选择器优先级与效率优化&lt;/h1&gt;

 &lt;blockquote&gt;
    &lt;p&gt;Date: 7th of Aug, 2015&lt;/p&gt;
  
    &lt;p&gt;Author: HaoyCn&lt;/p&gt;
&lt;/blockquote&gt;

 &lt;p&gt;本文收集网上各处关于CSS选择器的文章总结，并自己归纳一篇。&lt;/p&gt;

 &lt;h3&gt;各类选择器的优先级&lt;/h3&gt;

 &lt;ol&gt;
  &lt;li&gt;important声明          1,0,0,0&lt;/li&gt;
  &lt;li&gt;ID选择器                0,1,0,0&lt;/li&gt;
  &lt;li&gt;类选择器             0,0,1,0&lt;/li&gt;
  &lt;li&gt;伪类选择器                0,0,1,0&lt;/li&gt;
  &lt;li&gt;属性选择器                0,0,1,0&lt;/li&gt;
  &lt;li&gt;标签选择器                0,0,0,1&lt;/li&gt;
  &lt;li&gt;伪元素选择器           0,0,0,1&lt;/li&gt;
  &lt;li&gt;通配符选择器           0,0,0,0&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;在上面的选择器中，此外，经测试&lt;/p&gt;

 &lt;p&gt;属性选择器 = 伪类选择器(应用最后一个)&lt;/p&gt;

 &lt;pre&gt;  &lt;code&gt;:last-child{color:red;}
[desc]{color:green;}
&lt;/code&gt;&lt;/pre&gt;

 &lt;p&gt;伪类选择器 &amp;gt; 相邻选择器&lt;/p&gt;

 &lt;pre&gt;  &lt;code&gt;:last-child{color:green;}
p ~ p{color:blue;}
&lt;/code&gt;&lt;/pre&gt;

 &lt;p&gt;相邻选择器 = 子选择器 = 后代选择器(应用最后一个)&lt;/p&gt;

 &lt;pre&gt;  &lt;code&gt;p~p{color:red;}
body p{color:blue;}
body &amp;gt; p{color:green;}
&lt;/code&gt;&lt;/pre&gt;

 &lt;p&gt;后代选择器 &amp;gt; 标签选择器&lt;/p&gt;

 &lt;pre&gt;  &lt;code&gt;p ~ p{color:blue;}
p{color:green;}
&lt;/code&gt;&lt;/pre&gt;

 &lt;h3&gt;样式位置的影响&lt;/h3&gt;

 &lt;ol&gt;
  &lt;li&gt;   &lt;p&gt;    &lt;code&gt;&amp;lt;style&amp;gt;&amp;lt;/style&amp;gt;&lt;/code&gt; 同     &lt;code&gt;&amp;lt;link /&amp;gt;&lt;/code&gt; 同级，应用取决于    &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt;标签和    &lt;code&gt;&amp;lt;link /&amp;gt;&lt;/code&gt; 标签的先后顺序&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;p&gt;元素    &lt;code&gt;style=&amp;quot;&amp;quot;&lt;/code&gt;属性的优先级高于以上两种样式&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;p&gt;    &lt;code&gt;!important&lt;/code&gt; 优先级高于以上两种样式&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;  &lt;strong&gt;备注&lt;/strong&gt;&lt;/p&gt;

 &lt;p&gt;  &lt;code&gt;!important&lt;/code&gt; 在IE6中的BUG：在同一组CSS属性中,   &lt;code&gt;!important&lt;/code&gt;不起作用。如：&lt;/p&gt;

 &lt;pre&gt;  &lt;code&gt;#selector{color:blue !important;color:green;}
&lt;/code&gt;&lt;/pre&gt;

 &lt;h3&gt;选择器效率&lt;/h3&gt;

 &lt;p&gt;读取选择器的原则是从右到左。因此，我们书写的右边的最后一个选择器，被称作关键选择器，对于效率有决定性影响。&lt;/p&gt;

 &lt;p&gt;以下效率排行由   &lt;a href="http://stevesouders.com/" rel="nofollow"&gt;@Steve Souders&lt;/a&gt; 提供。&lt;/p&gt;

 &lt;ol&gt;
  &lt;li&gt;ID选择器&lt;/li&gt;
  &lt;li&gt;类选择器&lt;/li&gt;
  &lt;li&gt;标签选择器&lt;/li&gt;
  &lt;li&gt;相邻选择器&lt;/li&gt;
  &lt;li&gt;子选择器&lt;/li&gt;
  &lt;li&gt;后代选择器&lt;/li&gt;
  &lt;li&gt;通配符选择器&lt;/li&gt;
  &lt;li&gt;属性选择器&lt;/li&gt;
  &lt;li&gt;伪类选择器&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;  &lt;strong&gt;优先级高的不一定效率高&lt;/strong&gt;&lt;/p&gt;

 &lt;p&gt;举个例子：  &lt;code&gt;#id .class&lt;/code&gt; 与   &lt;code&gt;div#id p.class&lt;/code&gt;&lt;/p&gt;

 &lt;p&gt;前者效率高于后者，而后者优先级高于前者。我们需要在效率与优先级之间平衡取舍。&lt;/p&gt;

 &lt;h3&gt;优化建议&lt;/h3&gt;

 &lt;p&gt;以下网址提供了诸多建议：&lt;/p&gt;

 &lt;p&gt;  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Writing_efficient_CSS" rel="nofollow"&gt;&lt;/a&gt;  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Writing_efficient_CSS" rel="nofollow"&gt;https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Writing_efficie...&lt;/a&gt;&lt;/p&gt;

 &lt;p&gt;扼要摘其精要总结如下：&lt;/p&gt;

 &lt;ol&gt;
  &lt;li&gt;   &lt;p&gt;避免使用通配符&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;p&gt;不使用标签名或类名修饰ID规则：如果规则使用ID选择器作为关键选择器，不要给规则添加标签名。因为ID本身就是唯一的，添加标签名会不必要地降低匹配效率。&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;p&gt;不使用标签名修饰类：相较于标签，类更具独特性。&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;p&gt;尽量选择最具体的方式：造成低效的最简单粗暴的原因就是在标签上使用太多规则。给元素添加类可以更快细分到类方式，可以减少规则去匹配标签的时间。&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;p&gt;关于后代选择器和子选择器：避免使用后代选择器，非要用的话建议用子选择器代替，但子选择器也要慎用，标签规则永远不要包含子选择器。&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;p&gt;利用可继承性：没必要在一般内容上声明样式。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>css css选择器</category>
      <guid isPermaLink="true">https://itindex.net/detail/54106-css-%E9%80%89%E6%8B%A9-%E4%BC%98%E5%8C%96</guid>
      <pubDate>Fri, 07 Aug 2015 17:18:29 CST</pubDate>
    </item>
    <item>
      <title>HTML head 头标签</title>
      <link>https://itindex.net/detail/52513-html-head-%E6%A0%87%E7%AD%BE</link>
      <description>&lt;p&gt;  &lt;strong&gt;标签：&lt;/strong&gt;    &lt;a href="http://blogread.cn/it/tags.php?tag=head" target="_blank"&gt;head&lt;/a&gt;&lt;/p&gt; &lt;p&gt;HTML head 头部分的标签、元素有很多，涉及到浏览器对网页的渲染，SEO 等等，而各个浏览器内核以及各个国内浏览器厂商都有些自己的标签元素,这就造成了很多差异性。移动互联网时代，head 头部结构，移动端的 meta 元素，显得更为重要。了解每个标签的意义，写出满足自己需求的 head 头标签，是本文的目的。本篇以  &lt;a href="https://github.com/yisibl/blog/issues/1" target="_blank"&gt;一丝的文章&lt;/a&gt;为基础，进行扩展总结介绍常用的 head 中各个标签、元素的意义以及使用场景。&lt;/p&gt; &lt;h3&gt;DOCTYPE&lt;/h3&gt; &lt;p&gt;DOCTYPE(Document Type)，该声明位于文档中最前面的位置，处于   &lt;code&gt;html&lt;/code&gt; 标签之前，此标签告知浏览器文档使用哪种 HTML 或者 XHTML 规范。&lt;/p&gt; &lt;p&gt;DTD(Document Type Definition) 声明以   &lt;code&gt;&amp;lt;!DOCTYPE&amp;gt;&lt;/code&gt; 开始，不区分大小写，前面没有任何内容，如果有其他内容(空格除外)会使浏览器在 IE 下开启怪异模式(quirks mode)渲染网页。公共 DTD，名称格式为  &lt;code&gt;注册//组织//类型 标签//语言&lt;/code&gt;,  &lt;code&gt;注册&lt;/code&gt;指组织是否由国际标准化组织(ISO)注册，  &lt;code&gt;+&lt;/code&gt;表示是，  &lt;code&gt;-&lt;/code&gt;表示不是。  &lt;code&gt;组织&lt;/code&gt;即组织名称，如：W3C。  &lt;code&gt;类型&lt;/code&gt;一般是 DTD。  &lt;code&gt;标签&lt;/code&gt;是指定公开文本描述，即对所引用的公开文本的唯一描述性名称，后面可附带版本号。最后  &lt;code&gt;语言&lt;/code&gt;是 DTD 语言的 ISO 639 语言标识符，如：EN 表示英文，ZH 表示中文。XHTML 1.0 可声明三种 DTD 类型。分别表示严格版本，过渡版本，以及基于框架的 HTML 文档。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;p&gt;HTML 4.01 strict&lt;/p&gt;   &lt;div&gt;    &lt;pre&gt;     &lt;code&gt;&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;HTML 4.01 Transitional&lt;/p&gt;   &lt;div&gt;    &lt;pre&gt;     &lt;code&gt;&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/loose.dtd&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;HTML 4.01 Frameset&lt;/p&gt;   &lt;div&gt;    &lt;pre&gt;     &lt;code&gt;&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01 Frameset//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/frameset.dtd&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;最新 HTML5 推出更加简洁的书写，它向前向后兼容，推荐使用。&lt;/p&gt;   &lt;div&gt;    &lt;pre&gt;     &lt;code&gt;&amp;lt;!doctype html&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;在 HTML中   &lt;code&gt;doctype&lt;/code&gt; 有两个主要目的。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;p&gt;对文档进行有效性验证。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;它告诉用户代理和校验器这个文档是按照什么 DTD 写的。这个动作是被动的，每次页面加载时，浏览器并不会下载 DTD 并检查合法性，只有当手动校验页面时才启用。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;p&gt;决定浏览器的呈现模式&lt;/p&gt;   &lt;p&gt;对于实际操作，通知浏览器读取文档时用哪种解析算法。如果没有写，则浏览器则根据自身的规则对代码进行解析，可能会严重影响 html 排版布局。浏览器有三种方式解析 HTML 文档。&lt;/p&gt;   &lt;ul&gt;    &lt;li&gt;     &lt;p&gt;非怪异（标准）模式&lt;/p&gt;&lt;/li&gt;    &lt;li&gt;     &lt;p&gt;怪异模式&lt;/p&gt;&lt;/li&gt;    &lt;li&gt;     &lt;p&gt;部分怪异（近乎标准）模式 关于IE浏览器的文档模式，浏览器模式，严格模式，怪异模式，DOCTYPE 标签，可详细阅读      &lt;a href="http://padding.me/blog/2014/07/04/mode-or-standard/" target="_blank"&gt;模式？标准！&lt;/a&gt;的内容。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;charset&lt;/h3&gt; &lt;p&gt;声明文档使用的字符编码，&lt;/p&gt; &lt;div&gt;  &lt;pre&gt;   &lt;code&gt;&amp;lt;metacharset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;html5 之前网页中会这样写：&lt;/p&gt; &lt;div&gt;  &lt;pre&gt;   &lt;code&gt;&amp;lt;metahttp-equiv=&amp;quot;Content-Type&amp;quot;content=&amp;quot;text/html; charset=utf-8&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;这两个是等效的，具体可移步阅读：  &lt;a href="http://stackoverflow.com/questions/4696499/meta-charset-utf-8-vs-meta-http-equiv-content-type" target="_blank"&gt;   &lt;code&gt;&amp;lt;meta charset=&amp;apos;utf-8&amp;apos;&amp;gt;&lt;/code&gt; vs    &lt;code&gt;&amp;lt;meta http-equiv=&amp;apos;Content-Type&amp;apos;&amp;gt;&lt;/code&gt;&lt;/a&gt;，所以建议使用较短的，易于记忆。&lt;/p&gt; &lt;h3&gt;lang属性&lt;/h3&gt; &lt;p&gt;简体中文&lt;/p&gt; &lt;div&gt;  &lt;pre&gt;   &lt;code&gt;&amp;lt;htmllang=&amp;quot;zh-cmn-Hans&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;繁体中文&lt;/p&gt; &lt;div&gt;  &lt;pre&gt;   &lt;code&gt;&amp;lt;htmllang=&amp;quot;zh-cmn-Hant&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;为什么   &lt;code&gt;lang=&amp;quot;zh-cmn-Hans&amp;quot;&lt;/code&gt; 而不是我们通常写的   &lt;code&gt;lang=&amp;quot;zh-CN&amp;quot;&lt;/code&gt; 呢，请移步阅读:   &lt;a href="http://zhi.hu/XyIa" target="_blank"&gt;页头部的声明应该是用 lang=&amp;quot;zh&amp;quot; 还是 lang=&amp;quot;zh-cn&amp;quot;&lt;/a&gt;。&lt;/p&gt; &lt;h3&gt;优先使用 IE 最新版本和 Chrome&lt;/h3&gt; &lt;div&gt;  &lt;pre&gt;   &lt;code&gt;&amp;lt;metahttp-equiv=&amp;quot;X-UA-Compatible&amp;quot;content=&amp;quot;IE=edge,chrome=1&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;h3&gt;360 使用Google Chrome Frame&lt;/h3&gt; &lt;div&gt;  &lt;pre&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;renderer&amp;quot;content=&amp;quot;webkit&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;360 浏览器就会在读取到这个标签后，立即切换对应的极速核。 另外为了保险起见再加入&lt;/p&gt; &lt;div&gt;  &lt;pre&gt;   &lt;code&gt;&amp;lt;metahttp-equiv=&amp;quot;X-UA-Compatible&amp;quot;content=&amp;quot;IE=Edge,chrome=1&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;这样写可以达到的效果是如果安装了 Google Chrome Frame，则使用 GCF 来渲染页面，如果没有安装 GCF，则使用最高版本的 IE 内核进行渲染。&lt;/p&gt; &lt;p&gt;相关链接：  &lt;a href="http://se.360.cn/v6/help/meta.html" target="_blank"&gt;浏览器内核控制 Meta 标签说明文档&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;百度禁止转码&lt;/h3&gt; &lt;p&gt;通过百度手机打开网页时，百度可能会对你的网页进行转码，脱下你的衣服，往你的身上贴狗皮膏药的广告，为此可在 head 内添加&lt;/p&gt; &lt;div&gt;  &lt;pre&gt;   &lt;code&gt;&amp;lt;metahttp-equiv=&amp;quot;Cache-Control&amp;quot;content=&amp;quot;no-siteapp&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;相关链接：  &lt;a href="http://m.baidu.com/pub/help.php?pn=22&amp;ssid=0&amp;from=844b&amp;bd_page_type=1" target="_blank"&gt;SiteApp 转码声明&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;SEO 优化部分&lt;/h3&gt; &lt;ul&gt;  &lt;li&gt;   &lt;p&gt;页面标题    &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt;标签(head 头部必须)&lt;/p&gt;   &lt;div&gt;    &lt;pre&gt;     &lt;code&gt;&amp;lt;title&amp;gt;your title&amp;lt;/title&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;页面关键词 keywords&lt;/p&gt;   &lt;div&gt;    &lt;pre&gt;     &lt;code&gt;&amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;your keywords&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;页面描述内容 description&lt;/p&gt;   &lt;div&gt;    &lt;pre&gt;     &lt;code&gt;&amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;your description&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;定义网页作者 author&lt;/p&gt;   &lt;div&gt;    &lt;pre&gt;     &lt;code&gt;&amp;lt;meta name=&amp;quot;author&amp;quot; content=&amp;quot;author,email address&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;定义网页搜索引擎索引方式，robotterms 是一组使用英文逗号「,」分割的值，通常有如下几种取值：none，noindex，nofollow，all，index和follow。&lt;/p&gt;   &lt;div&gt;    &lt;pre&gt;     &lt;code&gt;&amp;lt;meta name=&amp;quot;robots&amp;quot; content=&amp;quot;index,follow&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;相关链接：  &lt;a href="http://msdn.microsoft.com/zh-cn/library/ff724037(v=expression.40).aspx" target="_blank"&gt;WEB1038 - 标记包含无效的值&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;viewport&lt;/h3&gt; &lt;p&gt;  &lt;code&gt;viewport&lt;/code&gt; 可以让布局在移动浏览器上显示的更好。 通常会写&lt;/p&gt; &lt;div&gt;  &lt;pre&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;viewport&amp;quot;content=&amp;quot;width=device-width, initial-scale=1.0&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;  &lt;code&gt;width=device-width&lt;/code&gt; 会导致 iPhone 5 添加到主屏后以 WebApp 全屏模式打开页面时出现黑边(  &lt;a href="http://bigc.at/ios-webapp-viewport-meta.orz" target="_blank"&gt;http://bigc.at/ios-webapp-viewport-meta.orz&lt;/a&gt;)&lt;/p&gt; &lt;p&gt;content 参数：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;p&gt;width viewport 宽度(数值/device-width)&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;height viewport 高度(数值/device-height)&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;initial-scale 初始缩放比例&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;maximum-scale 最大缩放比例&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;minimum-scale 最小缩放比例&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;user-scalable 是否允许用户缩放(yes/no)&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;minimal-ui iOS 7.1 beta 2 中新增属性，可以在页面加载时最小化上下状态栏。这是一个布尔值，可以直接这样写：&lt;/p&gt;   &lt;div&gt;    &lt;pre&gt;     &lt;code&gt;&amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1, minimal-ui&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;而如果你的网站不是响应式的，请不要使用 initial-scale 或者禁用缩放。&lt;/p&gt; &lt;div&gt;  &lt;pre&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;viewport&amp;quot;content=&amp;quot;width=device-width,user-scalable=yes&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;相关链接：  &lt;a href="http://www.qianduan.net/non-responsive-design-viewport.html" target="_blank"&gt;非响应式设计的viewport&lt;/a&gt;&lt;/p&gt; &lt;p&gt;适配 iPhone 6 和 iPhone 6plus 则需要写：&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;viewport&amp;quot;content=&amp;quot;width=375&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;viewport&amp;quot;content=&amp;quot;width=414&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;大部分 4.7~5 寸的安卓设备的 viewport 宽设为 360px，iPhone 6 上却是 375px，大部分 5.5 寸安卓机器（比如说三星 Note）的 viewport 宽为 400，iPhone 6 plus 上是 414px。&lt;/p&gt; &lt;h3&gt;ios 设备&lt;/h3&gt; &lt;p&gt;添加到主屏后的标题（iOS 6 新增）&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;apple-mobile-web-app-title&amp;quot;content=&amp;quot;标题&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- 添加到主屏后的标题（iOS 6 新增） --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;是否启用 WebApp 全屏模式&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;apple-mobile-web-app-capable&amp;quot;content=&amp;quot;yes&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- 是否启用 WebApp 全屏模式 --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;设置状态栏的背景颜色&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;apple-mobile-web-app-status-bar-style&amp;quot;content=&amp;quot;black-translucent&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- 设置状态栏的背景颜色，只有在 `&amp;quot;apple-mobile-web-app-capable&amp;quot; content=&amp;quot;yes&amp;quot;` 时生效 --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;只有在 &amp;quot;apple-mobile-web-app-capable&amp;quot; content=&amp;quot;yes&amp;quot; 时生效&lt;/p&gt; &lt;p&gt;content 参数：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;p&gt;default 默认值。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;black 状态栏背景是黑色。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;black-translucent 状态栏背景是黑色半透明。 如果设置为 default 或 black ,网页内容从状态栏底部开始。 如果设置为 black-translucent ,网页内容充满整个屏幕，顶部会被状态栏遮挡。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;禁止数字识自动别为电话号码&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;format-detection&amp;quot;content=&amp;quot;telephone=no&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- 禁止数字识自动别为电话号码 --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;h3&gt;iOS 图标&lt;/h3&gt; &lt;p&gt;rel 参数： apple-touch-icon 图片自动处理成圆角和高光等效果。 apple-touch-icon-precomposed 禁止系统自动添加效果，直接显示设计原图。 iPhone 和 iTouch，默认 57x57 像素，必须有&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;apple-touch-icon-precomposed&amp;quot;href=&amp;quot;/apple-touch-icon-57x57-precomposed.png&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- iPhone 和 iTouch，默认 57x57 像素，必须有 --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;iPad，72x72 像素，可以没有，但推荐有&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;apple-touch-icon-precomposed&amp;quot;sizes=&amp;quot;72x72&amp;quot;href=&amp;quot;/apple-touch-icon-72x72-precomposed.png&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- iPad，72x72 像素，可以没有，但推荐有 --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;Retina iPhone 和 Retina iTouch，114x114 像素，可以没有，但推荐有&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;apple-touch-icon-precomposed&amp;quot;sizes=&amp;quot;114x114&amp;quot;href=&amp;quot;/apple-touch-icon-114x114-precomposed.png&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- Retina iPhone 和 Retina iTouch，114x114 像素，可以没有，但推荐有 --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;Retina iPad，144x144 像素，可以没有，但推荐有&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;apple-touch-icon-precomposed&amp;quot;sizes=&amp;quot;144x144&amp;quot;href=&amp;quot;/apple-touch-icon-144x144-precomposed.png&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- Retina iPad，144x144 像素，可以没有，但推荐有 --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;IOS 图标大小在iPhone 6 plus上是180×180，iPhone 6 是120x120。 适配iPhone 6 plus，则需要在中加上这段&lt;/p&gt; &lt;div&gt;  &lt;pre&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;apple-touch-icon-precomposed&amp;quot;sizes=&amp;quot;180x180&amp;quot;href=&amp;quot;retinahd_icon.png&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;h3&gt;iOS 启动画面&lt;/h3&gt; &lt;p&gt;官方文档：  &lt;a href="https://developer.apple.com/library/ios/qa/qa1686/_index.html" target="_blank"&gt;https://developer.apple.com/library/ios/qa/qa1686/_index.html&lt;/a&gt; 参考文章：  &lt;a href="http://wxd.ctrip.com/blog/2013/09/ios7-hig-24/" target="_blank"&gt;http://wxd.ctrip.com/blog/2013/09/ios7-hig-24/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;iPad 的启动画面是不包括状态栏区域的。&lt;/p&gt; &lt;p&gt;iPad 竖屏 768 x 1004（标准分辨率）&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;apple-touch-startup-image&amp;quot;sizes=&amp;quot;768x1004&amp;quot;href=&amp;quot;/splash-screen-768x1004.png&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- iPad 竖屏 768 x 1004（标准分辨率） --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;iPad 竖屏 1536x2008（Retina）&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;apple-touch-startup-image&amp;quot;sizes=&amp;quot;1536x2008&amp;quot;href=&amp;quot;/splash-screen-1536x2008.png&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- iPad 竖屏 1536x2008（Retina） --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;iPad 横屏 1024x748（标准分辨率）&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;apple-touch-startup-image&amp;quot;sizes=&amp;quot;1024x748&amp;quot;href=&amp;quot;/Default-Portrait-1024x748.png&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- iPad 横屏 1024x748（标准分辨率） --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;iPad 横屏 2048x1496（Retina）&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;apple-touch-startup-image&amp;quot;sizes=&amp;quot;2048x1496&amp;quot;href=&amp;quot;/splash-screen-2048x1496.png&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- iPad 横屏 2048x1496（Retina） --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;iPhone 和 iPod touch 的启动画面是包含状态栏区域的。&lt;/p&gt; &lt;p&gt;iPhone/iPod Touch 竖屏 320x480 (标准分辨率)&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;apple-touch-startup-image&amp;quot;href=&amp;quot;/splash-screen-320x480.png&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- iPhone/iPod Touch 竖屏 320x480 (标准分辨率) --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;iPhone/iPod Touch 竖屏 640x960 (Retina)&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;apple-touch-startup-image&amp;quot;sizes=&amp;quot;640x960&amp;quot;href=&amp;quot;/splash-screen-640x960.png&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- iPhone/iPod Touch 竖屏 640x960 (Retina) --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;iPhone 5/iPod Touch 5 竖屏 640x1136 (Retina)&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;apple-touch-startup-image&amp;quot;sizes=&amp;quot;640x1136&amp;quot;href=&amp;quot;/splash-screen-640x1136.png&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- iPhone 5/iPod Touch 5 竖屏 640x1136 (Retina) --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;添加智能 App 广告条 Smart App Banner（iOS 6+ Safari）&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;apple-itunes-app&amp;quot;content=&amp;quot;app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- 添加智能 App 广告条 Smart App Banner（iOS 6+ Safari） --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;iPhone 6对应的图片大小是750×1294，iPhone 6 Plus 对应的是1242×2148 。&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;apple-touch-startup-image&amp;quot;href=&amp;quot;launch6.png&amp;quot;media=&amp;quot;(device-width: 375px)&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;apple-touch-startup-image&amp;quot;href=&amp;quot;launch6plus.png&amp;quot;media=&amp;quot;(device-width: 414px)&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;h3&gt;Windows 8&lt;/h3&gt; &lt;p&gt;Windows 8 磁贴颜色&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;msapplication-TileColor&amp;quot;content=&amp;quot;#000&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- Windows 8 磁贴颜色 --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;Windows 8 磁贴图标&lt;/p&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;msapplication-TileImage&amp;quot;content=&amp;quot;icon.png&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- Windows 8 磁贴图标 --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;h3&gt;rss订阅&lt;/h3&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;alternate&amp;quot;type=&amp;quot;application/rss+xml&amp;quot;title=&amp;quot;RSS&amp;quot;href=&amp;quot;/rss.xml&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- 添加 RSS 订阅 --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;h3&gt;favicon icon&lt;/h3&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;linkrel=&amp;quot;shortcut icon&amp;quot;type=&amp;quot;image/ico&amp;quot;href=&amp;quot;/favicon.ico&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- 添加 favicon icon --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;比较详细的 favicon 介绍可参考  &lt;a href="https://github.com/audreyr/favicon-cheat-sheet" target="_blank"&gt;https://github.com/audreyr/favicon-cheat-sheet&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;移动端的meta&lt;/h3&gt; &lt;div&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;viewport&amp;quot;content=&amp;quot;width=device-width, initial-scale=1, user-scalable=no&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;apple-mobile-web-app-capable&amp;quot;content=&amp;quot;yes&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;apple-mobile-web-app-status-bar-style&amp;quot;content=&amp;quot;black&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;format-detection&amp;quot;content=&amp;quot;telephone=no, email=no&amp;quot;/&amp;gt;&amp;lt;metaname=&amp;quot;viewport&amp;quot;content=&amp;quot;width=device-width, initial-scale=1, user-scalable=no&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;apple-mobile-web-app-capable&amp;quot;content=&amp;quot;yes&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- 删除苹果默认的工具栏和菜单栏 --&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;apple-mobile-web-app-status-bar-style&amp;quot;content=&amp;quot;black&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- 设置苹果工具栏颜色 --&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;format-detection&amp;quot;content=&amp;quot;telphone=no, email=no&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- 忽略页面中的数字识别为电话，忽略email识别 --&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- 启用360浏览器的极速模式(webkit) --&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;renderer&amp;quot;content=&amp;quot;webkit&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- 避免IE使用兼容模式 --&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metahttp-equiv=&amp;quot;X-UA-Compatible&amp;quot;content=&amp;quot;IE=edge&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- 针对手持设备优化，主要是针对一些老的不识别viewport的浏览器，比如黑莓 --&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;HandheldFriendly&amp;quot;content=&amp;quot;true&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- 微软的老式浏览器 --&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;MobileOptimized&amp;quot;content=&amp;quot;320&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- uc强制竖屏 --&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;screen-orientation&amp;quot;content=&amp;quot;portrait&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- QQ强制竖屏 --&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;x5-orientation&amp;quot;content=&amp;quot;portrait&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- UC强制全屏 --&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;full-screen&amp;quot;content=&amp;quot;yes&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- QQ强制全屏 --&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;x5-fullscreen&amp;quot;content=&amp;quot;true&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- UC应用模式 --&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;browsermode&amp;quot;content=&amp;quot;application&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- QQ应用模式 --&amp;gt;&amp;lt;metaname=&amp;quot;x5-page-mode&amp;quot;content=&amp;quot;app&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- windows phone 点击无高光 --&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;metaname=&amp;quot;msapplication-tap-highlight&amp;quot;content=&amp;quot;no&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;   &lt;code&gt;&amp;lt;!-- 适应移动端end --&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;这是来自   &lt;a href="http://weibo.com/toooobug" target="_blank"&gt;toobug&lt;/a&gt; 的分享总结。&lt;/p&gt; &lt;p&gt;更多的 meta 标签参考&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;p&gt;    &lt;a href="http://code.lancepollard.com/complete-list-of-html-meta-tags/" target="_blank"&gt;COMPLETE LIST OF HTML META TAGS&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;a href="http://www.iacquire.com/blog/18-meta-tags-every-webpage-should-have-in-2013" target="_blank"&gt;18 Meta Tags Every Webpage Should Have in 2013&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;参考文章：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;p&gt;    &lt;a href="https://github.com/yisibl/blog/issues/1" target="_blank"&gt;常用的 HTML 头部标签&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;a href="https://gist.github.com/paddingme/6182708733917ae36331" target="_blank"&gt;html5_header&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;a href="http://amazeui.org/css/" target="_blank"&gt;amazeui css&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;a href="http://www.douban.com/note/170560091/" target="_blank"&gt;DOCTYPE&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;a href="http://www.uisdc.com/ios8-ten-new-feature" target="_blank"&gt;WEB 工程师和设计师必学的 10 个 IOS 8 新鲜改变&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;br /&gt;&lt;/p&gt;
				 &lt;p&gt;  &lt;strong&gt;您可能还对下面的文章感兴趣：&lt;/strong&gt;&lt;/p&gt;
				 &lt;p&gt;  &lt;ol&gt;   &lt;li&gt;    &lt;a href="http://blogread.cn/it/article.php?id=7239" target="_blank"&gt;移动前端不得不了解的html5 head 头标签&lt;/a&gt; [2015-01-11 23:23:12]&lt;/li&gt;&lt;/ol&gt;&lt;/p&gt; &lt;img alt="" height="1" src="http://feeds.feedburner.com/~r/blogreadIT/~4/XGSnmEFpwGE" width="1"&gt;&lt;/img&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>CSS/HTML</category>
      <guid isPermaLink="true">https://itindex.net/detail/52513-html-head-%E6%A0%87%E7%AD%BE</guid>
      <pubDate>Sat, 17 Jan 2015 08:16:40 CST</pubDate>
    </item>
    <item>
      <title>几个前端UI框架的的比较</title>
      <link>https://itindex.net/detail/52747-%E5%89%8D%E7%AB%AF-ui-%E6%A1%86%E6%9E%B6</link>
      <description>&lt;p&gt;首先是在问答里面看到了一个问题：  &lt;br /&gt;
CSS框架 ui 有哪些啊（  &lt;a href="http://segmentfault.com/q/1010000002547926" rel="nofollow"&gt;http://segmentfault.com/q/1010000002547926&lt;/a&gt;）&lt;/p&gt;

 &lt;p&gt;刚开始接触HTML刚开始接触JS我也不懂就看了下- 正好我也在考虑怎么用HTML来搭我的APP UI。作为初学者，我发现Amaze UI是中文的，觉得对初学者看起来会更简单 - 尤其对HTML CSS等一窍不通，很快有人推荐了Ratchet，看了下感觉用来做手机APP确实很简单的样子.. 开始纠结了.. 跟公司大神讨教了下什么是UI框架以及一些主流的框架区别 优劣势，以及我们一些项目上使用的内容后，大神总结出了以下内容，受益匪浅 - 作为答案有点长，以博文形式发出来供大家一起探讨下：&lt;/p&gt;

 &lt;p&gt;------- 以下分割线 --------  &lt;br /&gt;
IoTgo 用的是 Bootstrap（  &lt;a href="http://getbootstrap.com" rel="nofollow"&gt;http://getbootstrap.com&lt;/a&gt;），原先是 Twitter 内部的一个 CSS 框架，后来开源放到 Github 上，成了 Github 上最热门的项目。Bootstrap 在 3.0 版本之前，都是以桌面优先，在 3.0 版本后，采用移动优先，即很好的支持移动平台，然后才考虑更好的支持桌面。所以 Bootstrap 对手机的支持也很好。&lt;/p&gt;

 &lt;p&gt;Foundation（foundation.zurb.com） 是设计公司 zurb.com 推出的开源 CSS 框架，在 CSS 框架领域是目前唯一能跟 Bootstrap 的竞争的项目。Foundation 的可定制性更好一些（因为是设计公司的产品，要应对各种客户需求），但入手难度也高一些。对于很多 Web 项目开发者而言，他们需要的就是一套简单快捷的 UI，对其美观性、可定制性要求不是太高，所以目前相对来讲 Foundation 没有 Bootstrap 热门。&lt;/p&gt;

 &lt;p&gt;答案中推荐的Ratchet如何：  &lt;br /&gt;
Ratchet 之前也是 Twitter 内部的一个 CSS 框架，后来也是开源到 Github 上，目前是作为 Bootstrap 的子项目存在（  &lt;a href="http://blog.getbootstrap.com/2014/04/02/ratchet-2-0-2-released/" rel="nofollow"&gt;http://blog.getbootstrap.com/2014/04/02/ratchet-2-0-2-released/&lt;/a&gt;），开发 Ratchet 和 Bootstrap 的基本就是同一拨人。Ratchet 一开始就以移动为先，预先提供了很多移动平台的常见 UI 工具，比如底部 Tab 标签栏、顶部标题及后退按钮、滑动的侧边栏等等——Bootstrap 也有，只是很多以插件形式存在，又或者需要自己做一些修改，不像 Ratchet 默认就有。&lt;/p&gt;

 &lt;p&gt;如果是做一个小项目，而且只以手机 App 的形式存在，可以考虑先用 Ratchet，如果同时兼容桌面，Bootstrap 更好一些。而且 Bootstrap 更新的速度更快，马上 4.0 版本就要出来了，有很多针对移动平台优化的特性，而 Ratchet 已经快一年没更新了。&lt;/p&gt;

 &lt;p&gt;另外，目前的移动 CSS 框架（或者更合适的说，UI 框架），还有 Facebook 的 React（  &lt;a href="http://facebook.github.io/react/" rel="nofollow"&gt;http://facebook.github.io/react/&lt;/a&gt;），Google 的 Angular Material（  &lt;a href="https://material.angularjs.org" rel="nofollow"&gt;https://material.angularjs.org&lt;/a&gt;），Telerik 的 Kendo UI(www.telerik.com/kendo-ui)，还有预先捆绑了 Cordova 的 Ionic Framework（ionicframework.com）等等。大家的评价大致是：&lt;/p&gt;

 &lt;ul&gt;
  &lt;li&gt;React：性能很好，因为采用了 Virtual DOM，但没有默认支持 2 way data binding（双向数据绑定），程序员需要自己做更多的工作来通过 UI 获取用户的输入&lt;/li&gt;
  &lt;li&gt;Angular Material：前景非常好，只是目前处于 pre-release 阶段（代码兼容性和稳定性都不是很好）。Angular目前几乎已经是前台 MVC 框架的事实标准（大约 70% 以上的占有率，其他的还有 Ember、Meteor、Backbone等等），Angular Material 基于 Google Material Design 开发，默认支持 Angular，因而在 UI的美观型和开发效率上都比较好。但性能是个问题，解决性能问题，需要程序员自己对代码做优化&lt;/li&gt;
  &lt;li&gt;Kendo UI：非常完备的 UI 框架，但是是商业版（前段时间将部分核心模块开源了）。开发商业 Web 或移动产品的企业更倾向Kendo UI 一些，因为可以得到很好的技术支持（当然要花钱）。Angular 热门知会，Telerik 也升级了 Kendo UI，使其能够较好的跟 Angular 交互——Kendo UI 是 UI，Angular 是前台代码逻辑&lt;/li&gt;
  &lt;li&gt;Ionic Framework：目前非常热门，因为他在 Angular 的基础上开发了支持移动平台的 UI Widget（UI组件）。Ionic Framework 搭好了整套移动开发环境（指的是 App 开发，不是网站移动版）、UI 套件、JS框架（Angular），因而在 2014 年获得巨大的社区反响。被誉为最有前景的移动开发框架（不仅仅是 UI 了）。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;我个人对 Angular 比较热衷，所以都会选择能够很好跟 Angular 交互的 CSS/UI 框架——一般来说，如果是纯 CSS 框架，那么跟任一一个 MVC 框架（比如 Angular、Ember）都可以很好的配合；如果是 UI 框架，可能会有一些冲突。&lt;/p&gt;

 &lt;p&gt;之前我们的智能开关手机 App 是基于 Ionic Framework 来开发的，后来切换到 Angular Material。一个是 Ionic Framework 虽然入手简单，但出现 Bug 我搞不清楚该怎么修改（需要花时间研究 Ionic Framework 的内部工作机制），二是我认为 Material Design 会成为 UI 设计的主流思想，Angular Material 会很快成熟起来。&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>前端框架 css框架</category>
      <guid isPermaLink="true">https://itindex.net/detail/52747-%E5%89%8D%E7%AB%AF-ui-%E6%A1%86%E6%9E%B6</guid>
      <pubDate>Wed, 11 Feb 2015 11:14:40 CST</pubDate>
    </item>
    <item>
      <title>可视化格式模型（ Visual formatting model）再学习</title>
      <link>https://itindex.net/detail/53268-%E5%8F%AF%E8%A7%86%E5%8C%96-%E6%A0%BC%E5%BC%8F-%E6%A8%A1%E5%9E%8B</link>
      <description>&lt;p&gt;“理论不懂就实践，实践不会就学理论”，非常赞同bluedavy的这句话。实践过程中经常会遇到某个属性的使用，浏览器渲染效果与预期效果不符，虽然通过死记硬背能避免或巧妙应用这种效果，但总感心虚发慌、毫无自信，因为不知晓背后的原理。这时就不要再用“就是这样的”的借口来搪塞自己，我们需要重新认识它。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;场景：&lt;/strong&gt;  &lt;a href="http://topcss.org/demo/absolute-positioning.html" target="_blank"&gt;DEMO&lt;/a&gt;&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;元素A，C绝对定位，不设置top，bottom值；&lt;/li&gt;
  &lt;li&gt;元素B处于常规流中；&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;  &lt;strong&gt;问题：&lt;/strong&gt;为什么元素C的位置受元素B的影响，跟随在元素B的下方？  &lt;br /&gt;
  &lt;img alt="abs-top-bottom-auto" height="295" src="http://www.topcss.org/wp-content/uploads/2015/04/abs-top-bottom-auto.gif" width="551"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;为了解决这个问题，我重新学习了CSS 2.1规范中的  &lt;a href="http://www.w3.org/TR/2011/REC-CSS2-20110607/visuren.html" target="_blank"&gt;9 Visual formatting model&lt;/a&gt;和  &lt;a href="http://www.w3.org/TR/2011/REC-CSS2-20110607/visudet.html" target="_blank"&gt;10 Visual formatting model details&lt;/a&gt;。&lt;/p&gt;
 &lt;p&gt;这两章讲解了可视化格式模型：用户代理在视觉媒体上如何处理文档树。在可视化格式模型中，文档树中的每个元素根据框模型（box modal）生成0或多个框。这些框的布局由以下因素决定：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;框尺寸和类型&lt;/li&gt;
  &lt;li&gt;定位方案（常规流、浮动和绝对定位）&lt;/li&gt;
  &lt;li&gt;文档树中元素之间的关系&lt;/li&gt;
  &lt;li&gt;外部信息（比如viewport尺寸、图像的固有尺寸等）&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;9.1.2 Containing blocks（包含块）&lt;/h2&gt;
 &lt;p&gt;CSS 2.1中，许多框的位置和尺寸的计算是相对于一个矩形框的边缘，这个矩形框称为  &lt;strong&gt;包含块&lt;/strong&gt;。通常情况下，生成框是后代框的包含块（generated boxes act as containing blocks for descendant boxes;），称之为一个框为其后代创建了包含块。短语“一个框的包含块”指的是“这个框存在其中的包含块”，而非它生成的框。&lt;/p&gt;
 &lt;p&gt;每个框会相对于其包含块赋予位置，但它并不囿于包含块，可能会溢出（overflow）。包含块的尺寸计算细节在第10章有详细介绍。&lt;/p&gt;
 &lt;h2&gt;9.2 Controlling box generation（控制框生成）&lt;/h2&gt;
 &lt;p&gt;本节描述了CSS 2.1中可生成的框类型。一个框的类型部分地影响其在可视化格式模型中的行为。&lt;/p&gt;
 &lt;h3&gt;9.2.1 Block-level elements and block boxes&lt;/h3&gt;
 &lt;p&gt;处在块格式化环境（BFC，block formatting context）中的框称之为  &lt;strong&gt;块级框（block-level box）。&lt;/strong&gt;每个块级元素生成一个包含后代框和生成的内容的主体块级框，同时这个框与定位方案密切相关。有些块级元素除了生成主体框外，还会生成一个附加框，如’list-item’元素。附加框相对于主体框定位。&lt;/p&gt;
 &lt;p&gt;表框（table boxes）和替换元素（replaced elements）外，块级框同时也是  &lt;strong&gt;块容器框（block container box）&lt;/strong&gt;。块容器框要么仅包含块级框，要么建立一个行内格式化环境（IFC，inline formatting context），即仅包含行内级框。并非所有的块容器框都是块级框：非替换行内块（inline blocks）和非替换表格单元格都是块容器，但不是块级框。既是块级框也是块容器的框称为  &lt;strong&gt;块框（block box）&lt;/strong&gt;。&lt;/p&gt;
 &lt;p&gt;“块级框”、“块容器框”和“块框”这三个术语有时被简称为  &lt;strong&gt;块（block）&lt;/strong&gt;。&lt;/p&gt;
 &lt;h3&gt;9.2.3 Run-in boxes（插入型框）&lt;/h3&gt;
 &lt;p&gt;CSS Level 3的  &lt;a href="http://www.w3.org/TR/css3-box/#run-in-boxes" target="_blank"&gt;CSS basic box model&lt;/a&gt;中定义。&lt;/p&gt;
 &lt;p&gt;run-in框的行为如下：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;如果run-in框包含一个块框，那么run-in框变为块框。&lt;/li&gt;
  &lt;li&gt;如果run-in框的后继兄弟元素为块框（非浮动，非绝对定位），那么run-in框变为该块框的第一个行内框。run-in不能插入本身为run-in的块中，也不能插入块中已有run-in的块中。&lt;/li&gt;
  &lt;li&gt;否则，run-in框变为块框。&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;浏览器支持：IE8+，chrome（不支持，难道是太鸡肋？）&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://topcss.org/demo/run-in-box.html" target="_blank"&gt;DEMO(IE下查看)&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="run-in-box" height="107" src="http://www.topcss.org/wp-content/uploads/2015/04/run-in-box.png" width="469"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h3&gt;9.3.2 Box offsets: ‘top’, ‘right’, ‘bottom’, ‘left’&lt;/h3&gt;
 &lt;ul&gt;
  &lt;li&gt;（绝对、固定）定位元素会生成一个定位框（positioned box），根据top，right，bottom，left布局。&lt;/li&gt;
  &lt;li&gt;初始值为   &lt;strong&gt;auto&lt;/strong&gt;，非0。（文章开头的问题中未设置四值，等同设置为auto   &lt;strong&gt;√&lt;/strong&gt;）&lt;/li&gt;
  &lt;li&gt;对于绝对定位元素，四值指定的是元素margin边与包含块的边之间的偏移量。对于相对定位元素，四值指定的是相对于自身框边的偏移量。&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;9.6 Absolute positioning&lt;/h2&gt;
 &lt;ul&gt;
  &lt;li&gt;从常规流中完全抽离，对其后继兄弟元素无影响。&lt;/li&gt;
  &lt;li&gt;固定定位是绝对定位的特例，它的包含块是viewport。&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;9.7 Relationships between ‘display’, ‘position’, and ‘float’&lt;/h2&gt;
 &lt;p&gt;这三个属性影响了框的生成和布局，相互影响如下：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;如果’display’值为’none’，同时不设置’position’和’float’，那么该元素不生成框。&lt;/li&gt;
  &lt;li&gt;否则，如果’positon’值为’absolute’或’fixed’，即框为绝对定位，’float’的计算值为’none’，并且’display’根据下表设置。那么该框的位置由’top’,’right’,’bottom’,’left’和框的包含块决定。&lt;/li&gt;
  &lt;li&gt;否则，如果’float’的值不为’none’，那么该框会浮动，’display’根据下表设置。&lt;/li&gt;
  &lt;li&gt;否则，如果该元素为根元素，’display’根据下表设置。&lt;/li&gt;
  &lt;li&gt;否则，剩余的’display’属性值与指定值相同。&lt;/li&gt;
&lt;/ol&gt;
 &lt;table border="1"&gt;

  &lt;tr&gt;
   &lt;th&gt;指定值&lt;/th&gt;
   &lt;th&gt;计算值&lt;/th&gt;
&lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;inline-table&lt;/td&gt;
   &lt;td&gt;table&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;inline, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block&lt;/td&gt;
   &lt;td&gt;block&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;others&lt;/td&gt;
   &lt;td&gt;same as specified&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;
 &lt;h2&gt;10.6 Calculating heights and margins（高度和margin值计算）&lt;/h2&gt;
 &lt;h3&gt;10.6.4 Absolutely positioned, non-replaced elements（绝对定位的非替换元素）&lt;/h3&gt;
 &lt;p&gt;  &lt;strong&gt;静态位置&lt;/strong&gt;（static position），粗略地讲是指一个元素在常规流中的位置。精确地讲，一个元素的静态top值，是指包含块顶部边沿与该元素的假想框的顶部margin边沿之间的距离。  &lt;strong&gt;假想框&lt;/strong&gt;是指如果该元素的’position’值为’static’，以及’float’值为’non’且’clear’值为’none’时，该元素的第一个框。&lt;/p&gt;
 &lt;p&gt;对于绝对定位的元素，垂直尺寸的使用值必须满足下面约束：&lt;/p&gt;
 &lt;blockquote&gt;
  &lt;p&gt;‘top’ + ‘margin-top’ + ‘border-top-width’ + ‘padding-top’ + ‘height’ + ‘padding-bottom’ + ‘border-bottom-width’ + ‘margin-bottom’ + ‘bottom’ = height of containing block&lt;/p&gt;
&lt;/blockquote&gt;
 &lt;p&gt;如果’top’，’bottom’，’height’值均为auto，那么’top’值为元素的静态位置。（这也就回答了文章开头的问题  &lt;strong&gt;√&lt;/strong&gt;）&lt;/p&gt;
 &lt;p&gt;如果三个值均不为auto，那么：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;如果’margin-top’和’margin-bottom’值均为’auto’，那么假定margin-top和margin-bottom两值相等，然后再解上面方程式。（可以利用这点实现垂直居中的效果，   &lt;a href="http://topcss.org/demo/css-blur.html" target="_blank"&gt;查看DEMO&lt;/a&gt;    &lt;strong&gt;√&lt;/strong&gt;）&lt;/li&gt;
  &lt;li&gt;如果’margin-top’和’margin-bottom’值中其一为’auto’，解上面方程式获取该margin值。&lt;/li&gt;
  &lt;li&gt;如果数值超过限制，忽略’bottom’值，解方程式获取该值。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;否则，从以下六种规则中挑选适用情况：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt; ‘top’和’height’为’auto’，’bottom’不为’auto’，那么’height’基于其内容根据   &lt;a href="http://www.w3.org/TR/2011/REC-CSS2-20110607/visudet.html#root-height" target="_blank"&gt;10.6.7规则&lt;/a&gt;计算，’margin-top’值设为’auto’，’margin-bottom’值设为0，解方程式得’top’值。&lt;/li&gt;
  &lt;li&gt; ‘top’和’bottom’为’auto’，’height’不为’auto’，那么设置’top’值为其静态位置，’margin-top’值设为’auto’，’margin-bottom’值设为0，解方程式得’bottom’值。&lt;/li&gt;
  &lt;li&gt; ‘bottom’和’height’为’auto’，’top’不为’auto’，那么’height’基于其内容根据   &lt;a href="http://www.w3.org/TR/2011/REC-CSS2-20110607/visudet.html#root-height" target="_blank"&gt;10.6.7规则&lt;/a&gt;计算，’margin-top’值设为’auto’，’margin-bottom’值设为0，解方程式得’bottom’值。&lt;/li&gt;
  &lt;li&gt; ‘top’值为’auto’，’bottom’和’height’不为’auto’，那么’margin-top’值设为’auto’，’margin-bottom’值设为0，解方程式得’top’值。&lt;/li&gt;
  &lt;li&gt; ‘height’值为’auto’，’bottom’和’top’不为’auto’，那么’margin-top’值设为’auto’，’margin-bottom’值设为0，解方程式得’height’值。&lt;/li&gt;
  &lt;li&gt; ‘bottom’值为’auto’，’height’和’top’不为’auto’，那么’margin-top’值设为’auto’，’margin-bottom’值设为0，解方程式得’bottom’值。&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>css run-in box Visual formatting model 包含块 可视化格式模型</category>
      <guid isPermaLink="true">https://itindex.net/detail/53268-%E5%8F%AF%E8%A7%86%E5%8C%96-%E6%A0%BC%E5%BC%8F-%E6%A8%A1%E5%9E%8B</guid>
      <pubDate>Thu, 16 Apr 2015 11:41:33 CST</pubDate>
    </item>
    <item>
      <title>JS 和 CSS 的位置对其他资源加载顺序的影响</title>
      <link>https://itindex.net/detail/52335-js-css-%E4%BD%8D%E7%BD%AE</link>
      <description>&lt;p&gt;克军做了一系列测试：  &lt;a href="http://hikejun.com/blog/2012/02/02/js%E5%92%8Ccss%E7%9A%84%E9%A1%BA%E5%BA%8F%E5%85%B3%E7%B3%BB/" rel="nofollow"&gt;js和css的顺序关系&lt;/a&gt;，给出了现象和结论，但未给出原因。&lt;/p&gt;

 &lt;p&gt;JS 和 CSS 在页面中的位置，会影响其他资源（指 img 等非 js 和 css 资源）的加载顺序，究其原因，有三个值得注意的点：&lt;/p&gt;

 &lt;ol&gt;
  &lt;li&gt;
   &lt;strong&gt;JS 有可能会修改 DOM.&lt;/strong&gt;典型的，可能会有    &lt;code&gt;document.write&lt;/code&gt;. 这意味着，在当前 JS 加载和执行完成前，后续所有资源的下载有可能是没必要的。这是 JS 阻塞后续资源下载的根本原因。&lt;/li&gt;
  &lt;li&gt;
   &lt;strong&gt;JS 的执行有可能依赖最新样式。&lt;/strong&gt;比如，可能会有    &lt;code&gt;var width = $(&amp;apos;#id&amp;apos;).width()&lt;/code&gt;. 这意味着，JS 代码在执行前，浏览器必须保证在此 JS 之前的所有 css（无论外链还是内嵌）都已下载和解析完成。这是 CSS 阻塞后续 JS 执行的根本原因。&lt;/li&gt;
  &lt;li&gt;
   &lt;strong&gt;现代浏览器很聪明，会进行 prefetch 优化。&lt;/strong&gt;性能是如此重要，现代浏览器在竞争中，在 UI update 线程之外，还会开启另一个线程，对后续 JS 和 CSS 提前下载（注意，仅提前下载，并不执行）。有了 prefetch 优化，这意味着，在不存在任何阻塞的情况下，理论上 JS 和 CSS 的下载时机都非常优先，和位置无关。&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;以上三点可简述为三条基本定律：&lt;/p&gt;

 &lt;ul&gt;
  &lt;li&gt;   &lt;strong&gt;定律一：资源是否下载依赖 JS 执行结果。&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;strong&gt;定律二：JS 执行依赖 CSS 最新渲染。&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;strong&gt;定律三：现代浏览器存在 prefetch 优化。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;有了这三条定律，再来看克军的测试，就很清晰了：&lt;/p&gt;

 &lt;blockquote&gt;
    &lt;p&gt;a,b – head里出现外联js，无论如何放，css文件都不能和body里的请求并行&lt;/p&gt;
&lt;/blockquote&gt;

 &lt;p&gt;根据定律一和定律三，可以知道上面的结论不够正确。比如：&lt;/p&gt;

 &lt;pre&gt;  &lt;code&gt;&amp;lt;head&amp;gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;mock.php?css1&amp;amp;sleep=2&amp;quot;&amp;gt;
&amp;lt;script src=&amp;quot;mock.php?js&amp;amp;sleep=3&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;mock.php?css2&amp;amp;sleep=4&amp;quot;&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;mock.php?css3&amp;amp;sleep=5&amp;quot;&amp;gt;
&amp;lt;img src=&amp;quot;test.gif&amp;quot;&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

 &lt;p&gt;在 Chrome 下的瀑布图是：&lt;/p&gt;

 &lt;p&gt;  &lt;img alt="" src="http://lifesinger.files.wordpress.com/2012/02/screen-shot-2012-02-03-at-11-01-20-am.png?w=700"&gt;&lt;/img&gt;&lt;/p&gt;

 &lt;p&gt;黄色条是 js 的，可以看出 img 的延时下载是由定律一决定的。&lt;/p&gt;

 &lt;p&gt;定律三则决定了所有 js/css 都是并行开始下载的。在 Firefox 10 下，prefetch 非常强悍，对 img 也会预加载，瀑布图如下：&lt;/p&gt;

 &lt;p&gt;  &lt;img alt="" src="http://lifesinger.files.wordpress.com/2012/02/screen-shot-2012-02-03-at-11-08-14-am.png?w=700"&gt;&lt;/img&gt;&lt;/p&gt;

 &lt;p&gt;调整一下 sleep 时间，还可以观察到定律二的威力：&lt;/p&gt;

 &lt;pre&gt;  &lt;code&gt;&amp;lt;head&amp;gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;mock.php?css1&amp;amp;sleep=3&amp;quot;&amp;gt; &amp;lt;!-- 修改 sleep 值，使其大于 js 的 --&amp;gt;
&amp;lt;script src=&amp;quot;mock.php?js&amp;amp;sleep=2&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;mock.php?css2&amp;amp;sleep=4&amp;quot;&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;mock.php?css3&amp;amp;sleep=5&amp;quot;&amp;gt;
&amp;lt;img src=&amp;quot;test.gif&amp;quot;&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

 &lt;p&gt;瀑布图立刻发生了变化：&lt;/p&gt;

 &lt;p&gt;  &lt;img alt="" src="http://lifesinger.files.wordpress.com/2012/02/screen-shot-2012-02-03-at-11-14-28-am.png?w=700"&gt;&lt;/img&gt;&lt;/p&gt;

 &lt;p&gt;因为定律一，决定 img 的下载在 js 执行后。又因为定律二，决定 js 的执行在第一个 css 后。于是最后在瀑布图上体现出来，就是 img 的下载在第一个 css 后。&lt;/p&gt;

 &lt;p&gt;再来看克军的第二个结论：&lt;/p&gt;

 &lt;blockquote&gt;
    &lt;p&gt;c – head里的内联js只要在所有外联css前面，css文件可以和body里的请求并行（图2）&lt;/p&gt;
  
    &lt;p&gt;d – head里的内联js只要在任一外联css后面，css文件就不能和body里的请求并行（图1）&lt;/p&gt;
&lt;/blockquote&gt;

 &lt;p&gt;这个是定律二的威力。结论 c 是正确的，因为没有 css 会影响 js 的执行。结论 d 则不够正确。img 等其他资源，会在 js 前面的 css 下载完成后，以及 js 执行后，立刻开始下载。与头部中，js 位置之后的 css 没关系。&lt;/p&gt;

 &lt;p&gt;克军的其他结论都是对的，不多说。&lt;/p&gt;

 &lt;p&gt;注意1：Firefox 10 的 prefetch 有点奇怪，有时会对 img 进行 prefetch，有时则不会。有兴趣的可以进一步寻找规律。&lt;/p&gt;

 &lt;p&gt;注意2：上面的三个定律，是黑盒猜测，有兴趣的可以去阅读浏览器的源码，应该能找到更深层次的原因。&lt;/p&gt;

 &lt;p&gt;注意3：本文没有考虑 defer, async 属性的影响，这是另一个故事。&lt;/p&gt;

 &lt;p&gt;浏览器在迅速发展，很多总结，特别是书籍上的，很难与时俱进。大家应该像克军学习，多测试，多发现，这样得来的知识，才不会过时。这篇博客的总结，也肯定在未来甚至就在现在，已经存在错误。这些都无所谓，关键是  &lt;strong&gt;要懂得测试的方法和分析的思路，有了“渔”，才能更好地探求和拥有“鱼”&lt;/strong&gt;。&lt;/p&gt;

 &lt;p&gt;转自   &lt;a href="http://lifesinger.wordpress.com/2012/02/03/performance-impact-of-js-css-loading-order/" rel="nofollow"&gt;岁月如歌&lt;/a&gt;&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>javascript css 响应速度 效率</category>
      <guid isPermaLink="true">https://itindex.net/detail/52335-js-css-%E4%BD%8D%E7%BD%AE</guid>
      <pubDate>Mon, 29 Dec 2014 10:24:05 CST</pubDate>
    </item>
    <item>
      <title>来，让我们谈一谈Normalize.css</title>
      <link>https://itindex.net/detail/51833-normalize-css</link>
      <description>&lt;blockquote&gt;
    &lt;p&gt;本文译自    &lt;a href="http://nicolasgallagher.com/about-normalize-css/" rel="nofollow"&gt;http://nicolasgallagher.com/about-normalize-css/&lt;/a&gt;   &lt;br /&gt;
  最初发布于我的博客：   &lt;a href="http://jerryzou.com/posts/aboutNormalizeCss/" rel="nofollow"&gt;http://jerryzou.com/posts/aboutNormalizeCss/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

 &lt;p&gt;  &lt;a href="http://necolas.github.io/normalize.css/" rel="nofollow"&gt;Normalize.css&lt;/a&gt; 只是一个很小的CSS文件，但它在默认的HTML元素样式上提供了跨浏览器的高度一致性。相比于传统的  &lt;code&gt;CSS reset&lt;/code&gt;，  &lt;code&gt;Normalize.css&lt;/code&gt;是一种现代的、为HTML5准备的优质替代方案。  &lt;code&gt;Normalize.css&lt;/code&gt;现在已经被用于  &lt;a href="http://getbootstrap.com/" rel="nofollow"&gt;Twitter Bootstrap&lt;/a&gt;、  &lt;a href="http://html5boilerplate.com/" rel="nofollow"&gt;HTML5 Boilerplate&lt;/a&gt;、  &lt;a href="http://www.gov.uk/" rel="nofollow"&gt;GOV.UK&lt;/a&gt;、  &lt;a href="http://www.rdio.com/" rel="nofollow"&gt;Rdio&lt;/a&gt;、  &lt;a href="http://css-tricks.com/" rel="nofollow"&gt;CSS Tricks&lt;/a&gt; 以及许许多多其他框架、工具和网站上。&lt;/p&gt;

 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="http://necolas.github.io/normalize.css/" rel="nofollow"&gt;Normalize.css 项目地址&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://github.com/necolas/normalize.css" rel="nofollow"&gt;Normalize.css 在GitHub上的源码&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;h1&gt;综述&lt;/h1&gt;

 &lt;p&gt;  &lt;code&gt;Normalize.css&lt;/code&gt;是一种  &lt;code&gt;CSS reset&lt;/code&gt;的替代方案。经过  &lt;a href="https://twitter.com/necolas" rel="nofollow"&gt;@necolas&lt;/a&gt;和  &lt;a href="https://twitter.com/jon_neal" rel="nofollow"&gt;@jon_neal&lt;/a&gt;花了几百个小时来努力研究不同浏览器的默认样式的差异，这个项目终于变成了现在这样。&lt;/p&gt;

 &lt;p&gt;我们创造  &lt;code&gt;normalize.css&lt;/code&gt;有下面这几个目的：&lt;/p&gt;

 &lt;ul&gt;
  &lt;li&gt;
   &lt;strong&gt;保护有用的浏览器默认样式&lt;/strong&gt;而不是完全去掉它们&lt;/li&gt;
  &lt;li&gt;
   &lt;strong&gt;一般化的样式&lt;/strong&gt;：为大部分HTML元素提供&lt;/li&gt;
  &lt;li&gt;
   &lt;strong&gt;修复浏览器自身的bug&lt;/strong&gt;并保证各浏览器的一致性&lt;/li&gt;
  &lt;li&gt;
   &lt;strong&gt;优化CSS可用性&lt;/strong&gt;：用一些小技巧&lt;/li&gt;
  &lt;li&gt;
   &lt;strong&gt;解释代码&lt;/strong&gt;：用注释和详细的文档来&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;  &lt;code&gt;Normalize.css&lt;/code&gt;支持包括手机浏览器在内的超多浏览器，同时对HTML5元素、排版、列表、嵌入的内容、表单和表格都进行了一般化。尽管这个项目基于一般化的原则，但我们还是在合适的地方使用了更实用的默认值。&lt;/p&gt;

 &lt;h1&gt;Normalize vs Reset&lt;/h1&gt;

 &lt;p&gt;知道  &lt;code&gt;Normalize.css&lt;/code&gt;和传统  &lt;code&gt;Reset&lt;/code&gt;的区别是非常有价值的。&lt;/p&gt;

 &lt;h3&gt;1. Normalize.css 保护了有价值的默认值&lt;/h3&gt;

 &lt;p&gt;  &lt;code&gt;Reset&lt;/code&gt;通过为几乎所有的元素施加默认样式，强行使得元素有相同的视觉效果。相比之下，  &lt;code&gt;Normalize.css&lt;/code&gt;保持了许多默认的浏览器样式。这就意味着你不用再为所有公共的排版元素重新设置样式。当一个元素在不同的浏览器中有不同的默认值时，  &lt;code&gt;Normalize.css&lt;/code&gt;会力求让这些样式保持一致并尽可能与现代标准相符合。&lt;/p&gt;

 &lt;h3&gt;2. Normalize.css 修复了浏览器的bug&lt;/h3&gt;

 &lt;p&gt;它修复了常见的桌面端和移动端浏览器的bug。这往往超出了  &lt;code&gt;Reset&lt;/code&gt;所能做到的范畴。关于这一点，  &lt;code&gt;Normalize.css&lt;/code&gt;修复的问题包含了HTML5元素的显示设置、预格式化文字的  &lt;code&gt;font-size&lt;/code&gt;问题、在IE9中SVG的溢出、许多出现在各浏览器和操作系统中的与表单相关的bug。&lt;/p&gt;

 &lt;p&gt;可以看以下这个例子，看看对于HTML5中新出现的  &lt;code&gt;input&lt;/code&gt;类型  &lt;code&gt;search&lt;/code&gt;，  &lt;code&gt;Normalize.css&lt;/code&gt;是如何保证跨浏览器的一致性的。&lt;/p&gt;

 &lt;pre&gt;  &lt;code&gt;/**
 * 1. Addresses appearance set to searchfield in S5, Chrome
 * 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof)
 */

input[type=&amp;quot;search&amp;quot;] {
  -webkit-appearance: textfield; /* 1 */
  -moz-box-sizing: content-box;
  -webkit-box-sizing: content-box; /* 2 */
  box-sizing: content-box;
}

/**
 * Removes inner padding and search cancel button in S5, Chrome on OS X
 */

input[type=&amp;quot;search&amp;quot;]::-webkit-search-decoration,
input[type=&amp;quot;search&amp;quot;]::-webkit-search-cancel-button {
  -webkit-appearance: none;
}
&lt;/code&gt;&lt;/pre&gt;

 &lt;h3&gt;3. Normalize.css 不会让你的调试工具变的杂乱&lt;/h3&gt;

 &lt;p&gt;使用Reset最让人困扰的地方莫过于在浏览器调试工具中大段大段的继承链，如下图所示。在  &lt;code&gt;Normalize.css&lt;/code&gt;中就不会有这样的问题，因为在我们的准则中对多选择器的使用时非常谨慎的，我们仅会有目的地对目标元素设置样式。&lt;/p&gt;

 &lt;p&gt;  &lt;img alt="css-reset-bug" src="http://segmentfault.com/img/bVjyNb"&gt;&lt;/img&gt;&lt;/p&gt;

 &lt;h3&gt;4. Normalize.css 是模块化的&lt;/h3&gt;

 &lt;p&gt;这个项目已经被拆分为多个相关却又独立的部分，这使得你能够很容易也很清楚地知道哪些元素被设置了特定的值。因此这能让你自己选择性地移除掉某些永远不会用到部分（比如表单的一般化）。&lt;/p&gt;

 &lt;h3&gt;5. Normalize.css 拥有详细的文档&lt;/h3&gt;

 &lt;p&gt;Normalize.css的代码基于详细而全面的跨浏览器研究与测试。这个文件中拥有详细的代码说明并在  &lt;a href="https://github.com/necolas/normalize.css/wiki" rel="nofollow"&gt;Github Wiki&lt;/a&gt;中有进一步的说明。这意味着你可以找到每一行代码具体完成了什么工作、为什么要写这句代码、浏览器之间的差异，并且你可以更容易地进行自己的测试。&lt;/p&gt;

 &lt;p&gt;这个项目的目标是帮助人们了解浏览器默认是如何渲染元素的，同时也让人们很容易地明白如何改进浏览器渲染。&lt;/p&gt;

 &lt;h1&gt;如何使用 normalize.css&lt;/h1&gt;

 &lt;p&gt;首先，安装或从Github  &lt;a href="http://necolas.github.com/normalize.css/" rel="nofollow"&gt;下载Normalize.css&lt;/a&gt;，接下来有两种主要途径去使用它。&lt;/p&gt;

 &lt;ul&gt;
  &lt;li&gt;策略一：将   &lt;code&gt;normalize.css&lt;/code&gt;作为你自己项目的基础CSS，自定义样式值以满足设计师的需求。&lt;/li&gt;
  &lt;li&gt;策略二：引入   &lt;code&gt;normalize.css&lt;/code&gt;源码并在此基础上构建，在必要的时候用你自己写的CSS覆盖默认值。&lt;/li&gt;
&lt;/ul&gt;
 &lt;h1&gt;结语&lt;/h1&gt;

 &lt;p&gt;无论从适用范畴还是实施上，  &lt;code&gt;Normalize.css&lt;/code&gt;与  &lt;code&gt;Reset&lt;/code&gt;都有极大的不同。尝试一下这两种方法并看看到底哪种更适合你的开发偏好是非常值得的。这个项目在Github上以开源的形式开发。任何人都能够提交问题报告或者提交补丁。整个项目发展的过程对所有人都是可见的，而每一次改动的原因也都写在commit信息中，这些都是有迹可循的。&lt;/p&gt;

 &lt;h1&gt;相关阅读&lt;/h1&gt;

 &lt;p&gt;关于更多默认UA样式的详细信息：&lt;/p&gt;

 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/rendering.html#the-css-user-agent-style-sheet-and-presentational-hints" rel="nofollow"&gt;WHATWG suggestions for rendering HTML documents&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://iecss.com/" rel="nofollow"&gt;Internet Explorer User Agent Style Sheets&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://css-class.com/test/css/defaults/UA-style-sheet-defaults.htm" rel="nofollow"&gt;CSS2.1 User Agent Style Sheet Defaults&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>css Normalize.css</category>
      <guid isPermaLink="true">https://itindex.net/detail/51833-normalize-css</guid>
      <pubDate>Thu, 20 Nov 2014 20:57:35 CST</pubDate>
    </item>
    <item>
      <title>未来必热：SVG Sprite技术介绍</title>
      <link>https://itindex.net/detail/50332-%E6%9C%AA%E6%9D%A5-svg-sprite</link>
      <description>&lt;p&gt;by   &lt;a href="http://www.zhangxinxu.com/"&gt;zhangxinxu&lt;/a&gt; from   &lt;a href="http://www.zhangxinxu.com/"&gt;http://www.zhangxinxu.com&lt;/a&gt;  &lt;br /&gt;
本文地址：  &lt;a href="http://www.zhangxinxu.com/wordpress/?p=4264"&gt;http://www.zhangxinxu.com/wordpress/?p=4264&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;一、Sprite技术&lt;/h3&gt;
 &lt;p&gt;这里所说的Sprite技术，没错，类似于CSS中的Sprite技术。图标图形整合在一起，实际呈现的时候准确显示特定图标。&lt;/p&gt;
 &lt;p&gt;另，本文图片甚多，爪机党继续浏览需慎重。&lt;/p&gt;
 &lt;h3&gt;二、SVG Sprite与symbol元素&lt;/h3&gt;
 &lt;p&gt;目前，SVG Sprite最佳实践是使用  &lt;code&gt;symbol&lt;/code&gt;元素。  &lt;code&gt;symbol&lt;/code&gt;元素是什么呢？单纯翻译的话，是“符号”的意思。然，这个释义并不符合这里的场景。不知大家有没有用过Flash，  &lt;code&gt;symbol&lt;/code&gt;实际上就类似于Flash中的“影片剪辑”、或者“元件”。&lt;/p&gt;
 &lt;p&gt;因此，我个人觉得，  &lt;code&gt;symbol&lt;/code&gt;应该解释为“元件”最为恰当！&lt;/p&gt;
 &lt;p&gt;那，  &lt;code&gt;symbol&lt;/code&gt;和SVG Sprite又有什么关系呢？&lt;/p&gt;
 &lt;p&gt;我们可以把SVG元素看成一个舞台，而  &lt;code&gt;symbol&lt;/code&gt;则是舞台上一个一个组装好的元件，这这些一个一个的元件就是我们即将使用的一个一个SVG图标。&lt;/p&gt;
 &lt;p&gt;于是，对于一个集合了三个SVG图标的SVG元素的代码结构会是这样：&lt;/p&gt;
 &lt;div&gt;
  &lt;pre&gt;
&amp;lt;svg&amp;gt;
    &amp;lt;symbol&amp;gt;
        &amp;lt;!-- 第1个图标路径形状之类代码 --&amp;gt;
    &amp;lt;/symbol&amp;gt;
    &amp;lt;symbol&amp;gt;
        &amp;lt;!-- 第2个图标路径形状之类代码 --&amp;gt;
    &amp;lt;/symbol&amp;gt;
    &amp;lt;symbol&amp;gt;
        &amp;lt;!-- 第3个图标路径形状之类代码 --&amp;gt;
    &amp;lt;/symbol&amp;gt;
&amp;lt;/svg&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;
 &lt;p&gt;每一个  &lt;code&gt;symbol&lt;/code&gt;就是一个图标元件，但是，只有上面的代码，是无法呈现类似下面的效果的：  &lt;br /&gt;
  &lt;img alt="SVG Sprite&amp;#30340;&amp;#25928;&amp;#26524;&amp;#22270;" height="162" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_103255.png" width="489"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;为何？&lt;/p&gt;
 &lt;p&gt;因为，舞台上只是放置了图标，如果你不使用(use)，是看不见的。就好比你女朋友买了几箱的衣服放家里，如果不穿出去，谁知道她这么土豪呢？&lt;/p&gt;
 &lt;p&gt;因此，还差一个“使用”，也就是SVG中的  &lt;code&gt;&amp;lt;use&amp;gt;&lt;/code&gt;元素。&lt;/p&gt;
 &lt;h3&gt;三、SVG中的use元素&lt;/h3&gt;
 &lt;p&gt;  &lt;a href="http://tutorials.jenkov.com/svg/use-element.html"&gt;use元素&lt;/a&gt;是SVG中非常强大，非常重要的一个元素，尤其在Web开发中，为何？&lt;/p&gt;
 &lt;p&gt;两点：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;可重复调用；&lt;/li&gt;
  &lt;li&gt;跨SVG调用；&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;  &lt;strong&gt;1. 可重复调用&lt;/strong&gt;  &lt;br /&gt;
你好不容易，用了几十个坐标值，好不容易绘制了一个图形，如果你想再弄一个同样造型，但位置不同的图形出来，你会怎么办？——再复制一遍代码？别说笑了，（如果真那样）SVG文件的尺寸赶得上二师兄的腰围了。&lt;/p&gt;
 &lt;p&gt;使用  &lt;code&gt;&amp;lt;use&amp;gt;&lt;/code&gt;元素就可以，看下面的板栗：&lt;/p&gt;
 &lt;div&gt;
  &lt;pre&gt;&amp;lt;svg&amp;gt;
  &amp;lt;defs&amp;gt;
    &amp;lt;g id=&amp;quot;shape&amp;quot;&amp;gt;
        &amp;lt;rect x=&amp;quot;0&amp;quot; y=&amp;quot;0&amp;quot; width=&amp;quot;50&amp;quot; height=&amp;quot;50&amp;quot; /&amp;gt;
        &amp;lt;circle cx=&amp;quot;0&amp;quot; cy=&amp;quot;0&amp;quot; r=&amp;quot;50&amp;quot; /&amp;gt;
    &amp;lt;/g&amp;gt;
  &amp;lt;/defs&amp;gt;

  &amp;lt;use xlink:href=&amp;quot;#shape&amp;quot; x=&amp;quot;50&amp;quot; y=&amp;quot;50&amp;quot; /&amp;gt;
  &amp;lt;use xlink:href=&amp;quot;#shape&amp;quot; x=&amp;quot;200&amp;quot; y=&amp;quot;50&amp;quot; /&amp;gt;
&amp;lt;/svg&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
 &lt;p&gt;结果是（IE9+浏览器可见）：  &lt;br /&gt;
          &lt;/p&gt;
 &lt;p&gt;首先，注意到没有，  &lt;code&gt;use&lt;/code&gt;元素是通过  &lt;code&gt;xlink:href&lt;/code&gt;属性，寻找要使用的元素的。  &lt;code&gt;#shape&lt;/code&gt;对应的就是  &lt;code&gt;id&lt;/code&gt;为  &lt;code&gt;shape&lt;/code&gt;的元素。  &lt;code&gt;use&lt;/code&gt;元素可以有自己的坐标，以及支持  &lt;code&gt;transform&lt;/code&gt;变换，甚至可以use其他  &lt;code&gt;use&lt;/code&gt;元素。&lt;/p&gt;
 &lt;p&gt;这里，两个  &lt;code&gt;use&lt;/code&gt;元素使用的是同一个  &lt;code&gt;g&lt;/code&gt;元素（组合），从而实现了图形的重复调用功能。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;2. 跨SVG调用&lt;/strong&gt;  &lt;br /&gt;
SVG中的  &lt;code&gt;use&lt;/code&gt;元素可以调用其他SVG文件的元素，只要在一个文档中。&lt;/p&gt;
 &lt;p&gt;紧接着上面的板栗：&lt;/p&gt;
 &lt;div&gt;
  &lt;pre&gt;&amp;lt;svg width=&amp;quot;500&amp;quot; height=&amp;quot;110&amp;quot;&amp;gt;&amp;lt;use xlink:href=&amp;quot;#shape&amp;quot; x=&amp;quot;50&amp;quot; y=&amp;quot;50&amp;quot; /&amp;gt;&amp;lt;/svg&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
 &lt;p&gt;结果仍是那个图形：  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;而这个  &lt;strong&gt;跨SVG调用&lt;/strong&gt;就是“SVG Sprite技术”的核心所在。&lt;/p&gt;
 &lt;p&gt;试想下，我们只要在页面某处载入一个充满Sprite(  &lt;code&gt;symbol&lt;/code&gt;)的SVG文件（或直接  &lt;code&gt;include&lt;/code&gt; SVG代码），于是，在页面的任何角落，只要想使用这个图标，只要简单这一点代码就可以了：&lt;/p&gt;
 &lt;div&gt;
  &lt;pre&gt;&amp;lt;svg class=&amp;quot;size&amp;quot;&amp;gt;&amp;lt;use xlink:href=&amp;quot;#target&amp;quot; /&amp;gt;&amp;lt;/svg&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
 &lt;p&gt;图标尺寸CSS控制，里面只有一个仅有  &lt;code&gt;xlink:href&lt;/code&gt;属性的  &lt;code&gt;use&lt;/code&gt;元素，Done! 完成！&lt;/p&gt;
 &lt;p&gt;也即是说，在HTML层面，图标使用的代码成本，跟传统的CSS Sprite或者流行的  &lt;code&gt;font-face&lt;/code&gt;几乎无异，代码简洁，而且很好维护。所有的SVG图标都在一个SVG源上。retina良好，尺寸可任意拉伸，且颜色可控，真乃Web图标的未来之星。&lt;/p&gt;
 &lt;p&gt;吹的嘴巴都干了，上个简单的demo给大家瞅瞅, 我先去给水排水~~&lt;/p&gt;
 &lt;p&gt;您可以狠狠地点击这里：  &lt;a href="http://www.zhangxinxu.com/study/201407/svg-sprite.php" target="_blank"&gt;SVG Sprite使用示意demo&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;代码如下截图：  &lt;br /&gt;
  &lt;img alt="SVG Sprite&amp;#20351;&amp;#29992;&amp;#31034;&amp;#24847;" height="376" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_114146.png" width="689"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;效果为：  &lt;br /&gt;
  &lt;img alt="SVG&amp;#20351;&amp;#29992;&amp;#30340;&amp;#22270;&amp;#26631;&amp;#25928;&amp;#26524;" height="208" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_142916.png" width="327"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;总结下就是：  &lt;strong&gt;symbol + use =&amp;gt; SVG Sprite&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;诸位会不会觉得本文的内容快要结束了呢？  &lt;img align="absmiddle" src="http://mat1.gtimg.com/www/mb/images/face/108.gif"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;嘻嘻嘻嘻，顶多才  &lt;strong&gt;1/3&lt;/strong&gt;，下面的才是重点，打起精神，走起~~&lt;/p&gt;
 &lt;h3&gt;四、SVG Sprite实际应用的阻碍&lt;/h3&gt;
 &lt;p&gt;两大问题：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;SVG图标从何而来？&lt;/li&gt;
  &lt;li&gt;SVG图标如何变成symbol并整合在一起？&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;第  &lt;strong&gt;1&lt;/strong&gt;个问题，  &lt;strong&gt;SVG图标从何而来？&lt;/strong&gt;  &lt;br /&gt;
“远在天边近在眼前”，CSS3   &lt;code&gt;font-face&lt;/code&gt;的逐渐升温，让很多  &lt;code&gt;font-face&lt;/code&gt;工具诞生了。例如以前我介绍过的国外的  &lt;a href="http://icomoon.io" target="_blank"&gt;icomoon.io&lt;/a&gt;，或者国内阿里系的  &lt;a href="http://iconfont.cn/" target="_blank"&gt;iconfont.cn&lt;/a&gt;, 或者bootsrap 3粉们的  &lt;a href="http://www.bootcss.com/p/font-awesome/" target="_blank"&gt;font-awesome&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;这些图标实际上都是使用SVG作为媒介的，所以，根本就不要担心“SVG图标从何而来”，这图标多的就像牛魔王身上的虱子——一抖一大把啊！&lt;/p&gt;
 &lt;p&gt;OK，如何获得呢？直接下载。拿  &lt;a href="http://iconfont.cn/" target="_blank"&gt;iconfont.cn&lt;/a&gt;示意，点击某一图标的下载按钮：  &lt;br /&gt;
  &lt;img alt="&amp;#28857;&amp;#20987;&amp;#19979;&amp;#36733;&amp;#22270;&amp;#26631;" height="206" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_115935.png" width="177"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;点击下载SVG:  &lt;br /&gt;
  &lt;img alt="&amp;#28857;&amp;#20987;&amp;#19979;&amp;#36733;SVG&amp;#25353;&amp;#38062;" height="234" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_115952.png" width="320"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;于是，我们就得到了SVG图标啦！如果你还需要其他图标，也按照这个步骤一个一个下载下来，很简单吧~ 然后把它们放在一个文件夹中，以备后用。&lt;/p&gt;
 &lt;p&gt;下面最关键的是第  &lt;strong&gt;2&lt;/strong&gt;个问题，  &lt;strong&gt;如何合并这些SVG到一个SVG上？&lt;/strong&gt;同时满足使用的是  &lt;code&gt;symbol&lt;/code&gt;标签，并可以使用裸露的  &lt;code&gt;use&lt;/code&gt;元素（除了  &lt;code&gt;xlink:href&lt;/code&gt;没有其他属性）调用呢？&lt;/p&gt;
 &lt;p&gt;很长很funny, 要专门独立两段，  &lt;img align="absmiddle" src="http://mat1.gtimg.com/www/mb/images/face/4.gif"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h3&gt;五、关于合并：偏开发的前端看这里&lt;/h3&gt;
 &lt;p&gt;这里的方法适用于偏开发的前端，一些对指令无感的妹子们，可以看下面偏设计的方法。&lt;/p&gt;
 &lt;p&gt;Github上，有个名为  &lt;code&gt;svgstore&lt;/code&gt;的  &lt;code&gt;grunt&lt;/code&gt;插件，地址  &lt;a href="https://github.com/FWeinb/grunt-svgstore/"&gt;戳这里&lt;/a&gt;。如果您还不了解  &lt;code&gt;grunt&lt;/code&gt;, 可以看看这两篇我觉得不错的文章：“  &lt;a href="http://www.cnblogs.com/snandy/archive/2013/03/07/2946989.html"&gt;使用GruntJS构建Web程序 (1)&lt;/a&gt;”和“  &lt;a href="http://www.cnblogs.com/snandy/archive/2013/03/11/2949177.html"&gt;使用GruntJS构建Web程序 (2)&lt;/a&gt;”.&lt;/p&gt;
 &lt;p&gt;  &lt;code&gt;grunt&lt;/code&gt;改装的装好后，执行下面的指令，&lt;/p&gt;
 &lt;div&gt;
  &lt;pre&gt;npm install grunt-svgstore --save-dev&lt;/pre&gt;
&lt;/div&gt;
 &lt;p&gt;  &lt;img alt="&amp;#23433;&amp;#35013;grunt-svgstore" height="411" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-09_113147.png" width="528"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;烧个香保佑安装成功，然后你就会看到在  &lt;code&gt;node_modules&lt;/code&gt;文件夹中一个名为  &lt;code&gt;grunt-svgstore&lt;/code&gt;的子文件夹（如下）：  &lt;br /&gt;
  &lt;img alt="grunt-svgstore&amp;#25991;&amp;#20214;&amp;#22841;" height="106" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_145657.png" width="329"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;这个名为  &lt;code&gt;grunt-svgstore&lt;/code&gt;的文件夹中有个名为  &lt;code&gt;Gruntfile.js&lt;/code&gt;的文件，据我个人理解，这个JS是所有  &lt;code&gt;grunt&lt;/code&gt;插件要使用的配置文件。&lt;/p&gt;
 &lt;p&gt;我在里面做了一件事情，加了这么一行代码：  &lt;br /&gt;
  &lt;img alt="&amp;#21152;&amp;#20102;&amp;#19968;&amp;#34892;&amp;#20195;&amp;#30721;&amp;#31034;&amp;#24847;" height="104" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_150346.png" width="498"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;为什么要加这么行代码呢？因为  &lt;a href="https://github.com/FWeinb/grunt-svgstore/"&gt;grunt-svgstore&lt;/a&gt;项目README.md让加的，所以我就加了   &lt;img align="absmiddle" src="http://mat1.gtimg.com/www/mb/images/face/98.gif"&gt;&lt;/img&gt;。&lt;/p&gt;
 &lt;p&gt;你会看到&lt;/p&gt;
 &lt;div&gt;
  &lt;pre&gt;svgstore: {

}&lt;/pre&gt;
&lt;/div&gt;
 &lt;p&gt;中有一大堆的配置什么的，这些都是用来独立测试各个API的（  &lt;code&gt;options&lt;/code&gt;对象中各个键就是API名称），让你知道此插件各个API都是干嘛用的，具体释义参见该Github项目。忍不住提一下，如果你希望SVG图标颜色可以在CSS中通过  &lt;code&gt;fill&lt;/code&gt;控制，  &lt;code&gt;cleanup&lt;/code&gt;设置为  &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;
 &lt;p&gt;OK, 准备工作完毕，下面来实践下。我把从iconfont.cn上下载下来的3个SVG都放在了一个名为  &lt;code&gt;mytest&lt;/code&gt;的文件夹下，我希望这个文件夹下的SVG都整合在一起，并可以方便调用，怎么办？&lt;/p&gt;
 &lt;p&gt;在  &lt;code&gt;svgstore: {}&lt;/code&gt;内部搞个自定义的配置，见下图：  &lt;br /&gt;
  &lt;img alt="&amp;#33258;&amp;#23450;&amp;#20041;&amp;#30340;&amp;#37197;&amp;#32622;" height="158" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_152531.png" width="368"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;意思是：  &lt;code&gt;mytest&lt;/code&gt;文件夹下的所有SVG合并成一个名为  &lt;code&gt;mytest.svg&lt;/code&gt;的大SVG文件，并放在  &lt;code&gt;tmp&lt;/code&gt;文件夹下。&lt;/p&gt;
 &lt;p&gt;我们  &lt;code&gt;cd&lt;/code&gt;到  &lt;code&gt;grunt-svgstore&lt;/code&gt;目录，然后在命令行工具中输入：&lt;/p&gt;
 &lt;div&gt;
  &lt;pre&gt;grunt&lt;/pre&gt;
&lt;/div&gt;
 &lt;p&gt;然后走起，再烧第2根香，保佑一切正常……  &lt;br /&gt;
  &lt;img alt="mytest&amp;#36208;&amp;#36215;~" height="188" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_153304.png" width="407"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;然后，就可以在tmp文件夹下看到我们的小结晶——  &lt;code&gt;mytest.svg&lt;/code&gt;，以及如何使用示意的HTML demo页面。  &lt;br /&gt;
  &lt;img alt="SVG&amp;#21512;&amp;#24182;&amp;#30340;&amp;#25991;&amp;#20214;&amp;#65292;&amp;#20197;&amp;#21450;&amp;#23545;&amp;#24212;&amp;#30340;demo~" height="76" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_153059.png" width="347"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;此demo页面源代码如下：&lt;/p&gt;
 &lt;div&gt;
  &lt;pre&gt;&amp;lt;svg xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; style=&amp;quot;width:0;height:0;visibility:hidden;&amp;quot;&amp;gt;&amp;lt;symbol viewBox=&amp;quot;0 0 1024 1024&amp;quot; id=&amp;quot;iconfont-baobei&amp;quot;&amp;gt;&amp;lt;title&amp;gt;iconfont-baobei&amp;lt;/title&amp;gt;&amp;lt;path fill=&amp;quot;#272636&amp;quot; d=&amp;quot;M...z&amp;quot; transform=&amp;quot;translate(0, 800) scale(1, -1)&amp;quot;/&amp;gt;&amp;lt;/symbol&amp;gt;&amp;lt;symbol viewBox=&amp;quot;0 0 1024 1024&amp;quot; id=&amp;quot;iconfont-bianji&amp;quot;&amp;gt;&amp;lt;title&amp;gt;iconfont-bianji&amp;lt;/title&amp;gt;&amp;lt;path fill=&amp;quot;#272636&amp;quot; d=&amp;quot;M...z&amp;quot; transform=&amp;quot;translate(0, 800) scale(1, -1)&amp;quot;/&amp;gt;&amp;lt;/symbol&amp;gt;&amp;lt;symbol viewBox=&amp;quot;0 0 1024 1024&amp;quot; id=&amp;quot;iconfont-shangchuan&amp;quot;&amp;gt;&amp;lt;title&amp;gt;iconfont-shangchuan&amp;lt;/title&amp;gt;&amp;lt;path fill=&amp;quot;#272636&amp;quot; d=&amp;quot;M...z&amp;quot; transform=&amp;quot;translate(0, 800) scale(1, -1)&amp;quot;/&amp;gt;&amp;lt;/symbol&amp;gt;&amp;lt;/svg&amp;gt;

&amp;lt;svg&amp;gt;
    &amp;lt;use xlink:href=&amp;quot;#iconfont-baobei&amp;quot;&amp;gt;&amp;lt;/use&amp;gt;
&amp;lt;/svg&amp;gt;
&amp;lt;svg&amp;gt;
    &amp;lt;use xlink:href=&amp;quot;#iconfont-bianji&amp;quot;&amp;gt;&amp;lt;/use&amp;gt;
&amp;lt;/svg&amp;gt;
&amp;lt;svg&amp;gt;
    &amp;lt;use xlink:href=&amp;quot;#iconfont-shangchuan&amp;quot;&amp;gt;&amp;lt;/use&amp;gt;
&amp;lt;/svg&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
 &lt;p&gt;效果如下截图：  &lt;br /&gt;
  &lt;img alt="&amp;#31532;&amp;#19968;&amp;#27425;&amp;#25104;&amp;#22411;&amp;#30340;SVG&amp;#25928;&amp;#26524;&amp;#22270;" height="116" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_154543.png" width="236"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;Oh, no! 怎么有残缺，不完美，感觉不会再爱了！  &lt;img align="absmiddle" src="http://mat1.gtimg.com/www/mb/images/face/18.gif"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;淡定，小问题，貌似是这些SVG制作的时候，本身有些问题（为了font-face做的调整？），我们在illustrator中打开这些SVG, 一下子就可以看出症结所在，例如，细细的铅笔图标：  &lt;br /&gt;
  &lt;img alt="&amp;#38085;&amp;#31508;&amp;#30340;&amp;#20004;&amp;#20010;&amp;#35282;&amp;#22312;&amp;#33310;&amp;#21488;&amp;#20043;&amp;#22806;&amp;#20102;" height="417" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_103003.png" width="427"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;铅笔的两个角在白色的舞台之外了，正好跟上面截图少掉的两个角一致。要修复，超easy, 等比例缩放到白色舞台内就OK了，ctrl+S保存，然后重新执行下  &lt;code&gt;grunt&lt;/code&gt;命令就好了。&lt;/p&gt;
 &lt;p&gt;然后，浏览器刷新下刚刚的demo页面，当当当当，撒花撒花~~&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="&amp;#28322;&amp;#20986;&amp;#35843;&amp;#25972;&amp;#21518;&amp;#30340;SVG&amp;#25928;&amp;#26524;" height="111" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_160014.png" width="242"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;以上~&lt;/p&gt;
 &lt;h3&gt;六、关于合并：偏设计的前端看这里&lt;/h3&gt;
 &lt;p&gt;注意：  &lt;strong&gt;这里的方法，就算是CSS完全不懂的设计师也可以轻松上手！&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;对于一些妹子，只会写些页面，对于开发、编程的感觉比减肥还难，显然，上面的偏开发需编译的工具插件对她们就很吃力。不急不急，这里有面向设计师的方法。&lt;/p&gt;
 &lt;p&gt;你需要一个犀利的软件，矢量之王，illustrator!&lt;/p&gt;
 &lt;p&gt;一步一步跟我来：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;打开软件，新建一个文件，然后另存为SVG格式；&lt;/li&gt;
  &lt;li&gt;从标尺中拉出一些参考线，搞些正方形格子，我自己用的尺寸是   &lt;code&gt;160*160&lt;/code&gt;, 矢量无尺寸，你随意；&lt;/li&gt;
  &lt;li&gt;把下载的SVG图形拖到这些格子中，缩放到合适大小。我是铺满的，这样由于对比明显，各个图标尺寸就都是一致的，CSS控制方便；   &lt;br /&gt;
   &lt;img alt="illustrator&amp;#21442;&amp;#32771;&amp;#32447;&amp;#19982;&amp;#22270;&amp;#24418;&amp;#32553;&amp;#25918;" height="245" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_161232.png" width="552"&gt;&lt;/img&gt;
&lt;/li&gt;
  &lt;li&gt;这一步很关键。打开Symbols面板，在Window菜单栏中，或Shift+Ctrl+F11启用。然后，拖动格子中的SVG图形到这个面板中，就会触发新建“元件”的行为，会打开类似下面的面板：   &lt;br /&gt;
   &lt;img alt="illustrator&amp;#20013;&amp;#26032;&amp;#24314;&amp;#20803;&amp;#20214;&amp;#30340;&amp;#38754;&amp;#26495;" height="327" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_161756.png" width="296"&gt;&lt;/img&gt;   &lt;p&gt;&lt;/p&gt;
   &lt;p&gt;其中，    &lt;code&gt;name&lt;/code&gt;就是SVG中对应的    &lt;code&gt;symbol&lt;/code&gt;元素的    &lt;code&gt;id&lt;/code&gt;，因此，最好使用英文，最好易识别。下面的    &lt;code&gt;type&lt;/code&gt;你随意，这个只要在SVG导入到Flash中使用时候才有用的，这里，我们不和Flash打交道。然后，OK, 这个图标就“元件”化了，按照同样的步骤，让3个图标都变成元件（以后可重复使用），Symbols面板会类似下面这样：    &lt;br /&gt;
    &lt;img alt="Symbols&amp;#38754;&amp;#26495;&amp;#25130;&amp;#22270;" height="150" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_162242.png" width="261"&gt;&lt;/img&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;Ctrl+S保存，合并好的SVG即出炉。我们直接在浏览器中打开此SVG，效果不错哦~   &lt;br /&gt;
   &lt;img alt="SVG Sprite&amp;#30340;&amp;#25928;&amp;#26524;&amp;#22270;" height="162" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_103255.png" width="489"&gt;&lt;/img&gt;
&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;是不是就这么结束了，太天真了。人生不如意事十之八九。我们瞅一瞅SVG的源代码，会发现，  &lt;code&gt;use&lt;/code&gt;元素居然跟小龙女一样，不干净纯洁啦——上面一大推乱七八糟的属性！  &lt;br /&gt;
  &lt;img alt="use&amp;#20803;&amp;#32032;&amp;#19978;&amp;#22823;&amp;#25226;&amp;#20081;&amp;#19971;&amp;#20843;&amp;#31967;&amp;#23646;&amp;#24615;" height="56" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_162911.png" width="579"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;难道我们要在网页中使用如此臃肿的  &lt;code&gt;use&lt;/code&gt;元素吗？&lt;/p&gt;
 &lt;p&gt;我以小新的明义告诉你，绝对不会！&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="&amp;#23567;&amp;#26032;&amp;#30340;&amp;#21517;&amp;#20041;" height="220" src="http://image.zhangxinxu.com/image/blog/201407/kaokaoni.jpg" width="234"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;因为我昨晚在家折腾出了个工具，可以将illustrator生成SVG转换成web可用SVG Sprite. &lt;/p&gt;
 &lt;p&gt;您可以狠狠地点击这里：  &lt;a href="http://www.zhangxinxu.com/sp/svg.html" target="_blank"&gt;illustrator生成SVG转换成web可用SVG Sprite工具demo&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;上工具完整地址是：http://www.zhangxinxu.com/sp/svg.html  很好记忆，我站点  &lt;code&gt;域名+sp+svg.html&lt;/code&gt;,   &lt;code&gt;sp&lt;/code&gt;是  &lt;code&gt;special&lt;/code&gt;的缩写，专门放工具用的。&lt;/p&gt;
 &lt;p&gt;使用很简单：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;把illustrator生成SVG所有代码拷贝到第一个框框里；&lt;/li&gt;
  &lt;li&gt;点击“转换萌萌哒”按钮，适用于SVG Sprite技术的新代码就出来了（左下的框框）；同时，右侧显示了如何使用该SVG Sprite在web中真实实践；&lt;/li&gt;
  &lt;li&gt;左下角还有个红色的“导出该SVG”，就是字面意思，可以自定义名称，也可使用随机名称，为空即可；&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;一开始的  &lt;a href="http://www.zhangxinxu.com/study/201407/svg-sprite.php" target="_blank"&gt;SVG Sprite使用示意demo&lt;/a&gt;就是使用这个工具生成的哦~ 见下缩略图：  &lt;br /&gt;
  &lt;img alt="illustrator&amp;#29983;&amp;#25104;SVG&amp;#36716;&amp;#25442;&amp;#24037;&amp;#20855;&amp;#20351;&amp;#29992;&amp;#25130;&amp;#22270;" height="449" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_164625.png" width="579"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;注意：&lt;/strong&gt;此工具值适用于illustrator生成的SVG, 水平有限，其他SVG转换十有八九会跛掉。没怎么测试，如果发现此工具转换出了问题，欢迎提醒，定会及时修复。另外，生成的SVG文件会不定期清理，请勿外链。&lt;/p&gt;
 &lt;p&gt;我想想，还有没有什么问题……哦，为什么说此方法与CSS Sprite还要简单。&lt;/p&gt;
 &lt;p&gt;因为，CSS Sprite还需要在CSS中使用  &lt;code&gt;background-position&lt;/code&gt;一个一个地定位，哦，天哪~ 如果没有工具的话，就纯粹搬砖的苦力活啊~&lt;/p&gt;
 &lt;p&gt;但是，这里的SVG Sprite的定位，你只要在illustrator中把位置放好，illustrator这个软件就自动帮你定位好了。你只要在我的工具中转换下，生成下，然后在需要使用的地方使用：&lt;/p&gt;
 &lt;div&gt;
  &lt;pre&gt;&amp;lt;svg&amp;gt;&amp;lt;use xlink:href=&amp;quot;#target&amp;quot; /&amp;gt;&amp;lt;/svg&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
 &lt;p&gt;就好了，用到CSS了吗？几乎没有，除了对SVG做尺寸限制以及改变图标的颜色。OK，这点程度的东西，小白设计师也可以轻松上手。&lt;/p&gt;
 &lt;p&gt;从这一点来看，SVG又一次成为了明日之星！设计师只要在illustrator中做好图就可以了，完全没有从前那种帮重构切图的苦逼经历了，是不是要啤酒炸鸡庆祝下！   &lt;img align="absmiddle" src="http://mat1.gtimg.com/www/mb/images/face/101.gif"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h3&gt;七、唯一的制约——兼容性&lt;/h3&gt;
 &lt;p&gt;SVG图标必定是未来的趋势。为何现在国内依然不温不火，不对，应该是还没有开始有温度。我觉得除了技术学习滞后性，浏览器兼容性是最关键的制约，毕竟IE8目前依然是大头(33.23%, 刚在百度流量研究院看到的数据)。&lt;/p&gt;
 &lt;p&gt;如何破？按照我的心情，鸟它个毛线，我就手机上用用，不也挺好。静下来想想，不能意气用事，提一下IE7/IE8浏览器的处理方法吧~&lt;/p&gt;
 &lt;p&gt;有些标签，浏览器识别，会忽略里面一些东西。例如SVG的  &lt;code&gt;desc&lt;/code&gt;元素，里面的内容一向不显示的。于是，对于IE7/IE8, 我们可以把对应图标的  &lt;code&gt;png&lt;/code&gt;图片放在其中，然后IE9+等支持SVG的浏览器就会忽略之，而IE7/IE8这些不识泰山的元素就会显示图片。拿礼物这个SVG举例：&lt;/p&gt;
 &lt;div&gt;
  &lt;pre&gt;&amp;lt;svg class=&amp;quot;webicon&amp;quot;&amp;gt;
    &amp;lt;desc&amp;gt;&amp;lt;img src=&amp;quot;iconfont-baobei.png&amp;quot; width=&amp;quot;16&amp;quot; height=&amp;quot;16&amp;quot;&amp;gt;&amp;lt;/desc&amp;gt;
    &amp;lt;use xlink:href=&amp;quot;#liwu&amp;quot;/&amp;gt;
&amp;lt;/svg&amp;gt;兑换礼物&lt;/pre&gt;
&lt;/div&gt;
 &lt;p&gt;于是，在IE8下，就会是这样：  &lt;br /&gt;
  &lt;img alt="IE8&amp;#27983;&amp;#35272;&amp;#22120;&amp;#19979;&amp;#25928;&amp;#26524;" height="167" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_172222.png" width="228"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;其他靠谱浏览器依然是这样：  &lt;br /&gt;
  &lt;img alt="SVG&amp;#20351;&amp;#29992;&amp;#30340;&amp;#22270;&amp;#26631;&amp;#25928;&amp;#26524;" height="208" src="http://image.zhangxinxu.com/image/blog/201407/2014-07-10_142916.png" width="327"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;于是，完美兼容了。只是活脱脱多了个标签，略败兴。当然，你也可以针对IE7/IE8使用CSS Sprite技术，原理类似，只是  &lt;code&gt;img&lt;/code&gt;标签换成其他  &lt;code&gt;i&lt;/code&gt;之类标签显示背景图，至少HTML这块会干净很多。&lt;/p&gt;
 &lt;h3&gt;八、结束语&lt;/h3&gt;
 &lt;p&gt;今年4月份的时候刚介绍过“  &lt;a href="http://www.zhangxinxu.com/wordpress/?p=4113"&gt;CSS3图标图形生成技术&lt;/a&gt;”，如果说“  &lt;code&gt;font-face&lt;/code&gt;图标生成技术”是热门的话，那“CSS3图标生成技术”则属于偏门，受设计制约很大，而本文介绍的“SVG Sprite图标生成”则代表了未来。&lt;/p&gt;
 &lt;p&gt;  &lt;code&gt;font-face&lt;/code&gt;在部分win系统下，字体较小的时候，锯齿问题很讨厌，苛刻的设计师无法忍受，甚至出现了响应式  &lt;code&gt;font-face&lt;/code&gt;这样的名堂，但是，据我观察，纯正的SVG图标是没有这个问题的，而且，SVG图标具备  &lt;code&gt;font-face&lt;/code&gt;几乎所有的优点，尺寸CSS可随意定制，颜色CSS可随意定制；且没有  &lt;code&gt;font-face&lt;/code&gt;异步加载延时渲染问题；同时没有某些浏览器下  &lt;code&gt;font-face&lt;/code&gt;跨域问题；更关键的是，SVG图标支持渐变，甚至彩色图标的。而  &lt;code&gt;font-face&lt;/code&gt;实现彩色图标，要一个一个拼起来，你以为贴马赛克啊！而且，SVG中每个  &lt;code&gt;path&lt;/code&gt;元素等可以独立控制，帅气的图标变换动画等的就是你来实现！&lt;/p&gt;
 &lt;p&gt;因此，各方面看，SVG完胜  &lt;code&gt;font-face&lt;/code&gt;, &lt;/p&gt;
 &lt;p&gt;目前唯一的问题就是兼容成本。但是，随着浏览器的发展，SVG一定会迎来自己Web新舞台！&lt;/p&gt;
 &lt;p&gt;感谢阅读，欢迎交流，踊跃纠错，多多赞助！  &lt;img align="absmiddle" src="http://mat1.gtimg.com/www/mb/images/face/13.gif"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;本文为原创文章，会经常更新知识点以及修正一些错误，因此转载请保留原出处，方便溯源，避免陈旧错误知识的误导，同时有更好的阅读体验。  &lt;br /&gt;
本文地址：  &lt;a href="http://www.zhangxinxu.com/wordpress/?p=4264"&gt;http://www.zhangxinxu.com/wordpress/?p=4264&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;（本篇完）&lt;/p&gt;
 &lt;div&gt;有话要说？点击  &lt;a href="http://www.zhangxinxu.com/wordpress/2014/07/introduce-svg-sprite-technology/#respond"&gt;这里&lt;/a&gt;发表评论。&lt;/div&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>SVG相关 css sprites grunt grunt-svgstore illustrator</category>
      <guid isPermaLink="true">https://itindex.net/detail/50332-%E6%9C%AA%E6%9D%A5-svg-sprite</guid>
      <pubDate>Thu, 10 Jul 2014 18:03:31 CST</pubDate>
    </item>
    <item>
      <title>使用uncss去除无用的CSS</title>
      <link>https://itindex.net/detail/49725-uncss-%E6%97%A0%E7%94%A8-css</link>
      <description>&lt;p&gt;从代码的角度讲，你知道什么是比往网站或应用里添加功能更好的事情吗？删除那些没用的东西。也许是一些代码、图片、或相关依赖等，就像扔掉家中储存柜里没用的产生异味的存货。我经常用ImageOptim来优化我的图片的体积，这既能提供页面加载速度，又能减少带宽流量。然而，你知道有什么工具能找到页面中样式文件里无用的CSS吗？之前我介绍过一个  &lt;a href="http://www.webhek.com/detect-unmatched-css-selectors/"&gt;用JavaScript找到无用CSS的方法&lt;/a&gt;，但事实上，我们并不想知道哪些CSS规则是无用的，我们想要的是一个没有多余CSS的干净的样式文件。所以，这个叫做  &lt;a href="https://github.com/giakki/uncss" rel="nofollow"&gt;   &lt;code&gt;uncss&lt;/code&gt;&lt;/a&gt;的NodeJS工具就是我们要找的了。下面我们来看看  &lt;code&gt;uncss&lt;/code&gt;是如何使用的！&lt;/p&gt;
 &lt;p&gt;一个基本的用法是直接在命令行窗口里输入  &lt;code&gt;uncss&lt;/code&gt;命令：&lt;/p&gt;
 &lt;pre&gt;uncss http://www.webhek.com &amp;gt; styles.css&lt;/pre&gt;
 &lt;p&gt;执行输出的结果就是一个你想要的、剔除了所有无用的CSS规则的完整的样式表文件。那  &lt;code&gt;uncss&lt;/code&gt;究竟是如何做到这些的呢？让我来一步步告诉你：&lt;/p&gt;
 &lt;blockquote&gt;
  &lt;ol&gt;
   &lt;li&gt;首先    &lt;a href="https://github.com/Obvious/phantomjs"&gt;PhantomJS&lt;/a&gt;会加载整个HTML页面，然后执行JavaScript。&lt;/li&gt;
   &lt;li&gt;接着从HTML页面里提取页面中所有的CSS样式。&lt;/li&gt;
   &lt;li&gt;然后用    &lt;a href="https://github.com/reworkcss/css"&gt;css-parse&lt;/a&gt;分析并连接所有的样式规则。&lt;/li&gt;
   &lt;li&gt;用    &lt;code&gt;document.querySelector&lt;/code&gt;过滤出哪些CSS选择器是没有用到的。&lt;/li&gt;
   &lt;li&gt;最后用剩下的CSS规则生成输出文件&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
 &lt;p&gt;跟其它NodeJS工具一样，它里面提供了很多JavaScriptAPI，下面是一个使用它的API的例子：&lt;/p&gt;
 &lt;pre&gt;var uncss = require(&amp;apos;uncss&amp;apos;);

var files   = [&amp;apos;my&amp;apos;, &amp;apos;array&amp;apos;, &amp;apos;of&amp;apos;, &amp;apos;HTML&amp;apos;, &amp;apos;files&amp;apos;],
    options = {
        ignore       : [&amp;apos;#added_at_runtime&amp;apos;, /test\-[0-9]+/],
        media        : [&amp;apos;(min-width: 700px) handheld and (orientation: landscape)&amp;apos;],
        csspath      : &amp;apos;../public/css/&amp;apos;,
        raw          : &amp;apos;h1 { color: green }&amp;apos;,
        stylesheets  : [&amp;apos;lib/bootstrap/dist/css/bootstrap.css&amp;apos;, &amp;apos;src/public/css/main.css&amp;apos;],
        ignoreSheets : [/fonts.googleapis/],
        urls         : [&amp;apos;http://localhost:3000/mypage&amp;apos;, &amp;apos;...&amp;apos;], // Deprecated
        timeout      : 1000,
        htmlroot     : &amp;apos;public&amp;apos;
    };

uncss(files, options, function (error, output) {
    console.log(output);
});

/* Look Ma, no options! */
uncss(files, function (error, output) {
    console.log(output);
});

/* Specifying raw HTML */
var raw_html = &amp;apos;...&amp;apos;;
uncss(raw_html, options, function (error, output) {
    console.log(output);
});&lt;/pre&gt;
 &lt;p&gt;一个运行维护多年的网站或Web应用必定会产生很多无用的代码，这是毫无例外的。多余的代码不仅给WEB程序员带来维护的负担，也给使用者造成负面效应。请试一下  &lt;code&gt;uncss&lt;/code&gt;，真的非常简单，完全自动的帮你清除无用的CSS代码！&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>开发工具 css css优化 uncss 无用的CSS</category>
      <guid isPermaLink="true">https://itindex.net/detail/49725-uncss-%E6%97%A0%E7%94%A8-css</guid>
      <pubDate>Sun, 25 May 2014 00:18:40 CST</pubDate>
    </item>
    <item>
      <title>9个最新的手机/移动设备jQuery插件</title>
      <link>https://itindex.net/detail/49968-%E6%89%8B%E6%9C%BA-%E7%A7%BB%E5%8A%A8%E8%AE%BE%E5%A4%87-jquery</link>
      <description>&lt;p&gt;随着互联网的流行，移动网站开始急速增加，在2014年手机网站将会出现很多，所以手机网站是必须要学会制作的。手机网站不像桌面平台一样制作，否则会影响显示效果，目前大部分手机网站使用  &lt;a href="http://www.shejidaren.com/tag/%e8%87%aa%e9%80%82%e5%ba%94"&gt;响应式设计&lt;/a&gt;技术，而且也很流行。&lt;/p&gt;
 &lt;p&gt;但是新手想实现响应式技术是不容易的，所以我们可以用一些响应式框架或适用于移动设备的jQuery插件来制作，这样能方便实现我们的需求。&lt;/p&gt;
 &lt;p&gt;今天设计达人网小编整理了9个好用的手机/移动设备jQuery插件，也许对你的手机项目有帮助哦！&lt;/p&gt;
 &lt;div&gt;相关  &lt;strong&gt;响应式&lt;/strong&gt;资源推荐：  &lt;br /&gt;
《  &lt;a href="http://www.shejidaren.com/10-responsive-navigation-tutorials.html"&gt;10个响应式设计的导航菜单源码-附教程&lt;/a&gt;》  &lt;br /&gt;
《  &lt;a href="http://www.shejidaren.com/responsive-web-desing-showcase-psd.html"&gt;响应式WEB设计展示必备 – PSD&lt;/a&gt;》  &lt;br /&gt;
《  &lt;a href="http://www.shejidaren.com/responsive-web-design-resource-and-frameworks.html"&gt;响应性网页设计资源及框架工具&lt;/a&gt;》
&lt;/div&gt;
 &lt;h3&gt;IOSSCRIPTS&lt;/h3&gt;
 &lt;p&gt;iosslider这个jQuery插件可以让桌面、手机、平板设备实现自适应的网页幻灯片（灯箱），支持水平和垂直方式。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="IOSSCRIPTS &amp;#25163;&amp;#26426;&amp;#25554;&amp;#20214; jQuery&amp;#25554;&amp;#20214;" border="0" height="340" src="http://images.shejidaren.com/wp-content/uploads/2014/06/034632vOc.jpg" title="IOSSCRIPTS" width="500"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://iosscripts.com/" rel="nofollow" target="_blank"&gt;查看演示及下载&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;Slip.js&lt;/h3&gt;
 &lt;p&gt;如果想实现触摸设备排序的话，我想Slip.js插件是最好的选择。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="Slip.js &amp;#25163;&amp;#26426;&amp;#25554;&amp;#20214; jQuery&amp;#25554;&amp;#20214;" height="347" src="http://images.shejidaren.com/wp-content/uploads/2014/06/slip-js-demo.gif" title="Slip.js" width="282"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://pornel.net/slip/" rel="nofollow" target="_blank"&gt;查看演示&lt;/a&gt;   &lt;a href="https://github.com/pornel/slip" rel="nofollow" target="_blank"&gt;下载插件&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;jQuery Finger&lt;/h3&gt;
 &lt;p&gt;一个触摸事件插件。和其它相关插件不同的是，它会移除触摸设备的300毫秒延迟。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="jQuery Finger &amp;#25163;&amp;#26426;&amp;#25554;&amp;#20214; jQuery&amp;#25554;&amp;#20214;" border="0" height="414" src="http://images.shejidaren.com/wp-content/uploads/2014/06/034632xid.jpg" title="jQuery Finger" width="500"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://ngryman.sh/jquery.finger/" rel="nofollow" target="_blank"&gt;查看演示&lt;/a&gt;   &lt;a href="http://github.com/ngryman/jquery.finger/zipball/v0.1.0" rel="nofollow" target="_blank"&gt;下载插件&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;Tocca.js&lt;/h3&gt;
 &lt;p&gt;超轻量级的触摸事件插件，大小只有1KB啊。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="Tocca.js &amp;#25163;&amp;#26426;&amp;#25554;&amp;#20214; jQuery&amp;#25554;&amp;#20214;" border="0" height="366" src="http://images.shejidaren.com/wp-content/uploads/2014/06/034632Pcq.jpg" title="Tocca.js" width="500"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://gianlucaguarini.github.io/Tocca.js/demo-fun.html" rel="nofollow" target="_blank"&gt;查看演示&lt;/a&gt;   &lt;a href="https://github.com/GianlucaGuarini/Tocca.js" rel="nofollow" target="_blank"&gt;下载插件&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;Leader.js&lt;/h3&gt;
 &lt;p&gt;用户登陆插件，目前为概念设计，是否真适用在实际项目中使用呢？&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="Leader.js &amp;#25163;&amp;#26426;&amp;#25554;&amp;#20214; jQuery&amp;#25554;&amp;#20214;" border="0" height="312" src="http://images.shejidaren.com/wp-content/uploads/2014/06/034632tHd.jpg" title="Leader.js" width="500"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://demo.peterbailey.eu/Leader.js/example.html" rel="nofollow" target="_blank"&gt;查看演示&lt;/a&gt;   &lt;a href="https://github.com/pea/Leader.js" rel="nofollow" target="_blank"&gt;下载插件&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;JQuery Mobile Date Navigation&lt;/h3&gt;
 &lt;p&gt;移动手机设备的日历导航插件，如果有日期弹出来选择就更强大了。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="JQuery Mobile Date Navigation &amp;#25163;&amp;#26426;&amp;#25554;&amp;#20214; jQuery&amp;#25554;&amp;#20214;" border="0" height="363" src="http://images.shejidaren.com/wp-content/uploads/2014/06/034632j3i.jpg" title="JQuery Mobile Date Navigation" width="500"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://victor-valencia.github.io/jquery-mobile-date-navigation/" rel="nofollow" target="_blank"&gt;查看演示及下载&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;jQuery Navobile&lt;/h3&gt;
 &lt;p&gt;这类侧边栏导航菜单插件我们介绍过，请看《  &lt;a href="http://www.shejidaren.com/slider-menu-jquery-plugins.html"&gt;好用的侧边栏菜单/面板jQuery插件&lt;/a&gt;》一文。&lt;/p&gt;
 &lt;p&gt;查看演示时，请把你的浏览器缩小到手机的分辨率就可以看一以了。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="jQuery Navobile &amp;#25163;&amp;#26426;&amp;#25554;&amp;#20214; jQuery&amp;#25554;&amp;#20214;" border="0" height="309" src="http://images.shejidaren.com/wp-content/uploads/2014/06/034632A04.jpg" title="jQuery Navobile" width="500"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://madebymade.github.io/jquery-navobile/" rel="nofollow" target="_blank"&gt;查看演示及下载&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;Responsive Mobile Menu&lt;/h3&gt;
 &lt;p&gt;一个响应式移动设备菜单插件。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="Responsive Mobile Menu &amp;#25163;&amp;#26426;&amp;#25554;&amp;#20214; jQuery&amp;#25554;&amp;#20214;" border="0" height="295" src="http://images.shejidaren.com/wp-content/uploads/2014/06/034632srL.jpg" title="Responsive Mobile Menu" width="500"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://responsivemobilemenu.com/en/" rel="nofollow" target="_blank"&gt;查看演示及下载&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;PhotoSwipe&lt;/h3&gt;
 &lt;p&gt;图像展示类的移动设备插件，功能实用，而且效果不错，请看DEMO体验。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="PhotoSwipe &amp;#25163;&amp;#26426;&amp;#25554;&amp;#20214; jQuery&amp;#25554;&amp;#20214;" border="0" height="375" src="http://images.shejidaren.com/wp-content/uploads/2014/06/034632DLh.jpg" title="PhotoSwipe" width="500"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://photoswipe.com/latest/examples/jquery-mobile.html" rel="nofollow" target="_blank"&gt;查看演示&lt;/a&gt;   &lt;a href="http://photoswipe.com/" rel="nofollow" target="_blank"&gt;下载插件&lt;/a&gt;&lt;/p&gt;
 &lt;hr&gt;&lt;/hr&gt;Copyright ©2010-2014 ¦  &lt;a href="http://www.shejidaren.com/feed" target="_blank" title="RSS&amp;#35746;&amp;#38405;"&gt;RSS订阅&lt;/a&gt; ¦  &lt;a href="http://weibo.com/shejidaren888" target="_blank" title="&amp;#26032;&amp;#28010;&amp;#24494;&amp;#21338;"&gt;新浪微博&lt;/a&gt; ¦  &lt;a href="http://www.shejidaren.com/9-jquery-mobile-plugins.html" target="_blank" title="9&amp;#20010;&amp;#26368;&amp;#26032;&amp;#30340;&amp;#25163;&amp;#26426;/&amp;#31227;&amp;#21160;&amp;#35774;&amp;#22791;jQuery&amp;#25554;&amp;#20214;"&gt;本文链接&lt;/a&gt; ¦  &lt;a href="http://www.shejidaren.com/9-jquery-mobile-plugins.html#respond" target="_blank" title="9&amp;#20010;&amp;#26368;&amp;#26032;&amp;#30340;&amp;#25163;&amp;#26426;/&amp;#31227;&amp;#21160;&amp;#35774;&amp;#22791;jQuery&amp;#25554;&amp;#20214;&amp;#30340;&amp;#35780;&amp;#35770;"&gt;添加评论&lt;/a&gt;  &lt;br /&gt;交流：UI设计交流群：59300679，与500名设计师交流设计，分享素材。&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>HTML &amp; CSS jQuery</category>
      <guid isPermaLink="true">https://itindex.net/detail/49968-%E6%89%8B%E6%9C%BA-%E7%A7%BB%E5%8A%A8%E8%AE%BE%E5%A4%87-jquery</guid>
      <pubDate>Tue, 10 Jun 2014 15:20:17 CST</pubDate>
    </item>
    <item>
      <title>100个惊人的CSS、JS代码技术</title>
      <link>https://itindex.net/detail/47699-css-js-%E4%BB%A3%E7%A0%81</link>
      <description>&lt;p&gt;  &lt;img alt="css top-2013" src="http://images.shejidaren.com/wp-content/uploads/2014/01/090348o8m.png" width="500"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;最近在Codepen看到Top Pens of 2013这个专题，专题内容为2013年上最优秀的前100个CSS、HTML5和Javascript Pens，在惊叹技术人员的创造力同时我们还能学习这些技术，对交互设计师而言还能获取灵感哦！&lt;/p&gt;
 &lt;blockquote&gt;  &lt;p&gt;Top Pens of 2013专题地址：   &lt;a href="http://codepen.io/2013/popular" rel="nofollow" target="_blank"&gt;http://codepen.io/2013/popular&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
 &lt;p&gt;这里我们选出排名前10名的Pens，无论是前端人员还是设计师，我觉得还是值得一看的。PS:在浏览这些技术记得使用兼容CSS3/  &lt;a href="http://www.shejidaren.com/tag/html5"&gt;HTML5&lt;/a&gt;的浏览器哦，否则有些效果你看不出来。&lt;/p&gt;
 &lt;h3&gt;TOP 10: CSS 绝对居中（水平垂直居中）&lt;/h3&gt;
 &lt;p&gt;一个CSS居中的新写法，这个我觉得比较实用，因为兼容IE8呢，IE6就不说了，一边去吧。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="css top-10" src="http://images.shejidaren.com/wp-content/uploads/2014/01/090349yAo.png" width="500"&gt;&lt;/img&gt;  &lt;br /&gt;
  &lt;a href="http://codepen.io/shshaw/pen/gEiDt" rel="nofollow" target="_blank"&gt;在看演示&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;TOP 9: 跟随移动鼠标HOVER特效&lt;/h3&gt;
 &lt;p&gt;这个中文有点难解释，大家自己看案例才知道是什么效果…挺新鲜的效果。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="css top-09" src="http://images.shejidaren.com/wp-content/uploads/2014/01/090349jxi.png" width="500"&gt;&lt;/img&gt;  &lt;br /&gt;
  &lt;a href="http://codepen.io/noeldelgado/pen/pGwFx" rel="nofollow" target="_blank"&gt;在看演示&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;TOP 8: 拟实化倒计时实例&lt;/h3&gt;
 &lt;p&gt;这个倒计时设计图出来的时候，第一眼就很喜欢了，现在代码版了，些DEMO由CSS+JS写的。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="css top-08" src="http://images.shejidaren.com/wp-content/uploads/2014/01/090349bHj.png" width="500"&gt;&lt;/img&gt;  &lt;br /&gt;
  &lt;a href="http://codepen.io/ademilter/pen/czIGo" rel="nofollow" target="_blank"&gt;在看演示&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;TOP 7: CSS 3D效果&lt;/h3&gt;
 &lt;p&gt;这个在实际项目中没什么有，但可以用来学习研究，看看能否在其它项目上使用。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="css top-07" src="http://images.shejidaren.com/wp-content/uploads/2014/01/090349n0M.png" width="500"&gt;&lt;/img&gt;  &lt;br /&gt;
  &lt;a href="http://codepen.io/peterwestendorp/pen/JEomi" rel="nofollow" target="_blank"&gt;在看演示&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;TOP 6: CSS+jQuery实现WIN8风格的效果切换&lt;/h3&gt;
 &lt;p&gt;效果确实真的不错，动画也流畅，如果用在个人博客还是挺个性化的。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="css top-06" src="http://images.shejidaren.com/wp-content/uploads/2014/01/090349PdD.png" width="500"&gt;&lt;/img&gt;  &lt;br /&gt;
  &lt;a href="http://codepen.io/SaraSoueidan/pen/sBELl" rel="nofollow" target="_blank"&gt;在看演示&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;TOP 5: 创意CSS菜单&lt;/h3&gt;
 &lt;p&gt;这个CSS写的菜单真的很有创新，点击后会以动画形式改变成形状的图标，NICE!&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="css top-05" src="http://images.shejidaren.com/wp-content/uploads/2014/01/090349g9U.png" width="500"&gt;&lt;/img&gt;  &lt;br /&gt;
  &lt;a href="http://codepen.io/bennettfeely/pen/twbyA" rel="nofollow" target="_blank"&gt;在看演示&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;TOP 4: 拟实化CSS按钮&lt;/h3&gt;
 &lt;p&gt;使用  &lt;a href="http://www.shejidaren.com/tag/css3"&gt;CSS3&lt;/a&gt;编写，效果不错。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="css top-04" src="http://images.shejidaren.com/wp-content/uploads/2014/01/090349PLx.png" width="500"&gt;&lt;/img&gt;  &lt;br /&gt;
  &lt;a href="http://codepen.io/soulwire/pen/bKens" rel="nofollow" target="_blank"&gt;在看演示&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;TOP 3: 创新CSS按钮&lt;/h3&gt;
 &lt;p&gt;鼠标移到按钮上的打开面板效果很不错，带3D感，还有阴影啊，做得真细节。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="css top-03" src="http://images.shejidaren.com/wp-content/uploads/2014/01/090349rNI.png" width="500"&gt;&lt;/img&gt;  &lt;br /&gt;
  &lt;a href="http://codepen.io/bennettfeely/pen/ErFGv" rel="nofollow" target="_blank"&gt;在看演示&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;TOP 2: 触摸设备菜单概念设计&lt;/h3&gt;
 &lt;p&gt;设计可爱，动画效果也很棒，赞！&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="css top-02" src="http://images.shejidaren.com/wp-content/uploads/2014/01/0903491y4.png" width="500"&gt;&lt;/img&gt;  &lt;br /&gt;
  &lt;a href="http://codepen.io/sol0mka/pen/Jsyxq" rel="nofollow" target="_blank"&gt;在看演示&lt;/a&gt;&lt;/p&gt;
 &lt;h3&gt;TOP 1: Tearable Cloth&lt;/h3&gt;
 &lt;p&gt;十分强大的js技术特效，PS: 用右键可以把网切开哦！&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="css top-01" src="http://images.shejidaren.com/wp-content/uploads/2014/01/090349Frc.png" width="500"&gt;&lt;/img&gt;  &lt;br /&gt;
  &lt;a href="http://codepen.io/suffick/pen/KrAwx" rel="nofollow" target="_blank"&gt;在看演示&lt;/a&gt;&lt;/p&gt;
 &lt;hr&gt;&lt;/hr&gt;Copyright ©2010-2013 ¦  &lt;a href="http://feed.feedsky.com/sjdr" target="_blank" title="RSS&amp;#35746;&amp;#38405;"&gt;RSS订阅&lt;/a&gt; ¦  &lt;a href="http://weibo.com/shejidaren888" target="_blank" title="&amp;#26032;&amp;#28010;&amp;#24494;&amp;#21338;"&gt;新浪微博&lt;/a&gt; ¦ &lt;a href="http://www.shejidaren.com/100-powerful-css-and-js-demo.html" target="_blank" title="100&amp;#20010;&amp;#24778;&amp;#20154;&amp;#30340;CSS&amp;#12289;JS&amp;#20195;&amp;#30721;&amp;#25216;&amp;#26415;"&gt;本文链接&lt;/a&gt; ¦  &lt;a href="http://www.shejidaren.com/100-powerful-css-and-js-demo.html#respond" target="_blank" title="100&amp;#20010;&amp;#24778;&amp;#20154;&amp;#30340;CSS&amp;#12289;JS&amp;#20195;&amp;#30721;&amp;#25216;&amp;#26415;&amp;#30340;&amp;#35780;&amp;#35770;"&gt;添加评论&lt;/a&gt; &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>HTML &amp; CSS CSS3 HTML5</category>
      <guid isPermaLink="true">https://itindex.net/detail/47699-css-js-%E4%BB%A3%E7%A0%81</guid>
      <pubDate>Mon, 20 Jan 2014 17:09:45 CST</pubDate>
    </item>
    <item>
      <title>8个纯CSS编写的手机设备Mock Up模型</title>
      <link>https://itindex.net/detail/48758-css-%E6%89%8B%E6%9C%BA-%E8%AE%BE%E5%A4%87</link>
      <description>&lt;p&gt;很多设计师在交付设计稿给客户预览时，都喜欢把自己的作品放在一些手机模型或电脑模型上演示，这样可以让客户看到最终的效果输出，所以MOCK UP我们应该收藏一些，在今天的文章中，我们分享8个纯CSS编写的手机设备Mock Up模型，手机品牌有很多哦，如：iPhone5S/5C、诺基亚的Lumia 920、HTC、三星等等，下面一起看看介绍。&lt;/p&gt;
 &lt;p&gt;其实大家也可以用这个来学习CSS，看看人家是怎么写的，然后自己做个练习出来，并不是很难的哦！相关推荐：前往《  &lt;a href="http://www.shejidaren.com/apple-product-psd-mockups.html"&gt;30个苹果系列产品模型&lt;/a&gt;》的分享，里面都是PSD或AI格式的素材，也是不错的选择！&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="8-Pure-CSS-Flat-Mobile-Devices" src="http://images.shejidaren.com/wp-content/uploads/2014/03/8-Pure-CSS-Flat-Mobile-Devices.jpg" width="500"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;这组手机Mockup由Marvelapp分享，通过CSS样式编写如此漂亮的扁平化手机设备，确实很赞。&lt;/p&gt;
 &lt;h3&gt;设备模型和颜色&lt;/h3&gt;
 &lt;ul&gt;
  &lt;li&gt;iPhone 5S（颜色：黑·白·金）&lt;/li&gt;
  &lt;li&gt;iPhone 5C（颜色：白·红·黄·绿·蓝）&lt;/li&gt;
  &lt;li&gt;iPad mini（颜色：黑色·白色）&lt;/li&gt;
  &lt;li&gt;iPhone 4S（颜色：黑色·白色）&lt;/li&gt;
  &lt;li&gt;Nexus 5&lt;/li&gt;
  &lt;li&gt;Lumia 920（颜色：黑·白·黄·红·蓝）&lt;/li&gt;
  &lt;li&gt;三星 S5（颜色：白色·黑色）&lt;/li&gt;
  &lt;li&gt;HTC one&lt;/li&gt;
&lt;/ul&gt;
 &lt;h3&gt;垂直&amp;amp;水平切换&lt;/h3&gt;
 &lt;p&gt;此外，我们可以点击  &lt;code&gt;LANDSCAPE&lt;/code&gt;链接来切换模板的水平和垂直展示，点击其它描点为切换颜色。  &lt;br /&gt;
  &lt;img alt="lumia-920-1" src="http://images.shejidaren.com/wp-content/uploads/2014/03/lumia-920-1.jpg" width="500"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;图：垂直视图&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="lumia-920-2" src="http://images.shejidaren.com/wp-content/uploads/2014/03/lumia-920-2.jpg" width="500"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;图：水平视图，点landscape切换&lt;/p&gt;
 &lt;h3&gt;使用方法&lt;/h3&gt;
 &lt;pre&gt;
#iphone5s.landscape.gold
        .device
                .inner
                .sleep
                .volume
                .camera
                .top-bar
                .sensor
                .speaker
                .screen
                        显示屏文字
                .bottom-bar
                .home
&lt;/pre&gt;
 &lt;p&gt;就介绍这么多，大家可以点击下面的连接去看看Demo和下载它。&lt;/p&gt;
 &lt;div&gt;  &lt;a href="http://marvelapp.github.io/devices.css/" rel="nofollow" target="_blank"&gt;在线DEMO&lt;/a&gt; |   &lt;a href="https://github.com/marvelapp/devices.css" rel="nofollow" target="_blank"&gt;下载模板文件&lt;/a&gt;（github）&lt;/div&gt;
 &lt;hr&gt;&lt;/hr&gt;Copyright ©2010-2014 ¦  &lt;a href="http://www.shejidaren.com/feed" target="_blank" title="RSS&amp;#35746;&amp;#38405;"&gt;RSS订阅&lt;/a&gt; ¦  &lt;a href="http://weibo.com/shejidaren888" target="_blank" title="&amp;#26032;&amp;#28010;&amp;#24494;&amp;#21338;"&gt;新浪微博&lt;/a&gt; ¦  &lt;a href="http://www.shejidaren.com/8-pure-css-flat-mobile-devices.html" target="_blank" title="8&amp;#20010;&amp;#32431;CSS&amp;#32534;&amp;#20889;&amp;#30340;&amp;#25163;&amp;#26426;&amp;#35774;&amp;#22791;Mock Up&amp;#27169;&amp;#22411;"&gt;本文链接&lt;/a&gt; ¦  &lt;a href="http://www.shejidaren.com/8-pure-css-flat-mobile-devices.html#respond" target="_blank" title="8&amp;#20010;&amp;#32431;CSS&amp;#32534;&amp;#20889;&amp;#30340;&amp;#25163;&amp;#26426;&amp;#35774;&amp;#22791;Mock Up&amp;#27169;&amp;#22411;&amp;#30340;&amp;#35780;&amp;#35770;"&gt;添加评论&lt;/a&gt;  &lt;br /&gt;交流：UI设计交流群：59300679，与500名设计师交流设计，分享素材。&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>HTML &amp; CSS CSS3</category>
      <guid isPermaLink="true">https://itindex.net/detail/48758-css-%E6%89%8B%E6%9C%BA-%E8%AE%BE%E5%A4%87</guid>
      <pubDate>Thu, 27 Mar 2014 15:27:21 CST</pubDate>
    </item>
    <item>
      <title>优秀的 HTML 和 CSS 代码规范</title>
      <link>https://itindex.net/detail/48755-html-css-%E4%BB%A3%E7%A0%81</link>
      <description>&lt;div&gt;
  &lt;p&gt;   &lt;a href="http://www.shtion.com/tag/html" target="_blank" title="&amp;#26597;&amp;#30475;HTML&amp;#20013;&amp;#30340;&amp;#20840;&amp;#37096;&amp;#25991;&amp;#31456;"&gt;HTML&lt;/a&gt; 和 CSS 代码规范究竟是怎么样的？做网站时，   &lt;a href="http://www.shtion.com/tag/html" target="_blank" title="&amp;#26597;&amp;#30475;HTML&amp;#20013;&amp;#30340;&amp;#20840;&amp;#37096;&amp;#25991;&amp;#31456;"&gt;HTML&lt;/a&gt; 和 CSS 代码有什么要求？   &lt;a href="http://www.shtion.com/tag/html" target="_blank" title="&amp;#26597;&amp;#30475;HTML&amp;#20013;&amp;#30340;&amp;#20840;&amp;#37096;&amp;#25991;&amp;#31456;"&gt;HTML&lt;/a&gt; 和 CSS 代码的写法是否影响网站的SEO？写好    &lt;a href="http://www.shtion.com/tag/html" target="_blank" title="&amp;#26597;&amp;#30475;HTML&amp;#20013;&amp;#30340;&amp;#20840;&amp;#37096;&amp;#25991;&amp;#31456;"&gt;HTML&lt;/a&gt; 和 CSS 代码需要注意些什么？带着这些问题请看本文。&lt;/p&gt;
  &lt;p&gt;一般大型WEB站点开发设计人员，要求使用者具有一定的   &lt;a href="http://www.shtion.com/tag/html" target="_blank" title="&amp;#26597;&amp;#30475;HTML&amp;#20013;&amp;#30340;&amp;#20840;&amp;#37096;&amp;#25991;&amp;#31456;"&gt;HTML&lt;/a&gt;、CSS基础知识，对原代码具有较强的控制能力。本规范的目的是为了开发出通用的、易于维护的高效率的WEB界面。&lt;/p&gt;
  &lt;a href="http://www.shtion.com/wp-content/uploads/html-css-guifan.jpg"&gt;   &lt;img alt="html-css-guifan" height="315" src="http://www.shtion.com/wp-content/uploads/html-css-guifan.jpg" width="450"&gt;&lt;/img&gt;&lt;/a&gt;
  &lt;h2&gt;   &lt;a href="http://www.shtion.com/tag/html" target="_blank" title="&amp;#26597;&amp;#30475;HTML&amp;#20013;&amp;#30340;&amp;#20840;&amp;#37096;&amp;#25991;&amp;#31456;"&gt;HTML&lt;/a&gt;&lt;/h2&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;语法&lt;/h3&gt;
   &lt;ul&gt;
    &lt;li&gt;用两个空格来代替制表符（tab） — 这是唯一能保证在所有环境下获得一致展现的方法。&lt;/li&gt;
    &lt;li&gt;嵌套元素应当缩进一次（即两个空格）。&lt;/li&gt;
    &lt;li&gt;对于属性的定义，确保全部使用双引号，绝不要使用单引号。&lt;/li&gt;
    &lt;li&gt;不要在自闭和（self-closing）元素的尾部添加斜线 –     &lt;a href="http://dev.w3.org/html5/spec-author-view/syntax.html#syntax-start-tag"&gt;HTML5 规范&lt;/a&gt;中明确说明这是可选的。&lt;/li&gt;
    &lt;li&gt;不要省略可选的结束标签（closing tag）（例如，     &lt;code&gt;&amp;lt;/li&amp;gt;&lt;/code&gt;或      &lt;code&gt;&amp;lt;/body&amp;gt;&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Page title&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;img src=&amp;quot;images/company-logo.png&amp;quot; alt=&amp;quot;Company&amp;quot;&amp;gt;
    &amp;lt;h1&amp;gt;Hello, world!&amp;lt;/h1&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;    &lt;a href="http://www.shtion.com/tag/html" target="_blank" title="&amp;#26597;&amp;#30475;HTML&amp;#20013;&amp;#30340;&amp;#20840;&amp;#37096;&amp;#25991;&amp;#31456;"&gt;HTML&lt;/a&gt;5 doctype&lt;/h3&gt;
   &lt;p&gt;为每个     &lt;a href="http://www.shtion.com/tag/html" target="_blank" title="&amp;#26597;&amp;#30475;HTML&amp;#20013;&amp;#30340;&amp;#20840;&amp;#37096;&amp;#25991;&amp;#31456;"&gt;HTML&lt;/a&gt; 页面的第一行添加标准模（standard mode）式的声明，这样能够确保在每个浏览器中拥有一致的展现。&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
  &amp;lt;/head&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;语言属性&lt;/h3&gt;
   &lt;p&gt;根据     &lt;a href="http://www.shtion.com/tag/html" target="_blank" title="&amp;#26597;&amp;#30475;HTML&amp;#20013;&amp;#30340;&amp;#20840;&amp;#37096;&amp;#25991;&amp;#31456;"&gt;HTML&lt;/a&gt;5 规范：&lt;/p&gt;
   &lt;blockquote&gt;    &lt;p&gt;强烈建议为 html 根元素指定 lang 属性，从而为文档设置正确的语言。这将有助于语音合成工具确定其所应该采用的发音，有助于翻译工具确定其翻译时所应遵守的规则等等。&lt;/p&gt;&lt;/blockquote&gt;
   &lt;p&gt;更多关于     &lt;code&gt;lang&lt;/code&gt; 属性的知识可以从     &lt;a href="http://www.w3.org/html/wg/drafts/html/master/semantics.html#the-html-element"&gt;此规范&lt;/a&gt; 中了解。&lt;/p&gt;
   &lt;p&gt;这里列出了    &lt;a href="http://reference.sitepoint.com/html/lang-codes"&gt;语言代码表&lt;/a&gt;。&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;&amp;lt;html lang=&amp;quot;en-us&amp;quot;&amp;gt;
  &amp;lt;!-- ... --&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;IE 兼容模式&lt;/h3&gt;
   &lt;p&gt;IE 支持通过特定的     &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; 标签来确定绘制当前页面所应该采用的 IE 版本。除非有强烈的特殊需求，否则最好是设置为    &lt;strong&gt;edge mode&lt;/strong&gt;，从而通知 IE 采用其所支持的最新的模式。&lt;/p&gt;
   &lt;a href="http://stackoverflow.com/questions/6771258/whats-the-difference-if-meta-http-equiv-x-ua-compatible-content-ie-edge-e"&gt;阅读这篇 stack overflow 上的文章&lt;/a&gt;可以获得更多有用的信息。   &lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;&amp;lt;meta http-equiv=&amp;quot;X-UA-Compatible&amp;quot; content=&amp;quot;IE=Edge&amp;quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;字符编码&lt;/h3&gt;
   &lt;p&gt;通过明确声明字符编码，能够确保浏览器快速并容易的判断页面内容的渲染方式。这样做的好处是，可以避免在     &lt;a href="http://www.shtion.com/tag/html" target="_blank" title="&amp;#26597;&amp;#30475;HTML&amp;#20013;&amp;#30340;&amp;#20840;&amp;#37096;&amp;#25991;&amp;#31456;"&gt;HTML&lt;/a&gt; 中使用字符实体标记（character entity），从而全部与文档编码一致（一般采用 UTF-8 编码）。&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;&amp;lt;head&amp;gt;
  &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;
&amp;lt;/head&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;引入 CSS 和 JavaScript 文件&lt;/h3&gt;
   &lt;p&gt;根据     &lt;a href="http://www.shtion.com/tag/html" target="_blank" title="&amp;#26597;&amp;#30475;HTML&amp;#20013;&amp;#30340;&amp;#20840;&amp;#37096;&amp;#25991;&amp;#31456;"&gt;HTML&lt;/a&gt;5 规范，在引入 CSS 和 JavaScript 文件时一般不需要指定     &lt;code&gt;type&lt;/code&gt; 属性，因为     &lt;code&gt;text/     &lt;a href="http://www.shtion.com/tag/css" target="_blank" title="&amp;#26597;&amp;#30475;css&amp;#20013;&amp;#30340;&amp;#20840;&amp;#37096;&amp;#25991;&amp;#31456;"&gt;css&lt;/a&gt;&lt;/code&gt; 和     &lt;code&gt;text/javascript&lt;/code&gt;分别是它们的默认值。&lt;/p&gt;
   &lt;h4&gt;HTML5 spec links&lt;/h4&gt;
   &lt;ul&gt;
    &lt;li&gt;     &lt;a href="http://www.w3.org/TR/2011/WD-html5-20110525/semantics.html#the-link-element"&gt;Using link&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;a href="http://www.w3.org/TR/2011/WD-html5-20110525/semantics.html#the-style-element"&gt;Using style&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;a href="http://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#the-script-element"&gt;Using script&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;&amp;lt;!-- External CSS --&amp;gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;code-guide.      &lt;a href="http://www.shtion.com/tag/css" target="_blank" title="&amp;#26597;&amp;#30475;css&amp;#20013;&amp;#30340;&amp;#20840;&amp;#37096;&amp;#25991;&amp;#31456;"&gt;css&lt;/a&gt;&amp;quot;&amp;gt;

&amp;lt;!-- In-document CSS --&amp;gt;
&amp;lt;style&amp;gt;
  /* ... */
&amp;lt;/style&amp;gt;

&amp;lt;!-- JavaScript --&amp;gt;
&amp;lt;script src=&amp;quot;code-guide.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;实用为王&lt;/h3&gt;
   &lt;p&gt;尽量遵循 HTML 标准和语义，但是不要以牺牲实用性为代价。任何时候都要尽量使用最少的标签并保持最小的复杂度。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;属性顺序&lt;/h3&gt;
   &lt;p&gt;HTML 属性应当按照以下给出的顺序依次排列，确保代码的易读性。&lt;/p&gt;
   &lt;ul&gt;
    &lt;li&gt;     &lt;code&gt;class&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;code&gt;id&lt;/code&gt;,      &lt;code&gt;name&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;code&gt;data-*&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;code&gt;src&lt;/code&gt;,      &lt;code&gt;for&lt;/code&gt;,      &lt;code&gt;type&lt;/code&gt;,      &lt;code&gt;href&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;code&gt;title&lt;/code&gt;,      &lt;code&gt;alt&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;code&gt;aria-*&lt;/code&gt;,      &lt;code&gt;role&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
   &lt;p&gt;class 用于标识高度可复用组件，因此应该排在首位。id 用于标识具体组件，应当谨慎使用（例如，页面内的书签），因此排在第二位。&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;&amp;lt;a id=&amp;quot;...&amp;quot; data-modal=&amp;quot;toggle&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;
  Example link
&amp;lt;/a&amp;gt;

&amp;lt;input type=&amp;quot;text&amp;quot;&amp;gt;

&amp;lt;img src=&amp;quot;...&amp;quot; alt=&amp;quot;...&amp;quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;布尔（boolean）型属性&lt;/h3&gt;
   &lt;p&gt;布尔型属性可以在声明时不赋值。XHTML 规范要求为其赋值，但是 HTML5 规范不需要。&lt;/p&gt;
   &lt;p&gt;更多信息请参考     &lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#boolean-attributes"&gt;WhatWG section on boolean attributes&lt;/a&gt;：&lt;/p&gt;
   &lt;blockquote&gt;    &lt;p&gt;元素的布尔型属性如果有值，就是 true，如果没有值，就是 false。&lt;/p&gt;&lt;/blockquote&gt;
   &lt;p&gt;如果    &lt;em&gt;一定&lt;/em&gt;要为其赋值的话，请参考 WhatWG 规范：&lt;/p&gt;
   &lt;blockquote&gt;    &lt;p&gt;如果属性存在，其值必须是空字符串或 [...] 属性的规范名称，并且不要再收尾添加空白符。&lt;/p&gt;&lt;/blockquote&gt;
   &lt;p&gt;    &lt;strong&gt;简单来说，就是不用赋值。&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;&amp;lt;input type=&amp;quot;text&amp;quot; disabled&amp;gt;

&amp;lt;input type=&amp;quot;checkbox&amp;quot; value=&amp;quot;1&amp;quot; checked&amp;gt;

&amp;lt;select&amp;gt;
  &amp;lt;option value=&amp;quot;1&amp;quot; selected&amp;gt;1&amp;lt;/option&amp;gt;
&amp;lt;/select&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;减少标签的数量&lt;/h3&gt;
   &lt;p&gt;编写 HTML 代码时，尽量避免多余的父元素。很多时候，这需要迭代和重构来实现。请看下面的案例：&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;&amp;lt;!-- Not so great --&amp;gt;
&amp;lt;span&amp;gt;
  &amp;lt;img src=&amp;quot;...&amp;quot;&amp;gt;
&amp;lt;/span&amp;gt;

&amp;lt;!-- Better --&amp;gt;
&amp;lt;img src=&amp;quot;...&amp;quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;JavaScript 生成的标签&lt;/h3&gt;
   &lt;p&gt;通过 JavaScript 生成的标签让内容变得不易查找、编辑，并且降低性能。能避免时尽量避免。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;h2&gt;CSS&lt;/h2&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;语法&lt;/h3&gt;
   &lt;ul&gt;
    &lt;li&gt;用两个空格来代替制表符（tab） — 这是唯一能保证在所有环境下获得一致展现的方法。&lt;/li&gt;
    &lt;li&gt;为选择器分组时，将单独的选择器单独放在一行。&lt;/li&gt;
    &lt;li&gt;为了代码的易读性，在每个声明块的左花括号前添加一个空格。&lt;/li&gt;
    &lt;li&gt;声明块的右花括号应当单独成行。&lt;/li&gt;
    &lt;li&gt;每条声明语句的      &lt;code&gt;:&lt;/code&gt; 后应该插入一个空格。&lt;/li&gt;
    &lt;li&gt;为了获得更准确的错误报告，每条声明都应该独占一行。&lt;/li&gt;
    &lt;li&gt;所有声明语句都应当以分号结尾。最后一条声明语句后面的分号是可选的，但是，如果省略这个分号，你的代码可能更易出错。&lt;/li&gt;
    &lt;li&gt;对于以逗号分隔的属性值，每个逗号后面都应该插入一个空格（例如，     &lt;code&gt;box-shadow&lt;/code&gt;）。&lt;/li&gt;
    &lt;li&gt;不要在      &lt;code&gt;rgb()&lt;/code&gt;、     &lt;code&gt;rgba()&lt;/code&gt;、     &lt;code&gt;hsl()&lt;/code&gt;、     &lt;code&gt;hsla()&lt;/code&gt; 或      &lt;code&gt;rect()&lt;/code&gt;值的     &lt;em&gt;内部&lt;/em&gt;的逗号后面插入空格。这样利于从多个属性值（既加逗号也加空格）中区分多个颜色值（只加逗号，不加空格）。&lt;/li&gt;
    &lt;li&gt;对于属性值或颜色参数，省略小于 1 的小数前面的 0 （例如，     &lt;code&gt;.5&lt;/code&gt; 代替      &lt;code&gt;0.5&lt;/code&gt;；     &lt;code&gt;-.5px&lt;/code&gt; 代替      &lt;code&gt;-0.5px&lt;/code&gt;）。&lt;/li&gt;
    &lt;li&gt;十六进制值应该全部小写，例如，     &lt;code&gt;#fff&lt;/code&gt;。在扫描文档时，小写字符易于分辨，因为他们的形式更易于区分。&lt;/li&gt;
    &lt;li&gt;尽量使用简写形式的十六进制值，例如，用      &lt;code&gt;#fff&lt;/code&gt; 代替     &lt;code&gt;#ffffff&lt;/code&gt;。&lt;/li&gt;
    &lt;li&gt;为选择器中的属性添加双引号，例如，     &lt;code&gt;input[type=&amp;quot;text&amp;quot;]&lt;/code&gt;。     &lt;a href="http://mathiasbynens.be/notes/unquoted-attribute-values#css"&gt;只有在某些情况下是可选的&lt;/a&gt;，但是，为了代码的一致性，建议都加上双引号。&lt;/li&gt;
    &lt;li&gt;避免为 0 值指定单位，例如，用      &lt;code&gt;margin: 0;&lt;/code&gt; 代替     &lt;code&gt;margin: 0px;&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
   &lt;p&gt;对于这里用到的术语有疑问吗？请参考 Wikipedia 上的    &lt;a href="http://en.wikipedia.org/wiki/Cascading_Style_Sheets#Syntax"&gt;syntax section of the Cascading Style Sheets article&lt;/a&gt;。&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;/* Bad CSS */
.selector, .selector-secondary, .selector[type=text] {
  padding:15px;
  margin:0px 0px 15px;
  background-color:rgba(0, 0, 0, 0.5);
  box-shadow:0px 1px 2px #CCC,inset 0 1px 0 #FFFFFF
}

/* Good CSS */
.selector,
.selector-secondary,
.selector[type=&amp;quot;text&amp;quot;] {
  padding: 15px;
  margin-bottom: 15px;
  background-color: rgba(0,0,0,.5);
  box-shadow: 0 1px 2px #ccc, inset 0 1px 0 #fff;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;声明顺序&lt;/h3&gt;
   &lt;p&gt;相关的属性声明应当归为一组，并按照下面的顺序排列：&lt;/p&gt;
   &lt;ol&gt;
    &lt;li&gt;Positioning&lt;/li&gt;
    &lt;li&gt;Box model&lt;/li&gt;
    &lt;li&gt;Typographic&lt;/li&gt;
    &lt;li&gt;Visual&lt;/li&gt;
&lt;/ol&gt;
   &lt;p&gt;由于定位（positioning）可以从正常的文档流中移除元素，并且还能覆盖盒模型（box model）相关的样式，因此排在首位。盒模型排在第二位，因为它决定了组件的尺寸和位置。&lt;/p&gt;
   &lt;p&gt;其他属性只是影响组件的    &lt;em&gt;内部（inside）&lt;/em&gt;或者是不影响前两组属性，因此排在后面。&lt;/p&gt;
   &lt;p&gt;完整的属性列表及其排列顺序请参考     &lt;a href="http://twitter.github.com/recess"&gt;Recess&lt;/a&gt;。&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;.declaration-order {
  /* Positioning */
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 100;

  /* Box-model */
  display: block;
  float: right;
  width: 100px;
  height: 100px;

  /* Typography */
  font: normal 13px &amp;quot;Helvetica Neue&amp;quot;, sans-serif;
  line-height: 1.5;
  color: #333;
  text-align: center;

  /* Visual */
  background-color: #f5f5f5;
  border: 1px solid #e5e5e5;
  border-radius: 3px;

  /* Misc */
  opacity: 1;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;不要使用     &lt;code&gt;@import&lt;/code&gt;&lt;/h3&gt;
   &lt;p&gt;与     &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; 标签相比，    &lt;code&gt;@import&lt;/code&gt; 指令要慢很多，不光增加了额外的请求次数，还会导致不可预料的问题。替代办法有以下几种：&lt;/p&gt;
   &lt;ul&gt;
    &lt;li&gt;使用多个      &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; 元素&lt;/li&gt;
    &lt;li&gt;通过 Sass 或 Less 类似的 CSS 预处理器将多个 CSS 文件编译为一个文件&lt;/li&gt;
    &lt;li&gt;通过 Rails、Jekyll 或其他系统中提供过 CSS 文件合并功能&lt;/li&gt;
&lt;/ul&gt;
   &lt;p&gt;请参考     &lt;a href="http://www.stevesouders.com/blog/2009/04/09/dont-use-import/"&gt;Steve Souders 的文章&lt;/a&gt;了解更多知识。&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;&amp;lt;!-- Use link elements --&amp;gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;core.      &lt;a href="http://www.shtion.com/tag/css" target="_blank" title="&amp;#26597;&amp;#30475;css&amp;#20013;&amp;#30340;&amp;#20840;&amp;#37096;&amp;#25991;&amp;#31456;"&gt;css&lt;/a&gt;&amp;quot;&amp;gt;

&amp;lt;!-- Avoid @imports --&amp;gt;
&amp;lt;style&amp;gt;
  @import url(&amp;quot;more.      &lt;a href="http://www.shtion.com/tag/css" target="_blank" title="&amp;#26597;&amp;#30475;css&amp;#20013;&amp;#30340;&amp;#20840;&amp;#37096;&amp;#25991;&amp;#31456;"&gt;css&lt;/a&gt;&amp;quot;);
&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;媒体查询（Media query）的位置&lt;/h3&gt;
   &lt;p&gt;将媒体查询放在尽可能相关规则的附近。不要将他们打包放在一个单一样式文件中或者放在文档底部。如果你把他们分开了，将来只会被大家遗忘。下面给出一个典型的实例。&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;.element { ... }
.element-avatar { ... }
.element-selected { ... }

@media (min-width: 480px) {
  .element { ...}
  .element-avatar { ... }
  .element-selected { ... }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;带前缀的属性&lt;/h3&gt;
   &lt;p&gt;当使用特定厂商的带有前缀的属性时，通过缩进的方式，让每个属性的值在垂直方向对其，这样便于多行编辑。&lt;/p&gt;
   &lt;p&gt;在 Textmate 中，使用     &lt;strong&gt;Text → Edit Each Line in Selection&lt;/strong&gt;(⌃⌘A)。在 Sublime Text 2 中，使用     &lt;strong&gt;Selection → Add Previous Line&lt;/strong&gt; (⌃⇧↑) 和     &lt;strong&gt;Selection → Add Next Line&lt;/strong&gt;(⌃⇧↓)。&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;/* Prefixed properties */
.selector {
  -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15);
          box-shadow: 0 1px 2px rgba(0,0,0,.15);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;单行规则声明&lt;/h3&gt;
   &lt;p&gt;对于    &lt;strong&gt;只包含一条声明&lt;/strong&gt;的样式，为了易读性和便于快速编辑，建议将语句放在同一行。对于带有多条声明的样式，还是应当将声明分为多行。&lt;/p&gt;
   &lt;p&gt;这样做的关键因素是为了错误检测 — 例如，CSS 校验器指出在 183 行有语法错误。如果是单行声明，你就不会忽略这个错误；如果是多行声明的话，你就要仔细分析了。&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;/* Single declarations on one line */
.span1 { width: 60px; }
.span2 { width: 140px; }
.span3 { width: 220px; }

/* Multiple declarations, one per line */
.sprite {
  display: inline-block;
  width: 16px;
  height: 15px;
  background-image: url(../img/sprite.png);
}
.icon           { background-position: 0 0; }
.icon-home      { background-position: 0 -20px; }
.icon-account   { background-position: 0 -40px; }
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;简写形式的属性声明&lt;/h3&gt;
   &lt;p&gt;在需要显示地设置所有值的情况下，应当尽量限制使用简写形式的属性声明。常见的滥用简写属性声明的情况如下：&lt;/p&gt;
   &lt;ul&gt;
    &lt;li&gt;     &lt;code&gt;padding&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;code&gt;margin&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;code&gt;font&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;code&gt;background&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;code&gt;border&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;code&gt;border-radius&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
   &lt;p&gt;大部分情况下，我们不需要为简写形式的属性声明指定所有值。例如，HTML 的 heading 元素只需要设置上、下边距（margin）的值，因此，在必要的时候，只需覆盖这两个值就可以。过度使用简写形式的属性声明会导致代码混乱，并且会对属性值带来不必要的覆盖从而引起意外的副作用。&lt;/p&gt;
   &lt;p&gt;MDN（Mozilla Developer Network）上一片非常好的关于    &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties"&gt;shorthand properties&lt;/a&gt; 的文章，对于不太熟悉简写属性声明及其行为的用户很有用。&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;/* Bad example */
.element {
  margin: 0 0 10px;
  background: red;
  background: url(&amp;quot;image.jpg&amp;quot;);
  border-radius: 3px 3px 0 0;
}

/* Good example */
.element {
  margin-bottom: 10px;
  background-color: red;
  background-image: url(&amp;quot;image.jpg&amp;quot;);
  border-top-left-radius: 3px;
  border-top-right-radius: 3px;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;Less 和 Sass 中的嵌套&lt;/h3&gt;
   &lt;p&gt;避免非必要的嵌套。这是因为虽然你可以使用嵌套，但是并不意味着应该使用嵌套。只有在必须将样式限制在父元素内（也就是后代选择器），并且存在多个需要嵌套的元素时才使用嵌套。&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;// Without nesting
.table &amp;gt; thead &amp;gt; tr &amp;gt; th { … }
.table &amp;gt; thead &amp;gt; tr &amp;gt; td { … }

// With nesting
.table &amp;gt; thead &amp;gt; tr {
  &amp;gt; th { … }
  &amp;gt; td { … }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;注释&lt;/h3&gt;
   &lt;p&gt;代码是由人编写并维护的。请确保你的代码能够自描述、注释良好并且易于他人理解。好的代码注释能够传达上下文关系和代码目的。不要简单地重申组件或 class 名称。&lt;/p&gt;
   &lt;p&gt;对于较长的注释，务必书写完整的句子；对于一般性注解，可以书写简洁的短语。&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;/* Bad example */
/* Modal header */
.modal-header {
  ...
}

/* Good example */
/* Wrapping element for .modal-title and .modal-close */
.modal-header {
  ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;class 命名&lt;/h3&gt;
   &lt;ul&gt;
    &lt;li&gt;class 名称中只能出现小写字符和破折号（dashe）（不是下划线，也不是驼峰命名法）。破折号应当用于相关 class 的命名（类似于命名空间）（例如，     &lt;code&gt;.btn&lt;/code&gt; 和     &lt;code&gt;.btn-danger&lt;/code&gt;）。&lt;/li&gt;
    &lt;li&gt;避免过度任意的简写。     &lt;code&gt;.btn&lt;/code&gt; 代表      &lt;em&gt;button&lt;/em&gt;，但是      &lt;code&gt;.s&lt;/code&gt; 不能表达任何意思。&lt;/li&gt;
    &lt;li&gt;class 名称应当尽可能短，并且意义明确。&lt;/li&gt;
    &lt;li&gt;使用有意义的名称。使用有组织的或目的明确的名称，不要使用表现形式（presentational）的名称。&lt;/li&gt;
    &lt;li&gt;基于最近的父 class 或基本（base） class 作为新 class 的前缀。&lt;/li&gt;
    &lt;li&gt;使用      &lt;code&gt;.js-*&lt;/code&gt; class 来标识行为（与样式相对），并且不要将这些 class 包含到 CSS 文件中。&lt;/li&gt;
&lt;/ul&gt;
   &lt;p&gt;在为 Sass 和 Less 变量命名是也可以参考上面列出的各项规范。&lt;/p&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;/* Bad example */
.t { ... }
.red { ... }
.header { ... }

/* Good example */
.tweet { ... }
.important { ... }
.tweet-header { ... }
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;选择器&lt;/h3&gt;
   &lt;ul&gt;
    &lt;li&gt;对于通用元素使用 class ，这样利于渲染性能的优化。&lt;/li&gt;
    &lt;li&gt;对于经常出现的组件，避免使用属性选择器（例如，     &lt;code&gt;[class^=&amp;quot;...&amp;quot;]&lt;/code&gt;）。浏览器的性能会受到这些因素的影响。&lt;/li&gt;
    &lt;li&gt;选择器要尽可能短，并且尽量限制组成选择器的元素个数，建议不要超过 3 。&lt;/li&gt;
    &lt;li&gt;     &lt;strong&gt;只有&lt;/strong&gt;在必要的时候才将 class 限制在最近的父元素内（也就是后代选择器）（例如，不使用带前缀的 class 时 — 前缀类似于命名空间）。&lt;/li&gt;
&lt;/ul&gt;
   &lt;p&gt;扩展阅读：&lt;/p&gt;
   &lt;ul&gt;
    &lt;li&gt;     &lt;a href="http://markdotto.com/2012/02/16/scope-css-classes-with-prefixes/"&gt;Scope CSS classes with prefixes&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;a href="http://markdotto.com/2012/03/02/stop-the-cascade/"&gt;Stop the cascade&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;/* Bad example */
span { ... }
.page-container #stream .stream-item .tweet .tweet-header .username { ... }
.avatar { ... }

/* Good example */
.avatar { ... }
.tweet-header .username { ... }
.tweet .avatar { ... }
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;代码组织&lt;/h3&gt;
   &lt;ul&gt;
    &lt;li&gt;以组件为单位组织代码段。&lt;/li&gt;
    &lt;li&gt;制定一致的注释规范。&lt;/li&gt;
    &lt;li&gt;使用一致的空白符将代码分隔成块，这样利于扫描较大的文档。&lt;/li&gt;
    &lt;li&gt;如果使用了多个 CSS 文件，将其按照组件而非页面的形式分拆，因为页面会被重组，而组件只会被移动。&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;div&gt;
   &lt;div&gt;
    &lt;pre&gt;     &lt;code&gt;/*
 * Component section heading
 */

.element { ... }

/*
 * Component section heading
 *
 * Sometimes you need to include optional context for the entire component. Do that up here if it&amp;apos;s important enough.
 */

.element { ... }

/* Contextual sub-component or modifer */
.element-heading { ... }
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;编辑器配置&lt;/h3&gt;
   &lt;p&gt;将你的编辑器按照下面的配置进行设置，以避免常见的代码不一致和差异：&lt;/p&gt;
   &lt;ul&gt;
    &lt;li&gt;用两个空格代替制表符（soft-tab 即用空格代表 tab 符）。&lt;/li&gt;
    &lt;li&gt;保存文件时，删除尾部的空白符。&lt;/li&gt;
    &lt;li&gt;设置文件编码为 UTF-8。&lt;/li&gt;
    &lt;li&gt;在文件结尾添加一个空白行。&lt;/li&gt;
&lt;/ul&gt;
   &lt;p&gt;参照文档并将这些配置信息添加到项目的     &lt;code&gt;.editorconfig&lt;/code&gt; 文件中。例如：    &lt;a href="https://github.com/twbs/bootstrap/blob/master/.editorconfig"&gt;Bootstrap 中的 .editorconfig 实例&lt;/a&gt;。更多信息请参考     &lt;a href="http://editorconfig.org/"&gt;about EditorConfig&lt;/a&gt;。&lt;/p&gt;
   &lt;p&gt;文章来自：    &lt;a href="http://lisizhang.com/author/admin/" title="&amp;#26597;&amp;#30475;&amp;#33853;&amp;#33457;&amp;#29983;&amp;#25152;&amp;#26377;&amp;#25991;&amp;#31456;"&gt;落花生&lt;/a&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

 &lt;div&gt;  &lt;div&gt;   &lt;h3&gt;以下这些跟本文相关的文章链接或许对您有帮助：&lt;/h3&gt;   &lt;ul&gt;    &lt;li&gt;     &lt;a href="http://www.shtion.com/631.html"&gt;      &lt;img alt="IE6, IE7, IE8 CSS &amp;#20860;&amp;#23481;&amp;#36895;&amp;#26597;&amp;#34920;" height="150" src="http://www.shtion.com/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/3.jpg" width="150"&gt;&lt;/img&gt;&lt;/a&gt;     &lt;small&gt;2009/10/18&lt;/small&gt;      &lt;a href="http://www.shtion.com/631.html"&gt;IE6, IE7, IE8 CSS 兼容速查表&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;     &lt;a href="http://www.shtion.com/6331.html"&gt;      &lt;img alt="&amp;#22914;&amp;#20309;&amp;#31105;&amp;#29992; WordPress &amp;#35780;&amp;#35770;&amp;#37324;&amp;#30340;HTML&amp;#26631;&amp;#35760;&amp;#65311;" height="150" src="http://www.shtion.com/wp-content/uploads/shtion-html-biaoji-150x150.gif" width="150"&gt;&lt;/img&gt;&lt;/a&gt;     &lt;small&gt;2011/05/08&lt;/small&gt;      &lt;a href="http://www.shtion.com/6331.html"&gt;如何禁用 WordPress 评论里的HTML标记？&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;     &lt;a href="http://www.shtion.com/3633.html"&gt;      &lt;img alt="&amp;#32473;HTML5&amp;#30340;&amp;#24314;&amp;#35758;&amp;#12289;HTML5&amp;#30340;&amp;#25216;&amp;#24039;&amp;#21644;&amp;#25216;&amp;#26415;" height="150" src="http://www.shtion.com/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/30.jpg" width="150"&gt;&lt;/img&gt;&lt;/a&gt;     &lt;small&gt;2010/07/21&lt;/small&gt;      &lt;a href="http://www.shtion.com/3633.html"&gt;给HTML5的建议、HTML5的技巧和技术&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;     &lt;a href="http://www.shtion.com/3060.html"&gt;      &lt;img alt="&amp;#27983;&amp;#35272;&amp;#22120;&amp;#20043;&amp;#25112;&amp;#23558;&amp;#36827;&amp;#20837;HTML5&amp;#26102;&amp;#20195;" height="150" src="http://www.shtion.com/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/19.jpg" width="150"&gt;&lt;/img&gt;&lt;/a&gt;     &lt;small&gt;2010/04/14&lt;/small&gt;      &lt;a href="http://www.shtion.com/3060.html"&gt;浏览器之战将进入HTML5时代&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;     &lt;a href="http://www.shtion.com/9851.html"&gt;      &lt;img alt="&amp;#20160;&amp;#20040;&amp;#26159; HTML 5 &amp;#65311;" height="150" src="http://www.shtion.com/wp-content/uploads/shtion-html5-use-150x150.png" width="150"&gt;&lt;/img&gt;&lt;/a&gt;     &lt;small&gt;2011/07/21&lt;/small&gt;      &lt;a href="http://www.shtion.com/9851.html"&gt;什么是 HTML 5 ？&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;     &lt;a href="http://www.shtion.com/3324.html"&gt;      &lt;img alt="30&amp;#20010;&amp;#32473;&amp;#32593;&amp;#39029;&amp;#35774;&amp;#35745;&amp;#24072;&amp;#30340;HTML5&amp;#23398;&amp;#20064;&amp;#36164;&amp;#28304;" height="150" src="http://www.shtion.com/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/7.jpg" width="150"&gt;&lt;/img&gt;&lt;/a&gt;     &lt;small&gt;2010/06/06&lt;/small&gt;      &lt;a href="http://www.shtion.com/3324.html"&gt;30个给网页设计师的HTML5学习资源&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;     &lt;a href="http://www.shtion.com/2366.html"&gt;      &lt;img alt="&amp;#24320;&amp;#21457;&amp;#32773;&amp;#23545;HTML5&amp;#26377;&amp;#20160;&amp;#20040;&amp;#26399;&amp;#24453;&amp;#65311;" height="150" src="http://www.shtion.com/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/28.jpg" width="150"&gt;&lt;/img&gt;&lt;/a&gt;     &lt;small&gt;2010/03/09&lt;/small&gt;      &lt;a href="http://www.shtion.com/2366.html"&gt;开发者对HTML5有什么期待？&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>html5 css HTML</category>
      <guid isPermaLink="true">https://itindex.net/detail/48755-html-css-%E4%BB%A3%E7%A0%81</guid>
      <pubDate>Thu, 27 Mar 2014 16:59:58 CST</pubDate>
    </item>
    <item>
      <title>可以从CSS框架中借鉴到什么</title>
      <link>https://itindex.net/detail/46068-css-%E6%A1%86%E6%9E%B6</link>
      <description>&lt;p&gt;现在很多人会使用 CSS 框架进行快速建站，  &lt;br /&gt;
那 CSS 框架是什么呢，它通常是一些 CSS 文件的集合，这些文件包括基本布局、表单样式、网格、简单组件、以及样式重置。使用 CSS 框架大大降低工作成本进行快速建站。  &lt;br /&gt;
当然对于一些大型的项目，可能会很难照搬某些框架直接使用的，因为直接使用会带来一些限制或者冗余的问题。  &lt;br /&gt;
但在 CSS 框架已经日趋成熟的今天，在我们设计项目架构、规范的时候，现时市面上一些优秀的框架也可以给我们提供很多可借鉴的地方。&lt;/p&gt;
 &lt;p&gt;本文主要从几个方面讨论 CSS 框架可以对我们项目的借鉴点：  &lt;br /&gt;
1. 目录组织  &lt;br /&gt;
2. CSS 规范  &lt;br /&gt;
3. 图形  &lt;br /&gt;
4. 应用方式  &lt;br /&gt;
5. 小建议&lt;/p&gt;
 &lt;p&gt;&lt;/p&gt;
 &lt;h1&gt;1. 目录组织&lt;/h1&gt;
 &lt;p&gt;在目录组织的分析上我们参考了 Bootstrap , Blueprint , Yui , Yaml 四个框架的组织方式&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://isux.tencent.com/wp-content/uploads/2013/10/20131015210145631.png" target="_blank"&gt;   &lt;img alt="&amp;#21487;&amp;#20197;&amp;#20174;CSS&amp;#26694;&amp;#26550;&amp;#20013;&amp;#20511;&amp;#37492;&amp;#21040;&amp;#20160;&amp;#20040;" height="1300" src="http://isux.tencent.com/wp-content/uploads/2013/10/20131015210145631.png" width="590"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p align="left"&gt;当使用一个框架时，我们一般会把所需框架本身的样式链到页面中，然后在它的基础上进行修改。所以框架本身所带的样式可以理解为基础样式。即我们平时所说的全局样式+组件样式。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://isux.tencent.com/wp-content/uploads/2013/10/20131015175052563.png" target="_blank"&gt;   &lt;img alt="&amp;#21487;&amp;#20197;&amp;#20174;CSS&amp;#26694;&amp;#26550;&amp;#20013;&amp;#20511;&amp;#37492;&amp;#21040;&amp;#20160;&amp;#20040;" height="239" src="http://isux.tencent.com/wp-content/uploads/2013/10/20131015175052563.png" width="591"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p align="left"&gt;可以看到，在目录架构上4个框架基本都是遵循基本样式+用户定义扩展样式的常规方式进行组织，&lt;/p&gt;
 &lt;p align="left"&gt;然而，如果按 Bootstrap 做法的话，可能会出现把不常用组件样式也包含在全局样式中一并引入，如果把组件也写在全局 CSS 中，最好确保该组件出现频率较高才引入，避免不必要的带宽浪费。&lt;/p&gt;
 &lt;p align="left"&gt;  &lt;strong&gt;关于 hack：&lt;/strong&gt;  &lt;br /&gt;
对于针对低版本浏览器所写的 hack，对它的处理方式，Blueprint 和 Yaml 都是使用单独引入 hack 文件的形式进行处理，笔者也尝试过这样的做法。  &lt;br /&gt;
个人觉得这种方式的好处是可以避免给高级浏览器带来冗余代码，而且通过条件判断引入 CSS 也不会给高级浏览器带来额外的请求。&lt;/p&gt;
 &lt;p align="left"&gt;这种方式比较适用于，高低级浏览器本来就刻意设计成有较大差别的情况下，即 hack 比较多的时候才使用。不然就为了十来行 hack 而多引入一个文件的话似乎也不太可取。&lt;/p&gt;
 &lt;h1&gt;2. CSS 规范&lt;/h1&gt;
 &lt;h2&gt;a. 前缀&lt;/h2&gt;
 &lt;p align="left"&gt;框架中公用模块都有前缀，分别有以下3个思想：  &lt;br /&gt;
1. Yaml , Yui ：无论如何都是统一的标识开头，再加上改模块名称  &lt;br /&gt;
2. Bootstrap：直接模块名称，这方式需要定义关键字。公用模块是 button 都以 btn – 开头， image 则以 img- 开头。  &lt;br /&gt;
3. Nec ：单字母开头来标识组件。&lt;/p&gt;
 &lt;p align="left"&gt;  &lt;a href="http://isux.tencent.com/wp-content/uploads/2013/10/20131015181252118.png" target="_blank"&gt;   &lt;img alt="&amp;#21487;&amp;#20197;&amp;#20174;CSS&amp;#26694;&amp;#26550;&amp;#20013;&amp;#20511;&amp;#37492;&amp;#21040;&amp;#20160;&amp;#20040;" height="134" src="http://isux.tencent.com/wp-content/uploads/2013/10/20131015181252118.png" width="496"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p align="left"&gt;一般来说应用一个框架，我们先引入框架的样式，再在之上覆盖上自己的样式，所以可以把框架看作是我们的基础CSS，&lt;/p&gt;
 &lt;p align="left"&gt;我们可以借鉴框架的前缀规范来规划我们的基础 CSS 前缀，根据自己的项目实际情况采取不同的方案。&lt;/p&gt;
 &lt;h2&gt;b. 类的划分&lt;/h2&gt;
 &lt;p align="left"&gt;类的划分方式在框架中主要有2种标准，分别为：以【组件为粒度】，和以【属性为粒度】&lt;/p&gt;
 &lt;p align="left"&gt;1.   &lt;strong&gt;组件为粒度&lt;/strong&gt;：把组件的所有样式封装在一个类名中，调用类名即可使用该组件  &lt;br /&gt;
2.   &lt;strong&gt;属性为粒度&lt;/strong&gt;：需要属性的时候，调用对应类名拼装&lt;/p&gt;
 &lt;p align="left"&gt;  &lt;a href="http://isux.tencent.com/wp-content/uploads/2013/10/20131015183427649.png" target="_blank"&gt;   &lt;img alt="&amp;#21487;&amp;#20197;&amp;#20174;CSS&amp;#26694;&amp;#26550;&amp;#20013;&amp;#20511;&amp;#37492;&amp;#21040;&amp;#20160;&amp;#20040;" height="104" src="http://isux.tencent.com/wp-content/uploads/2013/10/20131015183427649.png" width="582"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p align="left"&gt;在我们日常项目中，以属性对类名进行划分比较少见，因为一直遵循的都是“结构、样式、行为”分离的原则，力求降低三者的耦合度，&lt;/p&gt;
 &lt;p align="left"&gt;然而以这种方式划分在一些特定情况下也不是完全不可取，&lt;/p&gt;
 &lt;p align="left"&gt;例如对于一些元素的隐藏，如果没提供相关的类名的话，在js开发阶段开发就会直接内联 style 在对应的元素上（这将会触发 repaint/reflow），所以更好的方式是和js开发约定一个类名触发显示/隐藏的动作，在这种情况下，给 display: none 划分一个特定的类名，供给开发调用就会显得很实用了。&lt;/p&gt;
 &lt;p align="left"&gt;所以，更重要的是我们对所在的实际情况进行分析，并给出最佳的解决方案。&lt;/p&gt;
 &lt;h2&gt;c. 组件类名组合方式&lt;/h2&gt;
 &lt;p align="left"&gt;组件的样式，基本都是 基础类名+扩展类名 的套路来进行组合的变化。&lt;/p&gt;
 &lt;p align="left"&gt;但在选择符方面可以有3种方式， 目前最多框架使用的是：多类选择，通过修改 html 的类名组合，实现还原&lt;/p&gt;
 &lt;p align="left"&gt;以按钮样式的实现为例：  &lt;br /&gt;
  &lt;a href="http://isux.tencent.com/wp-content/uploads/2013/10/20131015193742291.png" target="_blank"&gt;   &lt;img alt="&amp;#21487;&amp;#20197;&amp;#20174;CSS&amp;#26694;&amp;#26550;&amp;#20013;&amp;#20511;&amp;#37492;&amp;#21040;&amp;#20160;&amp;#20040;" height="167" src="http://isux.tencent.com/wp-content/uploads/2013/10/20131015193742291.png" width="591"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;这里采用常规的组合方式，不再赘述&lt;/p&gt;
 &lt;h2&gt;d. 高级 CSS 选择器&lt;/h2&gt;
 &lt;p align="left"&gt;在对 Bootstrap 进行分析的过程中，发现 Bootstrap 定义了一系列的icon，这些 icon 的类名全部都是以 icon- 为前缀，&lt;/p&gt;
 &lt;p align="left"&gt;而在 CSS 中，Bootstrap 用到了子串匹配属性选择器，&lt;/p&gt;
 &lt;p align="left"&gt;  &lt;em&gt;[class^=&amp;quot;icon-&amp;quot;]&lt;/em&gt;&lt;/p&gt;
 &lt;p align="left"&gt;使用这个的好处是，对于 icon 类的标签，我们再也不需要对其加一个对于 icon 的公用类名，只需要类名是以 icon- 开头就可以匹配所有 icon ，省了一个类名。&lt;/p&gt;
 &lt;p align="left"&gt;使用这种方式可以降低一定的成本，但是只在 IE7+ 浏览器才适用，如果要使用该类选择器的话请考虑是否需要兼容 IE6。  &lt;br /&gt;
虽然 IE6 不支持，但是高级 CSS 选择器的确十分吸引，并且可用于移动端，所以特此提一下。&lt;/p&gt;
 &lt;h1&gt;3. 图形&lt;/h1&gt;
 &lt;p align="left"&gt;在参考的 CSS 框架中，它们会提供一些简单的图形元素， 但是实现的方式也有彼此不同之处。&lt;/p&gt;
 &lt;p align="left"&gt;但是共同点是，现今较新的框架，对于一些简单的效果，都会使用 CSS3 实现一些简单的渐变，对低版本 IE 进行优雅降级。&lt;/p&gt;
 &lt;p align="left"&gt;  &lt;a href="http://isux.tencent.com/wp-content/uploads/2013/10/20131015202527468.png" target="_blank"&gt;   &lt;img alt="&amp;#21487;&amp;#20197;&amp;#20174;CSS&amp;#26694;&amp;#26550;&amp;#20013;&amp;#20511;&amp;#37492;&amp;#21040;&amp;#20160;&amp;#20040;" height="361" src="http://isux.tencent.com/wp-content/uploads/2013/10/20131015202527468.png" width="590"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;h1&gt;4. 应用方式&lt;/h1&gt;
 &lt;p align="left"&gt;在参考实例是怎样使用这些框架的方式上，基本和我们平时项目使用方式一致，&lt;/p&gt;
 &lt;p align="left"&gt;在应用方式上，一般有两种方式：&lt;/p&gt;
 &lt;p align="left"&gt;1. 对于以组件为粒度的样式：  &lt;br /&gt;
按照 组件的 html 结构 来拼合自己的页面模块，再辅助添加 自定义的类名 来控制其个性化定义。&lt;/p&gt;
 &lt;p&gt;2. 对于以属性为粒度的样式：  &lt;br /&gt;
按所需要的样式对应类名进行拼接&lt;/p&gt;
 &lt;p align="left"&gt;下面可以看几个简单的例子，&lt;/p&gt;
 &lt;p align="left"&gt;1. 以组件为粒度：  &lt;br /&gt;
对于组件的覆盖，采取常规的自定义类名覆盖样式，此处不再赘述&lt;/p&gt;
 &lt;p align="left"&gt;2. 以属性为粒度：  &lt;br /&gt;
  &lt;a href="http://isux.tencent.com/wp-content/uploads/2013/10/20131016180458109.png" target="_blank"&gt;   &lt;img alt="&amp;#21487;&amp;#20197;&amp;#20174;CSS&amp;#26694;&amp;#26550;&amp;#20013;&amp;#20511;&amp;#37492;&amp;#21040;&amp;#20160;&amp;#20040;" height="171" src="http://isux.tencent.com/wp-content/uploads/2013/10/20131016180458109.png" width="590"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p align="left"&gt;可以看到，若需要样式是属性以粒度，即把对应类名调入即可，但是在实际项目中，这种方式由于灵活度不够，并且没有做到结构与样式分离，实际项目中比较少见这种用法。&lt;/p&gt;
 &lt;p align="left"&gt;而对于功能性的动作，例如显示/隐藏元素，可以灵活使用这种方式，把所需样式写到一个特定类名中供给js调用，避免直接写入 style 导致 reflow/repaint&lt;/p&gt;
 &lt;h1&gt;5. 小建议&lt;/h1&gt;
 &lt;h2&gt;对于目录组织：&lt;/h2&gt;
 &lt;h3&gt;目录组织——&lt;/h3&gt;
 &lt;p align="left"&gt;可以考虑结合 Bootstrap 与 Yaml/Blueprint 的思想，&lt;/p&gt;
 &lt;p align="left"&gt;a .把常用的基础样式压缩合成一个文件  &lt;br /&gt;
b. 把不必现组件样式抽离成单独 CSS，按需加载&lt;/p&gt;
 &lt;p align="left"&gt;【优化点】  &lt;br /&gt;
减少了单个 global_min 文件的大小&lt;/p&gt;
 &lt;p align="left"&gt;权衡点：  &lt;br /&gt;
需要考虑由此可能导致的请求数过多问题&lt;/p&gt;
 &lt;h3&gt;hack——&lt;/h3&gt;
 &lt;p align="left"&gt;根据实际情况，可考虑把针对 IE6 的 hack 文件单独分出来，&lt;/p&gt;
 &lt;p align="left"&gt;【优化点】  &lt;br /&gt;
便于对低级浏览器的大型差异化处理，并且减少对于高级浏览器的冗余代码&lt;/p&gt;
 &lt;h2&gt;对于 CSS 规范：&lt;/h2&gt;
 &lt;h3&gt;CSS 前缀——&lt;/h3&gt;
 &lt;p align="left"&gt;可考虑尝试 Nec 的方式，约定 “单字母_xxx”为公用样式的标识，取消单一的公用前缀，通过以不同字母作为顶级前缀，对公用模块进行划分&lt;/p&gt;
 &lt;p align="left"&gt;【优化点】  &lt;br /&gt;
减免了“公用前缀_组件前缀_组件名”的多级前缀，通过以类名格式作为标识，代替了原来公用前缀的作用。&lt;/p&gt;
 &lt;p align="left"&gt;权衡点：  &lt;br /&gt;
仍需按项目实际情况考虑。&lt;/p&gt;
 &lt;h3&gt;类的划分——&lt;/h3&gt;
 &lt;p align="left"&gt;可考虑约定统一几个功能性的类名（以属性为粒度的类名），例如元素隐藏的类名，供给js调用。&lt;/p&gt;
 &lt;p align="left"&gt;【优化点】  &lt;br /&gt;
减免让开发直接写 style 内联 CSS，造成页面的 reflow/repaint&lt;/p&gt;
 &lt;h3&gt;高级 CSS 选择器——&lt;/h3&gt;
 &lt;p align="left"&gt;在对移动端页面进行重构时可以考虑使用更高级的 CSS 选择器  &lt;br /&gt;
例： [class^=”icon”]，:first-child，:nth-child(n)….&lt;/p&gt;
 &lt;p align="left"&gt;【优化点】  &lt;br /&gt;
1. 相比于传统的方法，节省类名&lt;/p&gt;
 &lt;h2&gt;对于图形：&lt;/h2&gt;
 &lt;p align="left"&gt;考虑与设计师约定，视觉效果在可接受范围内，部分效果使用 CSS3 实现，对低级浏览器实现优雅降级&lt;/p&gt;
 &lt;p align="left"&gt;【优化点】  &lt;br /&gt;
1. 大量减少图片的使用，节省带宽以及请求数&lt;/p&gt;
 &lt;h1&gt;最后&lt;/h1&gt;
 &lt;p&gt;随着新技术的不断涌现，越来越多优秀的 CSS 框架出现在我们的眼前，这里分析覆盖面有限，未能一一进行对比并深入探索，如有不足之处，敬请大家多多指正交流。&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>前端技术 CSS</category>
      <guid isPermaLink="true">https://itindex.net/detail/46068-css-%E6%A1%86%E6%9E%B6</guid>
      <pubDate>Thu, 17 Oct 2013 13:55:45 CST</pubDate>
    </item>
    <item>
      <title>42个新鲜的开发人员资源素材</title>
      <link>https://itindex.net/detail/47035-%E6%96%B0%E9%B2%9C-%E5%BC%80%E5%8F%91-%E8%B5%84%E6%BA%90</link>
      <description>&lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools15.jpg"&gt;   &lt;img alt="newresourcestools15" height="428" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools15-495x428.jpg" title="newresourcestools15" width="495"&gt;&lt;/img&gt;&lt;/a&gt;  &lt;br /&gt;
对于开发和设计人员来说，很多时候接到项目后需要时刻和时间去做无形的赛跑。如何提高效率是每一次项目结束后大家都会讨论的热点问题之一。如何去接受和更多了解一些新工具或许是开启速度的钥匙。为了提高效率很多优秀的设计师和开发人员会在经历了一些项目后把经验演变成新的规则工具。后来者就可以站在前人的臂弯上去快速开始一些基础架构。让开发效率赢不断提高。今天要分享给大家的就是这样一些资源素材。相信你可以在这里找到你需要的好东西。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://drublic.github.io/css-modal/" target="_blank"&gt;CSS Modal&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;CSS Modal is built out of pure CSS. JavaScript is only for sugar. This makes them perfectly accessible. The modals are designed using responsive web design methods. They work on all screen sizes from a small mobile phone up to high resolution screens.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools1.jpg"&gt;   &lt;img alt="newresourcestools1" height="374" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools1-495x374.jpg" title="newresourcestools1" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://www.jshint.com/" target="_blank"&gt;JSHint&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;JSHint is a tool that helps to detect errors and potential problems in your JavaScript code. To start enter your JavaScript below and click the Lint button.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools23.jpg"&gt;   &lt;img alt="newresourcestools23" height="402" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools23-495x402.jpg" title="newresourcestools23" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://www.lighttable.com/" target="_blank"&gt;Light Table IDE&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Light Table is a new interactive IDE that lets you modify running programs and embed anything from websites to games. It provides the real time feedback we need to not only answer questions about our code, but to understand how our programs really work.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools40.jpg"&gt;   &lt;img alt="newresourcestools40" height="364" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools40-495x364.jpg" title="newresourcestools40" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://www.csstrashman.com/" target="_blank"&gt;CSS Trashman&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;The trashman examines your site’s live DOM and reverse engineers a new, more elegant definition that captures styles down to the pixel.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools2.jpg"&gt;   &lt;img alt="newresourcestools2" height="320" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools2-495x320.jpg" title="newresourcestools2" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://alphapixels.com/prepros/" target="_blank"&gt;Prepros&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Preprocessing just got easier with Prepros Enjoy the dead simple design &amp;amp; development workflow.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools3.jpg"&gt;   &lt;img alt="newresourcestools3" height="407" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools3-495x407.jpg" title="newresourcestools3" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://browserhacks.com/" target="_blank"&gt;Browserhacks&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Browserhacks is an extensive list of browser specific CSS and JavaScript hacks from all over the interwebs.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools4.jpg"&gt;   &lt;img alt="newresourcestools4" height="337" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools4-495x337.jpg" title="newresourcestools4" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://learnlayout.com/" target="_blank"&gt;Learn CSS Layout&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;This site teaches the CSS fundamentals that are used in any website’s layout.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools6.jpg"&gt;   &lt;img alt="newresourcestools6" height="346" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools6-495x346.jpg" title="newresourcestools6" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://kushagragour.in/lab/picssel-art/" target="_blank"&gt;PiCSSel-art&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;PiCSSel-art is a very useful drawing tool to draw pixel art and get it in CSS. Draw pixel art using CSS only.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools7.jpg"&gt;   &lt;img alt="newresourcestools7" height="389" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools7-495x389.jpg" title="newresourcestools7" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://mrcoles.com/demo/markdown-css/" target="_blank"&gt;Markdown.css&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;CSS to make HTML markup look like plain-text markdown.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools8.jpg"&gt;   &lt;img alt="newresourcestools8" height="418" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools8-495x418.jpg" title="newresourcestools8" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://jaymorrow.github.io/validatr/" target="_blank"&gt;Validatrn&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Cross Browser HTML5 Form Validation.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools9.jpg"&gt;   &lt;img alt="newresourcestools9" height="353" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools9-495x353.jpg" title="newresourcestools9" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://lessprefixer.com/" target="_blank"&gt;LESS Prefixer&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;LESS Prefixer is a set of LESS mixins that let you use vendor-prefixed CSS properties without the prefixes. It uses some simple conventions and gets out of the way so you can use the CSS you already know, but with less typing.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools10.jpg"&gt;   &lt;img alt="newresourcestools10" height="337" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools10-495x337.jpg" title="newresourcestools10" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://zmoazeni.github.io/csscss/" target="_blank"&gt;Csscss – A CSS Redundancy Analyze&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Csscss will parse any CSS files you give it and let you know which rulesets have duplicated declarations.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools11.jpg"&gt;   &lt;img alt="newresourcestools11" height="352" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools11-495x352.jpg" title="newresourcestools11" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://bem.info/tools/csso/" target="_blank"&gt;CSSO – Structural Optimization of CSS Files&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;CSSO (CSS Optimizer) is a CSS minimizer unlike others. In addition to usual minification techniques it can perform structural optimization of CSS files, resulting in smaller file size compared to other minifiers.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools12.jpg"&gt;   &lt;img alt="newresourcestools12" height="368" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools12-495x368.jpg" title="newresourcestools12" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://jslegers.github.io/cascadeframework/index.html" target="_blank"&gt;Cascade Framework&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Semantic and non-semantic grid layouts, base templates, table designs, navigation elements, typography and lots, lots more.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools13.jpg"&gt;   &lt;img alt="newresourcestools13" height="408" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools13-495x408.jpg" title="newresourcestools13" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://responsablecss.com/" target="_blank"&gt;Responsable Framework&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Responsable uses the power of less and sass to bring you a perfect responsive framework.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools14.jpg"&gt;   &lt;img alt="newresourcestools14" height="416" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools14-495x416.jpg" title="newresourcestools14" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://learn.jquery.com/" target="_blank"&gt;jQuery Learning Center&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;There’s a lot more to learn about building web sites and applications with jQuery than can fit in API documentation. If you’re looking for explanations of the basics, workarounds for common problems, best practices, and how-tos, you’re in the right place!&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools5.jpg"&gt;   &lt;img alt="newresourcestools5" height="324" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools5-495x324.jpg" title="newresourcestools5" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://muellergridsystem.com/" target="_blank"&gt;Mueller Grid System&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;MUELLER is a modular grid system for responsive/adaptive and non–responsive layouts, based on Compass. You have full control over column width, gutter width, baseline grid and media–queries.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools15.jpg"&gt;   &lt;img alt="newresourcestools15" height="428" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools15-495x428.jpg" title="newresourcestools15" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://purecss.io/" target="_blank"&gt;Pure&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;A set of small, responsive CSS modules that you can use in every web project.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools16.jpg"&gt;   &lt;img alt="newresourcestools16" height="292" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools16-495x292.jpg" title="newresourcestools16" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://arnaudleray.github.io/pocketgrid/" target="_blank"&gt;PocketGrid&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Tiny and powerful CSS grid system.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools17.jpg"&gt;   &lt;img alt="newresourcestools17" height="307" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools17-495x307.jpg" title="newresourcestools17" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://cferdinandi.github.io/kraken/" target="_blank"&gt;Kraken&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;A lightweight, mobile-first boilerplate for front-end web developers.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools18.jpg"&gt;   &lt;img alt="newresourcestools18" height="407" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools18-495x407.jpg" title="newresourcestools18" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://www.fitgrd.com/" target="_blank"&gt;.Fitgrid&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;.FITGRD is the lightweight &amp;amp; sexy looking responsive grid for your next awesome website.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools19.jpg"&gt;   &lt;img alt="newresourcestools19" height="355" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools19-495x355.jpg" title="newresourcestools19" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://valdelama.com/mosto/" target="_blank"&gt;Mosto Framework for Forms&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;A lightweight framework for forms.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools20.jpg"&gt;   &lt;img alt="newresourcestools20" height="434" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools20-495x434.jpg" title="newresourcestools20" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://typeplate.com/" target="_blank"&gt;Typeplate&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Frameworks make decisions for you about how to organize, structure and design a site. Pattern libraries don’t separate styling and markup, making them tough to use in a truly modular fashion. We weren’t satisfied, so we made a thing that doesn’t do that.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools21.jpg"&gt;   &lt;img alt="newresourcestools21" height="415" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools21-495x415.jpg" title="newresourcestools21" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://topcoat.io/" target="_blank"&gt;Topcoat&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;CSS for Clean &amp;amp; Fast Web Apps.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools22.jpg"&gt;   &lt;img alt="newresourcestools22" height="350" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools22-495x350.jpg" title="newresourcestools22" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://ricostacruz.com/flatdoc/" target="_blank"&gt;Flatdoc&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Flatdoc is the fastest way to create a site for your open source project.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools24.jpg"&gt;   &lt;img alt="newresourcestools24" height="392" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools24-495x392.jpg" title="newresourcestools24" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://www.svgjs.com/" target="_blank"&gt;svg.js&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;A lightweight library for manipulating and animating SVG.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools25.jpg"&gt;   &lt;img alt="newresourcestools25" height="396" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools25-495x396.jpg" title="newresourcestools25" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://shipp.co/midway/" target="_blank"&gt;Midway.js&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Midway.js makes it super easy to automatically center the responsive elements on your websites.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools26.jpg"&gt;   &lt;img alt="newresourcestools26" height="418" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools26-495x418.jpg" title="newresourcestools26" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://usablica.github.io/widearea/" target="_blank"&gt;WideArea&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;WideArea is simple and lightweight JavaScript and CSS library (2KB JS and 4KB CSS) which helps you to write better, simpler and faster.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools27.jpg"&gt;   &lt;img alt="newresourcestools27" height="357" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools27-495x357.jpg" title="newresourcestools27" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://jnordberg.github.io/gif.js/" target="_blank"&gt;Gif.js&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Full-featured JavaScript GIF encoder that runs in your browser.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools28.jpg"&gt;   &lt;img alt="newresourcestools28" height="374" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools28-495x374.jpg" title="newresourcestools28" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://radlikewhoa.github.io/Countable/" target="_blank"&gt;Countable.js&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Countable is a JavaScript function to add live paragraph-, word- and character-counting to an HTML element. Countable is a zero-dependency library and comes in at 1KB when minified and gzipped.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools29.jpg"&gt;   &lt;img alt="newresourcestools29" height="386" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools29-495x386.jpg" title="newresourcestools29" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://packery.metafizzy.co/" target="_blank"&gt;Packery&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Packery makes your crazy &amp;amp; clever layout a real thing. Be clever. Get crazy.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools30.jpg"&gt;   &lt;img alt="newresourcestools30" height="347" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools30-495x347.jpg" title="newresourcestools30" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://softwaremaniacs.org/soft/highlight/en/" target="_blank"&gt;Highlight.js&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Highlight.js highlights syntax in code examples on blogs, forums and in fact on any web pages. It’s very easy to use because it works automatically: finds blocks of code, detects a language, highlights it.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools31.jpg"&gt;   &lt;img alt="newresourcestools31" height="363" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools31-495x363.jpg" title="newresourcestools31" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://theintern.io/" target="_blank"&gt;Intern&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Intern takes the stress out of testing your Web app.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools32.jpg"&gt;   &lt;img alt="newresourcestools32" height="405" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools32-495x405.jpg" title="newresourcestools32" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://www.chartjs.org/" target="_blank"&gt;Chart.js&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Easy, object oriented client side graphs for designers and developers.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools33.jpg"&gt;   &lt;img alt="newresourcestools33" height="365" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools33-495x365.jpg" title="newresourcestools33" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://draggabilly.desandro.com/" target="_blank"&gt;Draggabilly&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Make that shiz draggable.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools34.jpg"&gt;   &lt;img alt="newresourcestools34" height="338" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools34-495x338.jpg" title="newresourcestools34" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://facebook.github.io/react/" target="_blank"&gt;React&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;A JavaScript library for building user interfaces.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools35.jpg"&gt;   &lt;img alt="newresourcestools35" height="327" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools35-495x327.jpg" title="newresourcestools35" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://pedestal.io/" target="_blank"&gt;Pedestal&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;An open source tool set for building web applications in Clojure.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools36.jpg"&gt;   &lt;img alt="newresourcestools36" height="403" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools36-495x403.jpg" title="newresourcestools36" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://helios.io/" target="_blank"&gt;Helios&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Helios is an open-source framework that provides essential backend services for iOS apps, from data synchronization and push notifications to in-app purchases and passbook integration. It allows developers to get a client-server app up-and-running in just a few minutes, and seamlessly incorporate functionality as necessary.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools37.jpg"&gt;   &lt;img alt="newresourcestools37" height="381" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools37-495x381.jpg" title="newresourcestools37" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://ndreckshage.github.io/roughdraft.js/" target="_blank"&gt;RoughDraft.js&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Quickly create and prototype a full interactive HTML mock-up without duplicating markup, server-side loops/code, or having to source fake content (lorem ipsum text/images).&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools38.jpg"&gt;   &lt;img alt="newresourcestools38" height="391" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools38-495x391.jpg" title="newresourcestools38" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://redpen.io/" target="_blank"&gt;Red Pen&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Red Pen lets you upload your design, share a short URL, and get live, annotated feedback super-fast. It remembers you— no project management, no complexity, no bullshit.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools39.jpg"&gt;   &lt;img alt="newresourcestools39" height="359" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools39-495x359.jpg" title="newresourcestools39" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://fakeimg.pl/" target="_blank"&gt;Fake Images Please?&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;When designing websites, you may not have the images you need at first. But you already know the sizes and inserting some placeholders can help you better seeing the layout. Don’t waste your time making dummy images for your mockup or wireframe. Fakeimg.pl is a little tool that generates images with an URL. Choose the size, the colors, even the text.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools41.jpg"&gt;   &lt;img alt="newresourcestools41" height="386" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools41-495x386.jpg" title="newresourcestools41" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;   &lt;a href="http://getpreboot.com/" target="_blank"&gt;Preboot&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Preboot is a comprehensive and flexible collection of LESS utilities. Its original variables and mixins became the precursor to Bootstrap. Since then, it’s all come full circle.&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools42.jpg"&gt;   &lt;img alt="newresourcestools42" height="311" src="http://www.jackchen.cn/blog/wp-content/uploads/2013/12/newresourcestools42-495x311.jpg" title="newresourcestools42" width="495"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.smashingapps.com/2013/11/18/42-fresh-tools-and-resources-for-developers-and-designers.html" target="_blank" title="42&amp;#20010;&amp;#26032;&amp;#40092;&amp;#30340;&amp;#24320;&amp;#21457;&amp;#20154;&amp;#21592;&amp;#36164;&amp;#28304;&amp;#32032;&amp;#26448;"&gt;   &lt;br /&gt;
Via&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://weibo.com/u/1646745652?s=6uyXnP" target="_blank"&gt;   &lt;br /&gt;
   &lt;img alt="" border="0" src="http://service.t.sina.com.cn/widget/qmd/1646745652/97235af6/1.png?rnd=1387032084611"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;table border="0" cellpadding="3" cellspacing="0"&gt;
    
      &lt;tr&gt;
           &lt;td colspan="4"&gt;    &lt;strong&gt;猜您也喜欢：&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    
          &lt;tr&gt;
                   &lt;td valign="top" width="102"&gt;
                        &lt;a href="http://app.wumii.com/ext/redirect?url=http%3A%2F%2Fwww.jackchen.cn%2Fblog%2Farchives%2F5772.html&amp;from=http%3A%2F%2Fwww.jackchen.cn%2Fblog%2Farchives%2F11512.html" target="_blank" title="7&amp;#20010;&amp;#24320;&amp;#21457;&amp;#20154;&amp;#21592;&amp;#21644;&amp;#35774;&amp;#35745;&amp;#24072;&amp;#36866;&amp;#29992;&amp;#30340;WEB&amp;#24212;&amp;#29992;&amp;#36164;&amp;#28304;"&gt;
                             &lt;img height="96px" src="http://static.wumii.cn/site_images/ti/7ybph66O.jpg?i=18GwX9TEl" width="96px"&gt;&lt;/img&gt;     &lt;br /&gt;
                        7个开发人员和设计师适用的WEB应用资源
                    &lt;/a&gt;
                &lt;/td&gt;
                   &lt;td valign="top" width="102"&gt;
                        &lt;a href="http://app.wumii.com/ext/redirect?url=http%3A%2F%2Fwww.jackchen.cn%2Fblog%2Farchives%2F5648.html&amp;from=http%3A%2F%2Fwww.jackchen.cn%2Fblog%2Farchives%2F11512.html" target="_blank" title="WEB&amp;#35774;&amp;#35745;&amp;#24072;&amp;#21644;&amp;#24320;&amp;#21457;&amp;#20154;&amp;#21592;&amp;#38656;&amp;#35201;&amp;#30340;&amp;#26032;&amp;#40092;&amp;#36164;&amp;#28304;"&gt;
                             &lt;img height="96px" src="http://static.wumii.cn/site_images/ti/4Rhw7qwD.jpg?i=wNQlHph4" width="96px"&gt;&lt;/img&gt;     &lt;br /&gt;
                        WEB设计师和开发人员需要的新鲜资源
                    &lt;/a&gt;
                &lt;/td&gt;
                   &lt;td valign="top" width="102"&gt;
                        &lt;a href="http://app.wumii.com/ext/redirect?url=http%3A%2F%2Fwww.jackchen.cn%2Fblog%2Farchives%2F3601.html&amp;from=http%3A%2F%2Fwww.jackchen.cn%2Fblog%2Farchives%2F11512.html" target="_blank" title="30&amp;#20010;&amp;#26032;&amp;#40092;icon&amp;#22270;&amp;#26631;&amp;#21253;&amp;#35774;&amp;#35745;&amp;#24072;&amp;#21644;&amp;#24320;&amp;#21457;&amp;#20154;&amp;#21592;&amp;#30340;&amp;#26368;&amp;#29233;"&gt;
                             &lt;img height="96px" src="http://static.wumii.cn/site_images/ti/n6AgqlR3.jpg?i=YTD2oXQZ" width="96px"&gt;&lt;/img&gt;     &lt;br /&gt;
                        30个新鲜icon图标包设计师和开发人员的最爱
                    &lt;/a&gt;
                &lt;/td&gt;
                   &lt;td valign="top" width="102"&gt;
                        &lt;a href="http://app.wumii.com/ext/redirect?url=http%3A%2F%2Fwww.jackchen.cn%2Fblog%2F%3Fp%3D5648&amp;from=http%3A%2F%2Fwww.jackchen.cn%2Fblog%2Farchives%2F11512.html" target="_blank" title="WEB&amp;#35774;&amp;#35745;&amp;#24072;&amp;#21644;&amp;#24320;&amp;#21457;&amp;#20154;&amp;#21592;&amp;#38656;&amp;#35201;&amp;#30340;&amp;#26032;&amp;#40092;&amp;#36164;&amp;#28304;"&gt;
                             &lt;img height="96px" src="http://static.wumii.cn/site_images/ti/4Rhw7qwD.jpg?i=H6SmruHq" width="96px"&gt;&lt;/img&gt;     &lt;br /&gt;
                        WEB设计师和开发人员需要的新鲜资源
                    &lt;/a&gt;
                &lt;/td&gt;
        &lt;/tr&gt;
    
      &lt;tr&gt;
           &lt;td align="right" colspan="4"&gt;
                &lt;a href="http://www.wumii.com/widget/relatedItems" target="_blank" title="&amp;#26080;&amp;#35269;&amp;#20851;&amp;#32852;&amp;#25512;&amp;#33616;"&gt;
                无觅
            &lt;/a&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>网页设计 CSS JavaScript jquery WEB</category>
      <guid isPermaLink="true">https://itindex.net/detail/47035-%E6%96%B0%E9%B2%9C-%E5%BC%80%E5%8F%91-%E8%B5%84%E6%BA%90</guid>
      <pubDate>Sun, 15 Dec 2013 10:04:05 CST</pubDate>
    </item>
    <item>
      <title>为原生表单控件穿上美丽的外衣</title>
      <link>https://itindex.net/detail/46863-%E6%8E%A7%E4%BB%B6-%E7%BE%8E%E4%B8%BD</link>
      <description>&lt;p&gt;在互联网成熟的今天，大家对网站的要求不仅仅在功能实现上，也开始注重视觉设计，多终端用户体验等等。表单控件是web页面上重要的组成元素，具有非常高的功能性。交互设计师为它设计更加方便的操作方式，视觉设计师也会绞尽脑汁设计出更加夺人眼球的视觉展现。可是由于表单控件自身的局限性，不能很好地自定义外表，所以就诞生了一系列的由聪明的前端同学模拟出来的以假乱真的表单控件。让我们从一个真实的“栗子”开始。&lt;/p&gt;
 &lt;p&gt;视觉设计师提供了一张设计稿：&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://isux.tencent.com/wp-content/uploads/2013/11/20131115164337753.jpg" target="_blank"&gt;   &lt;img alt="&amp;#20026;&amp;#21407;&amp;#29983;&amp;#34920;&amp;#21333;&amp;#25511;&amp;#20214;&amp;#31359;&amp;#19978;&amp;#32654;&amp;#20029;&amp;#30340;&amp;#22806;&amp;#34915;" height="403" src="http://isux.tencent.com/wp-content/uploads/2013/11/20131115164337753.jpg" width="403"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;作为前端同学，我在收到稿子的一瞬间，其实内心各种想法交织:&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://isux.tencent.com/wp-content/uploads/2013/11/20131115164634720.jpg" target="_blank"&gt;   &lt;img alt="&amp;#20026;&amp;#21407;&amp;#29983;&amp;#34920;&amp;#21333;&amp;#25511;&amp;#20214;&amp;#31359;&amp;#19978;&amp;#32654;&amp;#20029;&amp;#30340;&amp;#22806;&amp;#34915;" height="255" src="http://isux.tencent.com/wp-content/uploads/2013/11/20131115164634720.jpg" width="200"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;这样设计很好看，只是需要模拟控件，看样子还要切图，下拉效果也是要模拟的，最重要的是要考虑兼容性，此外做完还要留下详细文档解释用来与团队沟通。&lt;/p&gt;
 &lt;p&gt;这样的模拟需要在兼顾实现设计的同时，还要保证网站的性能和可用性。这时我不禁开始怀念那些看起来平凡却非常实用的原生表单控件。如果用他们几乎可以解决以上所有问题。&lt;/p&gt;
 &lt;h1&gt;  &lt;strong&gt;1. &lt;/strong&gt;  &lt;strong&gt;说服设计师用原生控件，原生控件好处一箩筐&lt;/strong&gt;&lt;/h1&gt;
 &lt;p&gt;我们从美观性、易用性、可用性、愉快感、忠诚度等几个维度对一个web产品评价，美观是其中的一环， 但是更好的功能实现、更高的效率会比华而不实的设计更加有利于产生愉悦的用户体验。&lt;/p&gt;
 &lt;h2&gt;  &lt;strong&gt;1.1 &lt;/strong&gt;  &lt;strong&gt;节省团队沟通成本&lt;/strong&gt;&lt;/h2&gt;
 &lt;p&gt;原生控件自身属性丰富，比如单选、复选框的不可选状态，输入框的不可输入状态等，可以直接开发使用，而不用像模拟控件，需要用样式模拟，增加工作量的同时增加各个环节的沟通成本。&lt;/p&gt;
 &lt;h2&gt;  &lt;strong&gt;1.2 &lt;/strong&gt;  &lt;strong&gt;兼容性&lt;/strong&gt;&lt;/h2&gt;
 &lt;p&gt;使用原生控件在各个浏览器都有非常高的兼容性，同时表单控件会根据各个浏览器的默认设置显示相应的视觉风格，也会根据在实际的不同状态做默认的相应变化。这样有效避免了模拟控件中包括对位置、状态等等判断和控制。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://isux.tencent.com/wp-content/uploads/2013/11/20131115164800627.jpg" target="_blank"&gt;   &lt;img alt="&amp;#20026;&amp;#21407;&amp;#29983;&amp;#34920;&amp;#21333;&amp;#25511;&amp;#20214;&amp;#31359;&amp;#19978;&amp;#32654;&amp;#20029;&amp;#30340;&amp;#22806;&amp;#34915;" height="300" src="http://isux.tencent.com/wp-content/uploads/2013/11/20131115164800627.jpg" width="570"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;h2&gt;  &lt;strong&gt;1.3&lt;/strong&gt;  &lt;strong&gt;可用性&lt;/strong&gt;&lt;/h2&gt;
 &lt;p&gt;关爱有障碍的人士是我们的社会责任，作为前端开发者，我们也致力于为有障碍的人士提供更好的上网体验。原生控件的特性更好地支持键盘操作，tab切换，快捷键等功能，这样有助于视觉障碍用户使用读屏软件等等辅助工具对网页访问。&lt;/p&gt;
 &lt;h2&gt;  &lt;strong&gt;1.4&lt;/strong&gt;  &lt;strong&gt;体验一致性&lt;/strong&gt;&lt;/h2&gt;
 &lt;p&gt;此外，跨平台开发比如在日趋火热的移动端开发，原生控件可以调用浏览器调用手机的控件，保证了跨平台的体验一致性；同时可以适应响应式设计，兼容多种终端设备。&lt;/p&gt;
 &lt;h2&gt;  &lt;strong&gt;1.5&lt;/strong&gt;  &lt;strong&gt;美观性&lt;/strong&gt;&lt;/h2&gt;
 &lt;p&gt;还在担心没办法自定义原生表单控件的外观吗？Webkit给我们提供了这种可能，它允许重新定义控件的外观，让它们跟设计稿一样美丽。下面的例子告诉你。&lt;/p&gt;
 &lt;h1&gt;  &lt;strong&gt;2. &lt;/strong&gt;  &lt;strong&gt;原生控件也可以很美丽，原生控件变装实例&lt;/strong&gt;&lt;/h1&gt;
 &lt;p&gt;使用原生控使用原来的html表单控件结构，通过css对控件自定义，改变其外形。下面从几个实例中，我们一起关注下那些可以自定义的相关属性，探寻未来可以自定义的种种可能。&lt;/p&gt;
 &lt;h2&gt;  &lt;strong&gt;例1：下拉菜单&lt;/strong&gt;&lt;/h2&gt;
 &lt;p&gt;  &lt;a href="http://isux.tencent.com/wp-content/uploads/2013/11/20131115164907235.jpg" target="_blank"&gt;   &lt;img alt="&amp;#20026;&amp;#21407;&amp;#29983;&amp;#34920;&amp;#21333;&amp;#25511;&amp;#20214;&amp;#31359;&amp;#19978;&amp;#32654;&amp;#20029;&amp;#30340;&amp;#22806;&amp;#34915;" height="830" src="http://isux.tencent.com/wp-content/uploads/2013/11/20131115164907235.jpg" width="418"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;p&gt;这里我们可以通过通用的css定义方法，定义下拉框的宽度、高度、边框、背景，还可以自定义下拉按钮的图片。这里为了方便处理，采用base64的图片。&lt;/p&gt;
 &lt;p&gt;  &lt;em&gt;Tip:&lt;/em&gt;  &lt;em&gt;下拉菜单的样式暂时只支持定义字体的大小。&lt;/em&gt;&lt;/p&gt;
 &lt;h2&gt;  &lt;strong&gt;例2：单选框&lt;/strong&gt;&lt;/h2&gt;
 &lt;p&gt;  &lt;a href="http://isux.tencent.com/wp-content/uploads/2013/11/20131115164907736.jpg" target="_blank"&gt;   &lt;img alt="&amp;#20026;&amp;#21407;&amp;#29983;&amp;#34920;&amp;#21333;&amp;#25511;&amp;#20214;&amp;#31359;&amp;#19978;&amp;#32654;&amp;#20029;&amp;#30340;&amp;#22806;&amp;#34915;" height="830" src="http://isux.tencent.com/wp-content/uploads/2013/11/20131115164907736.jpg" width="418"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;p&gt;单选框也可以被改变包括宽度、高度、背景图片等属性。这里为了节约流量，把几种状态的图片合并为雪碧图。从图中效果来看，依靠单选框本身固有属性很方便实现选中和未选中时不可点的状态，并且不用担心兼容性问题。&lt;/p&gt;
 &lt;h2&gt;  &lt;strong&gt;例3：复选框&lt;/strong&gt;&lt;/h2&gt;
 &lt;p&gt;  &lt;a href="http://isux.tencent.com/wp-content/uploads/2013/11/2013111516491220.jpg" target="_blank"&gt;   &lt;img alt="&amp;#20026;&amp;#21407;&amp;#29983;&amp;#34920;&amp;#21333;&amp;#25511;&amp;#20214;&amp;#31359;&amp;#19978;&amp;#32654;&amp;#20029;&amp;#30340;&amp;#22806;&amp;#34915;" height="860" src="http://isux.tencent.com/wp-content/uploads/2013/11/2013111516491220.jpg" width="418"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;p&gt;复选框和单选框非常相似，我们可以通过定义宽度、高度、背景图片等属性，得到我们想要的效果。同样的也可以用自己自身属性实现可点击、不可点击、选中和未选中状态的设置。&lt;/p&gt;
 &lt;h2&gt;  &lt;strong&gt;例子4. 其实，还可以做得更加好看些&lt;/strong&gt;&lt;/h2&gt;
 &lt;p&gt;以上的几个例子是在原生控件基础上做小的视觉改动，其实，我们可以做得更漂亮一些。下图设计是一组第一眼看起来跟单选框没关系的控件，透过现象看本质，同一时间只能选择其中一个空间，这就一个单选框控件的设计。所以我们以单选框为基础，改变他们的展现就做成了下面样子。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://isux.tencent.com/wp-content/uploads/2013/11/20131115165143795.gif" target="_blank"&gt;   &lt;img alt="&amp;#20026;&amp;#21407;&amp;#29983;&amp;#34920;&amp;#21333;&amp;#25511;&amp;#20214;&amp;#31359;&amp;#19978;&amp;#32654;&amp;#20029;&amp;#30340;&amp;#22806;&amp;#34915;" height="134" src="http://isux.tencent.com/wp-content/uploads/2013/11/20131115165143795.gif" width="332"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;p&gt;这一组已经用在我们项目中， 是不是看起来非常特别。 未来有更多的不拘泥默认样式的表单设计我们也可以试试看。&lt;/p&gt;
 &lt;h1&gt;  &lt;strong&gt;3. &lt;/strong&gt;  &lt;strong&gt;某个时候美丽的外衣还是“国王的新衣”&lt;/strong&gt;&lt;/h1&gt;
 &lt;p&gt;非常遗憾，由于非webkit内核浏览器不支持这种自定义的操作，一部分用户包括国内浏览器大户ie版本比较低的用户还是不能体验到这种美观的控件。实用和美观的平衡对于产品来说固然都非常重要的，有时候舍弃一些视觉效果多一些实用性可能换来的是更好评的体验， 而且随着技术的发展，自定义越来越灵活，浏览器对其的支持也越来越好，从这个角度来看，或许未来我们可以更多使用一些原生表单控件。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://isux.tencent.com/wp-content/uploads/2013/11/20131115164937140.jpg" target="_blank"&gt;   &lt;img alt="&amp;#20026;&amp;#21407;&amp;#29983;&amp;#34920;&amp;#21333;&amp;#25511;&amp;#20214;&amp;#31359;&amp;#19978;&amp;#32654;&amp;#20029;&amp;#30340;&amp;#22806;&amp;#34915;" height="370" src="http://isux.tencent.com/wp-content/uploads/2013/11/20131115164937140.jpg" width="370"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>前端技术 CSS isux 用户体验</category>
      <guid isPermaLink="true">https://itindex.net/detail/46863-%E6%8E%A7%E4%BB%B6-%E7%BE%8E%E4%B8%BD</guid>
      <pubDate>Mon, 25 Nov 2013 11:55:43 CST</pubDate>
    </item>
    <item>
      <title>网页重构应该避免的10大 CSS 糟糕用法</title>
      <link>https://itindex.net/detail/46646-%E7%BD%91%E9%A1%B5-%E9%87%8D%E6%9E%84-css</link>
      <description>&lt;p&gt;  &lt;strong&gt;标签：&lt;/strong&gt;    &lt;a href="http://blogread.cn/it/tags.php?tag=%E9%87%8D%E6%9E%84" target="_blank"&gt;重构&lt;/a&gt;&lt;/p&gt; &lt;p&gt;    今天在回广州的火车上看到一篇  &lt;a href="http://www.creativebloq.com/css3/avoid-css-mistakes-10135080"&gt;“10 CSS mistakes every web designer must avoid”&lt;/a&gt;，想着还不错，就翻译给大家。&lt;/p&gt; &lt;p&gt;    对于网页重构来说，  &lt;a href="http://www.csszengarden.com/tr/chinese/"&gt;CSS禅意花园&lt;/a&gt; 是网页布局从 table 表格转到了 html +css 的标志 。这些年来，随着我们的网站越来越复杂：html5，css3，新的技术、新的属性，越来越多的开发者开始思考和尝试提高他们的 CSS 技能。那么我们从哪里着手呢？对于网页重构工作来说，我们应该养成什么样的开发习惯？一个糟糕的 css 用法是怎样的？我们应该怎么处理这些糟糕的 css。今天这篇文章，我将谈一谈10个我们应该避免的 css 糟糕用法，当然，我们也会分享怎么才是正确的用法。&lt;/p&gt; &lt;p&gt;    为了方便大家理解，我将这10个糟糕用法归为三大类：权重、工作流、自以为是。&lt;/p&gt; &lt;h4&gt;权重！权重！！权重！！！&lt;/h4&gt; &lt;p&gt;    正所谓  &lt;a href="http://zh.wikipedia.org/wiki/%E9%A9%AC%E5%A4%AA%E6%95%88%E5%BA%94"&gt;马太效应&lt;/a&gt;，如果你写了很烂的 css，这段烂代码的不好之处是他会导致更多和更烂的代码。如果你需要解决一个 css bug，发现唯一的解决方法是：使用更多层级的选择器、 id 选择器；甚至跟糟糕：使用内联样式( inline-style )，直到使用最后的大杀器!important。以上提到的所有用法归根到期他们犯了「过多权重」的错误。&lt;/p&gt; &lt;p&gt;    CSS 中的权重取决于你如何使用具体的css 规则。&lt;/p&gt; &lt;p&gt;    #layout #header #title .logo a { display: block; }&lt;/p&gt; &lt;p&gt;    看看上面这串 CSS 选择器，你可能觉得这是一段符合语义化的「好」选择器：简单明了。如果你依照习惯从左往右读，你可能是这么理解：「先找到主要布局区域，再找头部区域，再找倒 title 标题区域，再找到 logo 标志区域，再找到这里面的所有 a 锚点」，对于 css 来说，这是一个很具体的精确定位，但是，实际上我们很少有机会  &lt;strong&gt;需要&lt;/strong&gt;这么精确的定位。过大的css权重会造成你的样式表更加难以维护(你考虑过接你班的同事的感受木有！)，也更加难以阅读和理解(这么多层声明、一长串你闹哪样啊)。&lt;/p&gt; &lt;h6&gt;01.滥用 id&lt;/h6&gt; &lt;p&gt;    CSS 权重的高低取决于你使用什么样的选择器：id,class 类,tags 标签。举个栗子：&lt;/p&gt; &lt;pre&gt;#my-link{color: red}
.my-link{color: yellow}
a{ colour: blue}
&lt;/pre&gt; &lt;p&gt;    来做这么一个小测试，有这么一个超链接如下，如果我们没有其定义其他样式，浏览器渲染出来的最终结果会是什么颜色？&lt;/p&gt; &lt;pre&gt;&amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my-link&amp;quot; class=&amp;quot;my-link&amp;quot;&amp;gt;举个栗子&amp;lt;/a&amp;gt;
&lt;/pre&gt; &lt;p&gt;  &lt;img border="0" height="507" hspace="0" src="http://luolei.org/wp-content/uploads/2013/11/css-specifity-1.png" vspace="0" width="680"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;    最终的颜色会是红色，因为 id 属性是三者之中权重最高的(id在网页中只能使用一次，他得权重值为100)，所以红色葫芦娃成功击败了其他娃娃，举起了栗子。&lt;/p&gt; &lt;p&gt;    根据 css 权重，权重次于 id 的是class类，最后才是tag标签，正如你如上图审查器中所看到的。&lt;/p&gt; &lt;p&gt;    当然啦，像上面我们举的栗子这种「同时使用 id/calss/tag 」的情况在实际应用中还是很少见的，在日常开发中，我们更多的情况是会遇到如下情况：&lt;/p&gt; &lt;pre&gt;#header a { border:2px dashed #000 }
&lt;/pre&gt; &lt;p&gt;    假设这是我们的一个项目，现在我们决定要把一个在 header 的 link设置成无边框，随手一写，我们添加了：&lt;/p&gt; &lt;pre&gt;.special-link { border:none }
&lt;/pre&gt; &lt;p&gt;    然后再在 html 中添加了一个 special-link 的class 类，这下解决我们的问题了吗？ 答案是：没有！ 由于 id 的权重如此之高，我们需要更高权重的声明才能实现我们的需求。下面这样写才是正确的：&lt;/p&gt; &lt;pre&gt;#header .special-link { border: none }
&lt;/pre&gt; &lt;p&gt;  &lt;img border="0" height="511" hspace="0" src="http://luolei.org/wp-content/uploads/2013/11/css-specifity-2.png" vspace="0" width="680"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;    假如说这种情景在我们的 code 过程中不断地出现：设置 header 区域另外一个特殊的超链接 link 为某特殊的样式，你该怎么处理呢？ id 的高权重特性意味着滥用 id 绝对是一个很糟的做法！&lt;/p&gt; &lt;p&gt;    那我们如何解决这个问题呢？用 class 类来代替 id 吧。&lt;/p&gt; &lt;h6&gt;02.大串的 css 选择器(多层级)&lt;/h6&gt; &lt;pre&gt;#header #title .left-side img.logo { opacity: 0.5 }
&lt;/pre&gt; &lt;p&gt;    上面这个栗子不仅仅乱用 id，他还很长，正如同乱用 id导致的高权重麻烦，如果你使用一大串选择器(超过三个层级)你同样会造成过高权重，导致你陷入到高权重和更高权重的汪洋大海之中。&lt;/p&gt; &lt;p&gt;    那针对这个问题的解决办法有什么呢——精简！如同我们现在这个栗子，如果我们用一个 .logo class类就能解决我们的需求，那我们就没必要写这么以大串了。一般情况下，我们应该控制选择器在2个，最多3个。&lt;/p&gt; &lt;h6&gt;03.Inline styles&lt;/h6&gt; &lt;p&gt;    内联样式是css 权重罪恶的源泉，同时也从根本上摧毁了我们使用 css 的初心(结构样式分离)。当我们的工程师好不容易走出 tables 的魔窟开怀拥抱外部样式表，我们早就应该知道不要把样式同结构混杂在一起。&lt;/p&gt; &lt;p&gt;    根据 css 权重级的特性，内联样式只能被!important 所覆盖。一般来说，这就意味着，如果某猿使用了!important，他们更多是被逼的没办法才这么用(对应英文 reactive)，而不是想这么用(preoactive)。的确!important在 css 样式表中用起来十分方便，但我们最好是聪明地、小心翼翼地碰她、用他，而不是把他当做救命稻草(救命稻草用多了，迟早也会从救命稻草变成压死骆驼的稻草)。&lt;/p&gt; &lt;p&gt;    下面举例怎么解决内联样式的问题，就两步 1.复制删除 2.粘贴 。剔除内联样式，转移到样式表之中吧。&lt;/p&gt; &lt;p&gt;  &lt;img src="http://luolei.org/wp-content/uploads/2013/11/css-specifity-3.jpg"&gt;&lt;/img&gt;&lt;/p&gt; &lt;h6&gt;04.从上至下式的粗放命名&lt;/h6&gt; &lt;p&gt;    说完 css 权重，接下来我们来谈谈其他 CSS 的糟糕用法。假设我们开始了一个新项目，设计师丢给我们一份 psd，我们开始在 html 中写基本的框架。&lt;/p&gt; &lt;p&gt;    根据结构从下至上式的命名方式模糊化了 html 结构，工程师常常根据上下结构来命名id 和 class，而不是具体的设计元素，例如#header,content，这常常会导致长选择器(举个例子如. menu ul li a｛　｝)，这样的后果是我们的代码变得难以调试和维护。怎么解决这个问题呢？我们应该尝试从网页中分离出设计元素，这同样可以减少我们代码中的冗余。&lt;/p&gt; &lt;h6&gt;05.冗余/重复&lt;/h6&gt; &lt;p&gt;    冗余意味着你写 css 的过程中不断重复某些代码。在使用编程语言的时候， 我们很好理解重复(造轮子)意味着浪费时间，我们在 code 中应该遵循 DRY 原则(Don’t repeat yourself)。什么情况下我们会重复造轮子呢？举个栗子：&lt;/p&gt; &lt;pre&gt;.some-title { font-weight: bold; }
.some-other-title { font-weight: bold; color: red }
&lt;/pre&gt; &lt;p&gt;    实际上，我们可以有个更好的解决办法&lt;/p&gt; &lt;pre&gt;.some-title, .some-other-title { font-weight: bold; }
.some-other-title { color: red; }
&lt;/pre&gt; &lt;p&gt;    比如说我们要添加一个不同颜色的标题，我们可以使用一个常用的命名，或者添加一个具体的 class 类。&lt;/p&gt; &lt;pre&gt;&amp;lt;h3 class=&amp;quot;some-title pop&amp;quot;&amp;gt;我的标题/h3&amp;gt;
&lt;/pre&gt; &lt;p&gt;    这个有点  &lt;strong&gt;   &lt;a href="http://www.qianduan.net/object-oriented-css.html"&gt;面向对象的CSS&lt;/a&gt;&lt;/strong&gt;的思想在里面，使用 Sass 中的 @extend 特性可以很好地解决我们这个问题。&lt;/p&gt; &lt;p&gt;    在 Sass 之中，你可以使用@extend 继承选择器，被继承的选择器的样式也被继承。这个特性使得我们可以很方便管理不同的样式，举个栗子：&lt;/p&gt; &lt;pre&gt;.some-title { font-weight: bold; }
.some-other-title { @extend .some-title; color: red; }
&lt;/pre&gt; &lt;p&gt;    当CSS预处理编译器将.scss转换成.css文件时，我们最终输出的样式是：&lt;/p&gt; &lt;pre&gt;.some-title, .some-other-title { font-weight: bold; }
.some-other-title { color: red; }
&lt;/pre&gt; &lt;p&gt;    最终输出的是一模一样的效果，解决重复和冗余的问题，要求我们在写 css 的时候心中对 html 层级结构要有个大致的规划，思考不同的设计元素之间的层级和关系，我们规划得越清晰，最终输出的 css 也越精简。&lt;/p&gt; &lt;h6&gt;06.精简你的单位&lt;/h6&gt; &lt;p&gt;    如果你的样式表中混杂着 px,em,rem等等单位，是时候改变了，业内著名的web开发者  &lt;a href="http://rachelnabors.com/"&gt;Rachel Nabors&lt;/a&gt; 呼吁大家统一使用em为字体大小单位，他曾说「我看其他人的样式表第一件事就是看字体样式，然后把所有的font-size的单位换成em」，这几年用户使用的终端越来越多样(不同的终端、不同的浏览器使用的默认字体大小存在差异)，使用绝对字体大小px变得越来越不可控，使用em等相对大小的字体则避免了这个问题。&lt;/p&gt; &lt;p&gt;    如果你想在转成em对这些单位有个深入点的了解，推荐你阅读  &lt;a href="http://www.1z1b.com/one-blog-a-week/px-em-pt/"&gt;《CSS文字大小单位PX、EM、PT》&lt;/a&gt;。&lt;/p&gt; &lt;p&gt;    当然，如果你就是不喜欢em和他们嵌套特性，那么你可以更进一步了解 CSS3 中推出的新单位   &lt;a href="http://www.w3cplus.com/css3/define-font-size-with-css3-rem"&gt;rem&lt;/a&gt;。&lt;/p&gt; &lt;p&gt;    不同单位在 web 设计之中的战争还在继续(可参考文章  &lt;a href="http://kyleschaeffer.com/development/css-font-size-em-vs-px-vs-pt-vs/"&gt;CSS Font-Size: em vs. px vs. pt vs. percent&lt;/a&gt;&lt;/p&gt; &lt;p&gt;    )，学习一点相关知识对我们提高代码可维护性至关重要。&lt;/p&gt; &lt;p&gt;    下面我们进入到这篇博文的第三也是最后一个部分「自以为是」，这些坏习惯包括：增加不必要的东西，错误，无意义的 css。&lt;/p&gt; &lt;h6&gt;07.向下兼容和无效的规则&lt;/h6&gt; &lt;p&gt;    在开发的过程中，如果你不需要使用 css3 之类的高大上代码就能实现效果，那再好不过了。可是，作为工程师的你在 Chrome 最新版本上面看到的效果，并不意味着你的用户能在他们的浏览器上看到同样的效果(考虑过 IE 的感受没有)，一个十分糟糕的坏习惯就是完全忽略向下兼容性。&lt;/p&gt; &lt;p&gt;    如果你在项目中使用rgba()，你是否测试过这个属性的兼容性？如果没有，那你最好祈祷没有 IE8的用户会访问你的网站。你是否写全了针对不同浏览器的不同的规则(-webkit,-ms -moz 等等)？解决这个问题，可以使用   &lt;a href="http://csslint.net/"&gt;CSS LInt&lt;/a&gt;检测下你的 css 代码，CSS Lint的检测规则包括错误的和不合理的地方。&lt;/p&gt; &lt;h6&gt;08.(没有意义)不起作用的样式&lt;/h6&gt; &lt;p&gt;      &lt;a&gt;Harry Roberts&lt;/a&gt;的  &lt;a href="http://csswizardry.com/2012/11/code-smells-in-css/"&gt;Code smells in CSS&lt;/a&gt;是关于 css 糟糕用法的经典文章。他举了几个可有可无的不起作用样式的栗子：&lt;/p&gt; &lt;pre&gt;h2{
font-size:2em;
margin-bottom:0.5em;
padding-bottom:0.5em;
border-bottom:1px solid #ccc;
}
.no-border{
padding-bottom:0;
border-bottom:none;
}
&lt;/pre&gt; &lt;p&gt;    Roberts 推荐的重构精简方法是删掉属性为0和none的属性值。&lt;/p&gt; &lt;pre&gt;h2{
font-size:2em;
margin-bottom:0.5em;
}
.headline{
padding-bottom:0.5em;
border-bottom:1px solid #ccc;
}
&lt;/pre&gt; &lt;p&gt;    如果你像重构之前的那样写法，h2是一个我们在web 设计中会不断重复用到的元素，这个本质上「你写了更多的代码却没有实现了更少的样式效果」，如果我们接下来又要设置一个h2的属性为其他样式，那代码会得很乱。&lt;/p&gt; &lt;p&gt;  &lt;img src="http://media.creativebloq.futurecdn.net/sites/creativebloq.com/files/images/2013/10/net245featcss/05.jpg"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;    Harry Roberts是   &lt;a href="http://inuitcss.com/"&gt;inuit.css&lt;/a&gt; 框架的作者。&lt;/p&gt; &lt;h6&gt;09.巧而不巧:用 Hack 不意味着你是个好 Hacker&lt;/h6&gt; &lt;p&gt;    负的 margin 边距，!important等等，上面的这些就是我们所说的 hack 用法(此 hack 非针对IE 兼容的 hack，也可以理解成 cheater 作弊用法)，如果其他人问我们为什么要这么写？我们可能只需要回答「管他呢，反正能实现效果」。&lt;/p&gt; &lt;p&gt;    当我们为自己使用这些充满「弊」端的方法而略不放心的时候，一个解决办法就是把我们的这些 hack 放到一个特定的样式表文件hack.css之中。&lt;/p&gt; &lt;p&gt;    任何时候你意识到你写了一个 css 的 hack 用法的时候，你直接把这些代码放到这个hack.css 之中(或者样式表的特定区域：通过注释跟其他样式区分开)，这个专属区域是个好解决方案因为他最终会在用户端隐藏。&lt;/p&gt; &lt;p&gt;    当我们养成了这个习惯，我们可以十分清晰地知道我们写了哪些 hack ，同样可以方便我们了解我们使用这些 hack 的情景，让我们可以知道如何避免这些 hack 。我们有许多写 hack 用法的理由，但是如果我们不记录我们为什么 hack，我们将不会从我们这些 hack 中学到我们为什么要错误地这么用。&lt;/p&gt; &lt;h6&gt;10.糟糕的文档和注释&lt;/h6&gt; &lt;p&gt;    昨天在微博上看到一个段子「程序员最讨厌的四件事：写注释、写文档、别人不写注释、别人不写文档 …」。&lt;/p&gt; &lt;p&gt;    写文档和注释绝对不是一个有意思的事情，但却是一个最重要的事情(尤其是涉及到项目后续可维护性时)，文档可以有效地让其他人知道你的代码是干什么的，同时其他人理解你的 css。对于大部分语言(html,css,php,JavaScript) ，开发者可以直接在代码文件中写上注释(文档)。&lt;/p&gt; &lt;p&gt;      &lt;a href="http://rachelnabors.com/"&gt;Nabors&lt;/a&gt; 曾说「我曾YY：如果我今天写完一个项目的 css 但是明儿我却挂掉了，有一个人幸运地接手我这个项目，那他看得懂我的这些代码是什么意思吗？」。尽量地让我们的样式表中的结构清晰，如果不能让人立马知道你的选择器指的是哪里的样式，可以尝试添加注释(什么！你还说注释增加css 文件大小！难道你不知道压缩工具么！)。&lt;/p&gt; &lt;p&gt;    第一步是在必须的地方做好注释，第二步是使用工具把css文件中的这些注释转换成一个合适的文档。推荐可以使用  &lt;a href="https://github.com/tkadauke/css_doc"&gt;css_doc&lt;/a&gt;和  &lt;a href="https://github.com/kneath/kss"&gt;KSS&lt;/a&gt;。&lt;/p&gt; &lt;p&gt;    css_doc 跟 JavaDoc类似，他的转换原理基于 CSSDOC. KSS(Knyle Style Sheets)，对于前端和设计师来说都十分有益。&lt;/p&gt; &lt;h4&gt;总结&lt;/h4&gt; &lt;p&gt;    在这篇文章中，我们介绍了一些常见的 css 糟糕用法，指出了为什么我们应该避免这些用法和应该使用什么正确的用法。还是这句话”Doin something is always better than nothing”，行动起来总比什么都不做要好点，未雨绸缪有备无患。&lt;/p&gt; &lt;p&gt;    今天你看完这篇文章，知道了10个糟糕的 CSS 用法，这不意味着你明儿去上班就把你过去所有的代码都重构一遍。从点滴开始，一步一步来才是我们开发工作的正确做法。在接下来的工作中，注意这些细节，避免这些「小」错误，让我们的代码更漂亮点。终有一天，我们会发现”Code is poetry”。&lt;/p&gt; &lt;h4&gt;译者言&lt;/h4&gt; &lt;p&gt;    这是第二次翻译技术相关文章，不得不说，还是低估了翻译的难度。要把技术类的文章翻译得语言流畅、通俗易懂，还是挺有挑战性的。译文中加入了自己的理解，配图也是自己通过 codepen 重新截图演示，这篇文章的译稿我放在了 google docs 上，如果对于某些翻译你有更好的用法，可以直接建议修改。&lt;/p&gt; &lt;p&gt;    https://docs.google.com/document/d/11Ly6z0dlVVPzIL-W22L_U6waoU7Pid4-KdDmEx6D0c8/edit?usp=sharing&lt;/p&gt;
				 &lt;p&gt;  &lt;strong&gt;您可能还对下面的文章感兴趣：&lt;/strong&gt;&lt;/p&gt;
				 &lt;p&gt;  &lt;ol&gt;   &lt;li&gt;    &lt;a href="http://blogread.cn/it/article.php?id=6759" target="_blank"&gt;代码重构方向原则指导&lt;/a&gt; [2013-10-23 12:59:38]&lt;/li&gt;   &lt;li&gt;    &lt;a href="http://blogread.cn/it/article.php?id=6291" target="_blank"&gt;实践中的重构&lt;/a&gt; [2013-03-07 13:54:53]&lt;/li&gt;   &lt;li&gt;    &lt;a href="http://blogread.cn/it/article.php?id=5996" target="_blank"&gt;如何避免重构带来的危险&lt;/a&gt; [2012-11-11 23:43:29]&lt;/li&gt;   &lt;li&gt;    &lt;a href="http://blogread.cn/it/article.php?id=5638" target="_blank"&gt;前端重构实践（一） —— 性能优化&lt;/a&gt; [2012-08-05 22:55:17]&lt;/li&gt;   &lt;li&gt;    &lt;a href="http://blogread.cn/it/article.php?id=5569" target="_blank"&gt;实战遗留代码&lt;/a&gt; [2012-07-19 12:22:40]&lt;/li&gt;   &lt;li&gt;    &lt;a href="http://blogread.cn/it/article.php?id=5331" target="_blank"&gt;什么是重构，什么不是重构&lt;/a&gt; [2012-05-14 22:20:55]&lt;/li&gt;   &lt;li&gt;    &lt;a href="http://blogread.cn/it/article.php?id=3605" target="_blank"&gt;抵制代码重写&lt;/a&gt; [2011-05-17 09:10:49]&lt;/li&gt;   &lt;li&gt;    &lt;a href="http://blogread.cn/it/article.php?id=1107" target="_blank"&gt;关于重构和重写&lt;/a&gt; [2010-03-02 13:39:21]&lt;/li&gt;   &lt;li&gt;    &lt;a href="http://blogread.cn/it/article.php?id=556" target="_blank"&gt;网站重构到底是什么，网站重构到底要多久&lt;/a&gt; [2009-11-12 19:01:52]&lt;/li&gt;   &lt;li&gt;    &lt;a href="http://blogread.cn/it/article.php?id=411" target="_blank"&gt;重构发现：指针操作问题&lt;/a&gt; [2009-11-02 21:05:07]&lt;/li&gt;&lt;/ol&gt;&lt;/p&gt; &lt;img height="1" src="http://feeds.feedburner.com/~r/blogreadIT/~4/jqepruZ8nco" width="1"&gt;&lt;/img&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>CSS/HTML</category>
      <guid isPermaLink="true">https://itindex.net/detail/46646-%E7%BD%91%E9%A1%B5-%E9%87%8D%E6%9E%84-css</guid>
      <pubDate>Fri, 22 Nov 2013 07:18:46 CST</pubDate>
    </item>
  </channel>
</rss>

