整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

WP主题开发14:怎样添加wordpress主题trans的文章列表页模板?

前面的章节中,我们创建了wordpress主题trans的公共模板:header.php头部模板、sidebar.php侧边栏模板、footer.php底部模板,这样就更加方便了trans主题的其它动态模板的开发。就比如,今天我们要开发的模板——文章列表页模板,就不需要再去修改头部、侧边栏、底部的代码了。好了,闲话不多说,我们直接进入到今天的主题当中,怎样添加trans主题的文章列表页模板?

第一步:创建列表页模板文件。

在trans主题目录下创建一个列表页模板的文件——archive.php。wordpress程序默认的文章列表页模板的名字必须是:archive 或 categoty,也就是说,可以是archive.php,也可以是category.php,我们这里用archive.php。

第二步:引入头部模板。

用sublime等编辑器打开trans主题的静态模板list.html,把你的代码复制到archive.php文件中。然后,在代码找到</header>这句代码,从<!doctype html>与</header>之间的所有代码全部删除,因为这段代码,我们已经可以使用公共模板——header.php来代替了。

删除后,我们再来引入header.php这个头部模板:

< ?php get_header(); ?>

这时,我们可以正常打开列表页了。但是有一个小问题:标题显示的不是文章分类的名称,仍然是网站的名称。而我们需要的效果是,在列表页时,我们需要显示的是文章分类目录的名称。所以,我们要在header.php文件中的<title></title>标签中修改一个调用代码,

原代码是:

< title>< ?php echo get_bloginfo("name"); ?></title>

修改成如下代码:

< title>< ?php if(is_home()){echo get_bloginfo("name"); }else{if(is_category()){$cat_c = get_the_category();echo $cat_c[0]->cat_name; echo " - "; bloginfo("name");}else{the_title(); echo " - "; bloginfo("name");} } ?></title>

这段代码的意思是:如果是网站的首页,就显示网站的名称;如果是列表页,就显示为“分类目录名称 + 网站名称”;否则就显示“文章标题+网站名称”。

第三步:引入右侧边栏模板。

在archive.php中找到< div class="c_right">标签中的所有代码,删除掉,然后,在当前位置上,引入公共模板sidebar.php侧边栏模板,代码如下:

< ?php get_sidebar(); ?>

这样,我们就不需要再去修改原< div class="c_right">标签内的代码了,而只需直接把sidebar.php拿来用就可以了。

第四步:引入底部模板。

同上,在archive.php代码中找到< footer>标签,然后,把< footer>及它后面的所有代码全部删除掉,现在不需要了,因为,我们有footer.php底部公共模板了。删除掉后,我们在原位置上直接引入这个footer.php底部模板,代码如下:

< ?php get_footer(); ?>

在引入完头部、侧边栏、底部的公共模板后,我们再来看看archive.php的模板代码,如下图:

然后,我们只需要修改archive.php模板代码中的 < div class="c_left">标签内部的代码就可以了。

第五步:修改左侧主体部分。


其实,我们查看trans主题的静态代码的效果时,我们可以看到,列表页与首页基本上是一样的,只是左侧的顶部多了一个面包屑导航。所以,我们只需要修改< div class="c_left">标签里的代码就可以了(如上图所示)。我们可以先把archive.php代码中的< div class="c_left">里的代码全部删除掉,然后把首页模板index.php代码中的< div class="c_left">所有代码全部复制下来,粘贴到archive.php中。这段代码包括了左侧的文章列表以及分页按钮。这样,archive.php的左侧主体部分基本弄好。

第六步:添加面包屑导航。

我们在archive.php模板的< div class="c_left"> 标签中的< div class="left_bottom">标签的上方,添加发下代码:

< div class="left_top">< ul>< li><span class="dashicons-before dashicons-admin-generic"></span><?php echo $cat_c[0]->cat_name; //获取当前分类名 ?></li>< li>< a href="< ?php bloginfo("siteurl"); ?>">< span class="dashicons-before dashicons-admin-home"></span>首页</a> > < ?php the_category(","); ?></li></ul>< ul>< ?php $cat_desc = $cat_c[0]->category_description; //获取当前分类的描述。if($cat_desc){echo $cat_desc; }else{echo $cat_c[0]->cat_name; //获取当前分类名}?></ul></div>

这段代码中,我们又用到了几个wordpress的函数:

the_category(","):获取当前分类导航;$cat_c = get_the_category():获取当前分类的信息,并赋值给$cat_c这个变量

面包屑导航的主要作用,就是让用户可以看到当前页面所在的个体位置。而且,可以通过点击面包屑导航中的相关链接,可以跳转到链接页面,如:返回首页(如下图)。

​通过上面的几步,我们就完成了wordpress主题trans的文章列表页动态模板的修改。嗯,是不是有一个小小的发现:修改trans主题的列表页模板要比修改首页模板index.php所花的时间要少得多。是的,因为在修改index.php首页模板时,我们需要所有的代码,而修改archive.php模板时,我们只需要把公共模板拿来直接用就可以了,省去了大量的时间,这就是公共模板的魅力之所在。好了,本节就介绍到这里,如有疑问,欢迎点评。

作为一个内容类应用,看新闻读资讯一直是头条用户的核心需求,页面的打开速度直接关系到用户使用头条的核心体验,在头条中,为了更多的承载足够丰富的样式和逻辑下保持多端体验的统一,详情页的内容我们是通过 WebView 来承载的,但 WebView 本身的性能相比 Native 来说比较差,因此,技术团队一直致力于优化详情页的加载速度。

经过不断的优化,目前中详情页在线上的打开体验,从肉眼上基本已经感知不到加载过程。在接下来这篇文章里,我们会逐步拆解和介绍我们对详情页加载优化的思路和实践。

先让我们来看看优化前后的效果吧~

详情页加载体验优化前

详情页加载体验优化后

数据建立

性能

当我们开始着手优化页面加载速度之前,我们需要明确一个问题,怎样才是用户真正体验到的页面加载时间。

首先我们可以看下面这个公式:

页面加载时间 = 页面加载完成时间 - 页面开始加载时间

页面开始加载时间很好确定,当用户点击了 Feed 上的卡片,我们就可以认为页面开始加载了。

问题是怎么定义页面加载完成了呢?从客户端的角度上看,无论是 iOS 还是 Android,WebView 都提供了一个 loadFinsih 的回调,但在实际应用中我们发现,loadFinish 回调并不能反应用户的真实体验。

一般来说,WebView 渲染需要经过下面几个步骤

  1. 解析 HTML 文件
  2. 加载 JavaScript 和 CSS 文件
  3. 解析并执行 JavaScript
  4. 构建 DOM 结构
  5. 加载图片等资源
  6. 页面加载完毕

而 loadFinish 实际上是在页面加载完毕阶段,而 DOM 构建完成时页面结构就已经基本渲染完成,所以从用户真实体验的角度出发,我们以 DOM 结构构建完成(即 domReady)的时间点作为页面加载完成时间点。

白屏

在详情页浏览过程中,除了页面加载速度之外,还有一个特别影响用户体验的问题,就是页面的白屏,也是早期的时候用户反馈比较多的问题,但有很多场景都可能导致详情页发生白屏,比如说网络异常,WebView 异常等等,需要从用户体验的角度出发去检测用户发生白屏的情况。

目前可以想到最直观的方案就是对 WebView 进行截图,遍历截图的像素点的颜色值,如果非白屏颜色的颜色点超过一定的阈值,就可以认为不是白屏,目前需要考虑的是这个方案的性能问题和检测时机。

iOS 中提供了 WebView 快照的接口获取当前 WebView 渲染的内容,底层采用异步回调的实现方式,API 耗时 10ms 左右,用户基本无感知。

- (void)takeSnapshotWithConfiguration:(nullable WKSnapshotConfiguration *)snapshotConfiguration completionHandler:(void (^)(UIImage * _Nullable snapshotImage, NSError * _Nullable error))completionHandler API_AVAILABLE(ios(11.0));

Android 中系统提供的获取视图内容的接口为 getDrawingCache,API 耗时在 40ms 左右,性能损耗也不是特别大。

除了截图的性能损耗,像素点检测也是白屏检测中比较耗时的场景,经过实验,我们把 WebView 截图的图片进行缩小到原图的 1/6,遍历检测图片的像素点,当非白色的像素点大于 5% 的时候我们就认为是非白屏的情况,可以相对高效检测准确得出详情页是否发生了白屏。

指标建立

确定好口径之后,我们还有需要明确的一个问题是,什么指标可以反映用户刷头条时的真实体验。

最早的时候,我们用的是详情页页面的页面平均加载时长,也就是页面加载时长的总和/页面 pv,在开始的时候这个指标也的确可以明确我们的加载速度。

后来随着详情页的加载优化逐渐的深入,会发现平均加载时长虽然也可以反映详情页加载速度,但是因为详情页的 pv 比较高,如果使用平均加载速度化很多用户体验问题就被平均掉了,并不能反映用户的真实情况,后面我们又调整了口径,将指标调整为所有用户进入详情页的 80 分位值,比如说,假如头条详情页加载速度 80 分位值是 1 秒,那么就说明 80% 的情况下用户进入详情页都能在 1s 内加载完成,当然经过我们的不断优化,详情页加载的 80 分位值已经能够达到 0.3s 以内,也就是说,80% 的情况下用户都能够在 0.3s 内完成页面加载。

80分位优化数据对比

再后来我们又发现,在头条详情页的量级下面,即使是 80 分位的数据也不能反应许多长尾用户的真实情况,也为了更极致的追求详情页的加载性能,我们最后将详情页的性能口径调整到 95 分位。到目前在我们的努力下,详情页的加载速度 95 分位也优化了将近 80% 。

我们究竟做了什么呢,接下来会慢慢介绍一下。

模板优化

模板拆分

如前所述,图文详情页是通过 WebView 来承载的,而 WebView 承载页面最简单的做法就是直接通过 URL 去加载一个线上页面。那么先来一道简单的面试题,当用户从浏览器输入一个 URL 到页面展现发生了什么呢?

之前已经介绍过页面的渲染流程了,现在我们再简单看看用户从点击到看到页面内容需要经历如下几个阶段:

WebView 加载流程


可以看到,通过线上页面加载用户每次进入详情页都要通过多次网络加载,极容易受网络波动的影响,这种情况下,也无法保证页面加载的时长和成功率,极大的影响了用户体验。

于是在头条中,我们将新闻中标题和正文内容进行拆分,把头条详情页的公共样式 CSS 和 逻辑 JS 都抽离出来,形成一个独立而完备的详情页模板,这样我们就可以把模板直接内置在客户端中。

同时我们会与前端约定好的 JS 脚本,通过接口将正文内容数据注入页面完成详情页的页面展示,通过该这种方式我们可以将接口放到客户端上进行请求。

这样用户进入详情页的时候只需要本地加载模板,而且加载模板的时候也可以同时并行请求详情页数据,再将数据注入进模板中。

那么用户点击到看到页面内容只需要经历下面的阶段:

模板拆分


如上图所示,我们只需要通过一次网络加载就可以完成页面渲染。

还能不能更快一点呢?当然能!

为了提高页面的加载速度,客户端通过一定的策略去预加载新闻数据,这样在理想状态下用户进入页面时看到页面时就可以直接使用缓存的数据,用户在看新闻的时候可以实现完全离线化,避免受到网络的影响。

本地加载

模板预热

完全脱离了网络加载之后,还能再快一点呢?当然还是可以的!

当全流程离线化之后,页面加载的瓶颈就变成了本地模板的加载时间,所以我们接下来要做的就是优化模板加载时间。

对于模板来说,我们做了两件事情

  1. 模板合并,正常来说,WebView 需要在加载玩主 HTML 之后再去加载 HTML 中的 JS 和 CSS,需要多次 IO 操作,于是我们将 JS 和 CSS 还有一些图片都内联到一个文件中,这样,加载模板时就只需要一次 IO 操作,也大大减少因为 IO 加载冲突导致模板加载失败问题
  2. 模板简化,我们将部分非必须的脚本异步化拉取,精简不必要的样式和 JS 代码,将模板大小压缩了 20% 以上

通过上面优化,我们就已经将模板加载时间大大优化了,但是还能不能更给力呢?还是可以的。

对于客户端来说,当模板跟数据分离之后,由于每次用户点击的时候加载的都是同一个模板,所以实际上,我们并不需要在用户进入页面的时候才去创建 WebView 以及加载模板,我们只需要在合适的时机在后台创建 WebView,并且提前预热加载模板,当用户点击进入页面的时候就能使用已经加载好模板的 WebView,直接将详情页的内容数据通过 JS 注入到页面中,前端收到数据后进行页面渲染即可。

此时用户进入详情页实际就不再需要重新加载模板了,路径就变成了:

模板预热

可以看下,通过本地测试的模板预热和数据预取的优化效果,还是比较明显的,基本上已经达到了上面的截图中的验证效果。

本地测试数据

模板复用

当我们拆分完模板和数据之后,数据上优化已经比较明显,但我们说过,除了验证数据,我们还需要看线上用户的真实体验数据,从 95 分位上看实际数据优化却不是很明显,所以我们从数据上观察,用户预热模板的命中率只有 53%,还有进一步的提升空间。

模板预热率

为了尽可能的提高页面的加载速度,我们希望用户每次进入详情页的时候都能够使用预热好模板的 WebView,一般情况下,我们都会使用模板预创建池的手段来优化用户进入详情页时的预热模板命中率。

但其实在很多情况下,WebView 的创建是一个性能开销比较大的操作,如果我们使用预创建池的方案,那么就会在后台频繁创建 WebView,这样对用户在 Feed 场景的浏览体验也会有一定的影响。

而且假如用户频繁且快速进出详情页时,实际场景中用户也很容易遇到无法命中预热模板的场景。

这个时候为了优化用户的体验,如前文所述,我们每次使用的时候都是同一个模板,所以我们使用完当前 WebView 之后,只需要在用户退出页面的时候把正文数据清空,这样进入下一个页面的时候就能够继续复用这个 WebView 重新注入数据即可。

通过这个手段,我们既避免了频繁在后台预创建 WebView 对用户刷 Feed 体验的影响,把用户进入页面时候的预热模板命中率从 53% 提升到 92%,优化了用户体验。

预热模板命中率

网络优化

说完我们在模板 WebView 方面的优化之后,再介绍一下我们在内容请求上的优化。

CDN 加速

由于头条详情页请求有以下特点

  1. 流量大,之前说过,看新闻作为用户在头条的核心场景,每天都有上亿用户在使用头条,详情页的数据流量十分大。
  2. 数据属性基本不变,在详情页的请求中,很多热点文章是重复渲染计算的,正文、标题、作者信息、图片控制以及一些样式和业务逻辑渲染是基本不变的,这部分重复计算耗费了带宽、服务器资源,是比较没有必要的。
  3. 用户分布广,网络状况难以保证,头条的用户量很大,覆盖了各种运营商网络和网络状态,网络质量无法得到很好的保证。而 CDN 能够将数据缓存在各地的边缘节点,用户就近接入了边缘节点,避免在网络质量无法保证的公网上长时间传输,从而提高了响应速度和响应的成功率。
  4. 接口数据大,由于正文数据的存在,接口返回的数据常常会很大,如果每一次都实时返回,对网络的压力会比较大,可能会把带宽打满而影响其他服务

所以我们将详情页内容数据分为静态和动态两部分,将正文内容、标题、作者栏等用户主要消费的又基本不变的内容托管到了 CDN 上。

CDN 的全称是 Content Delivery Network,即内容分发网络。其目的是通过在现有的 Internet 中增加一层新的网络架构,将网站的内容发布到最接近用户的网络“边缘”,使用户可以就近取得所需的内容,提高用户访问网站的响应速度。CDN 有别于镜像,因为它比镜像更智能,或者可以做这样一个比喻:CDN=更智能的镜像+缓存+流量导流。因而,CDN 可以明显提高 Internet 网络中信息流动的效率。从技术上全面解决由于网络带宽小、用户访问量大、网点分布不均等问题,提高用户访问网站的响应速度。

托管到 CDN 之后,全国各地的用户可以直接从最佳节点就获取到详情页数据,也大大节省了带宽成本。

容灾

1. 多域名备份

为了防止某个 CDN 出现故障,导致服务雪崩,服务端会下发多个 CDN 链接,当用户访问当前 CDN 节点的出异常时,可以快速自动切换到下个 CDN 节点。

2. 快速超时

一般的超时策略,客户端在请求时,会遍历请求 CDN 1、2、3。如果这些 CDN 都请求失败,则整个网络请求算作失败。

但这个方案的问题是,假设请求 CDN 的超时时间是 15s。如果 CDN 1 出现故障,则需要等待 15s 才能切换到 CDN 2 上,这对于详情页的加载时间来说是不可接受,如果用户网络突然变差,则需要等待 45s 才能返回失败展示错误页。

基于此我们设计了详情页请求的快速动态超时策略

  • 单次请求 CDN 的超时时间,根据上次成功请求 CDN 的值计算,因子 1.5(z 值)。且最小为 1s(x 值),最大为 4s(y 值)。超过这一时间不取消,直接请求下个 CDN。
  • 单次请求 CDN 有一个硬性超时时间 4s(w 值,w 需>=y),超过这一时间请求取消。n 个 CDN 的请求全部取消后反馈用户失败。

几个 case:

  • 第 1 个 CDN 突然挂掉(假设上次成功请求的耗时为 a) 下一次请求:第一个 CDN 很快超时(a _ 1.5);开始请求第二个 CDN(超时时间为 a _ 1.5,但实际上 b 秒就会返回请求)。用户本次等待时间为 a _ 1.5 + b 下两次请求:第一个 CDN 很快超时(b _ 1.5);开始请求第二个 CDN(超时时间为 b _ 1.5,但实际 c 秒就会返回请求)。用户本次等待时间为 b _ 1.5 + c

  • 用户突然进入了一个网络很差的环境(假设上次成功请求的耗时为 a) 下一次请求:第一个 CDN 很快超时(a _ 1.5);开始请求第二个 CDN(a _ 1.5)也超时;开始请求第三个 CDN(a _ 1.5)。最后一个请求会在 a _ 3 + w 后返回失败(这个值会在 12s 以内)。

可以看到,通过多域名备份和快速超时的策略,即使用户在网络或者服务异常的情况下,也能快速恢复或者让用户能感知到自身网络问题。

渲染优化

当我们在模板层和网络层优化到极致的时候,限制我们的就是 WebView 的渲染速度了!

服务端预渲染

正常来讲,正常的内容数据可能是类似 JSON 等数据,客户端获取到数据之后,将数据注入给前端,前端还需要将 JSON 数据跟模板进行组装,拼上 HTML 标签等模板了之后再呈现到 WebView 渲染,导致前端渲染上耗时也比较久。

为了提高用户的首屏效率,我们在服务端就会把所有的详情页正文的 HTML 数据组装好,通过将服务端直出内容注入到页面中时,可以直接给 WebView 进行渲染,对于其他动态下发的内容(比如相关搜索),前端再进行二次异步处理,提升用户效率。

客户端渲染

一般来说,我们正文中所有内容都是通过 WebView 渲染,经过上述的优化之后,文章的文字部分渲染效率已经很高了,但是实际场景中,很多文章会包含比较多的图片和视频场景。

在实际场景中,WebView 渲染非文字内容会存在以下问题:

  1. 相比于文字内容,非文字内容比如说图片和视频类资源的渲染对于 WebView 来说渲染效率比较差
  2. 在详情页中文章有大量图片的场景,对于 WebView 的渲染内存占用和滑动体验也有问题
  3. 最后,如果用户多次打开同一篇文章,这篇文章中的图片也会存在多次加载的问题,无法与客户端进行缓存共享,对用户的流量也是一种浪费。

所以在详情页中,我们会将图片和视频等非文字内容通过原生组件的方式放在客户端进行渲染,既可以提高渲染效率,也可以减少不必要的流量消耗。

原生化渲染还有一个好处,图片越来越成为文章体验的重要部分,对于多图文章,我们在 Feed 页面也可以智能加载详情页需要的图片,增加用户的文章首屏体验。

白屏优化

讲完了性能优化,最后再分享一下我们对详情页白屏率的一些优化,其实很多用户反馈白屏问题大部分都可能是由于网络等问题导致页面加载时间过长,导致用户从体验上观感是白屏了,这部分通过上面分享的性能优化手段已经能够解决,所以下面只是简单介绍下一些非网络原因的白屏问题。

我们通过白屏检测和上报之后的数据分析之后发现,非网络原因导致的详情页的白屏问题大体是 WebView 加载的问题。

在 iOS 中,我们使用的是系统提供的 WKWebView,WKWebView 是运行在一个独立进程中的组件,所以当 WKWebView 上占用内存过大时,WKWebView 所在的 WebContent Process 会被系统 kill 掉,反映在用户体验上就是发生了白屏。

根据网上的做法,我们可以在 WKWebView 提供的回调 webViewWebContentProcessDidTerminate 函数中通过 reload 方法重新加载当前页面恢复,但是这种情况只适用于通过 loadRequest 加载的请求,在详情页中,由于使用了模板化的 WebView 中,重新 reload 只能重新 reload 模板,并不能正常恢复整个详情页,需要客户端重新加载模板之后再重新注入数据。

另外由于我们有预热模板的逻辑,所以可能在进入详情页的时候使用的 WKWebView 就已经崩溃,在调用 JS 注入数据时会直接返回失败,失败时,我们会尝试重新加载模板。但后来实际操作中发现一个问题,如果直接调用数据注入的方法,等待系统 WebView 返回失败的回调耗时比较久,所以后续也调整了数据注入的接口,我们提前在注入的脚本中判断是否存在数据注入的接口,如果不存在,就说明模板存在问题,直接重试即可。

而在 Android 中,我们采用的是自研内核 WebView,也会遇到一些奇奇怪怪的坑。

  1. 多线程读模板文件问题,WebView 在运行中会读取的文件模板,如果此时另外一个线程同时更新模板文件时,就出现了模板加载问题,所以需要保证模板加载的原子性
  2. Render 卡死问题,内核是一个比较复杂的逻辑,内部渲染极少数情况也会出现 Render 卡死问题,但是在详情页整体用户的量级下,即使只有十万分之一的可能,对用户来说也是一个比较大的问题,此时我们会从业务上做白屏监控进行重试

当然不管是 iOS 和 Android, WebView 加载的逻辑都比较复杂,有时候怎么重试也无法成功,这个时候我们会直接降级到加载线上的详情页,优先保证用户的体验。

总结

限于篇幅原因,我们还做了很多其他事情,包括请求精简,push 文章预拉取,数据注入的方式优化等等,也做了很多其他的方向的探索,这里不做展开,希望有机会能再分享给大家。

最后总结一下我们在优化详情页打开速度之后的一些想法

  • 数据很重要,我们在优化加载速度之前做的第一件事情其实是建立了一个详情页的数据看板,只有通过数据我们才能真正了解目前线上用户的现状,从真实用户的体验中找到瓶颈和优化点。
  • 用户体验优先,优化方案有很多,除了加载速度之外,还需要从整体应用体验出发,选择对用户最佳的方案
  • 追求极致,其实最开始的优化是比较简单的,但是越到后面越难,需要一点点抠细节,才能达到极致的用户体验

更多分享

Android Camera 内存问题剖析

字节跳动自研线上引流回放系统的架构演进

iOS大解密:玄之又玄的KVO

Android '秒' 级编译速度优化

技术团队

技术团队不仅致力于在业务上不断深耕挖掘,在技术上也一直在追求极致的用户体验。

如果你也向往在一个亿级 DAU 业务里成长,也期待在技术上有突飞猛进的提升,欢迎你加入我们。

无论你是 iOS/Android/前端/后端,我们在深圳/北京/广州等你来,一起做更有挑战的事!简历投递邮箱: tech@bytedance.com ;邮件标题:姓名-工作年限-头条技术团队


欢迎关注字节跳动技术团队

页切图过程中div+css命名规则


标签属性命名规范 (建议)

下划线连接符命名法“hello_world”

中杠 连接符命名法“hello-world”

骆驼式命名法“helloWorld”


  内容:content/container 导航:nav 侧栏:sidebar    
  栏目:column 标志:logo 页面主体:main   
  广告:banner 热点:hot 新闻:news
  下载:download 子导航:subnav 菜单:menu
  搜索:search 页脚:footer 滚动:scroll
  版权:copyright 友情链接:friendlink 子菜单:submenu
  内容:content 标签页:tab 文章列表:list
  注册:regsiter 提示信息:msg 小技巧:tips
  加入:joinus 栏目标题:title 指南:guild
  服务:service 状态:status 投票:vote
   尾:footer 合作伙伴:partner 登录条:loginbar
  页面外围控制整体布局宽度:wrapper 左右中:left right center   
  
  
(二)注释的写法:
  /* Footer */
  内容区
  /* End Footer */
  
  
(三)id(具有唯一性)的命名:
  
  
(1)页面结构
  容器: container 页头:header 内容:content/container
  页面主体:main 页尾:footer 导航:nav
  侧栏:sidebar 栏目:column 左右中:left right center
  页面外围控制整体布局宽度:wrapper
  
(2)导航
  导航:nav
  主导航:mainbav
  子导航:subnav
  顶导航:topnav
  边导航:sidebar
  左导航:leftsidebar
  右导航:rightsidebar
  菜单:menu 子菜单:submenu 标题: title 摘要: summary
  
  
(3)功能
  标志:logo
  广告:banner
  登陆:login
  登录条:loginbar
  注册:regsiter
  搜索:search
  功能区:shop
  标题:title
  加入:joinus
  状态:status
  按钮:btn
  滚动:scroll
  标签页:tab
  文章列表:list
  提示信息:msg
  当前的: current
  小技巧:tips
  图标: icon
  注释:note
  指南:guild
  服务:service
  热点:hot
  新闻:news
  下载:download
  投票:vote
  合作伙伴:partner
  友情链接:link
  版权:copyright
  
  
(四)class的命名:
  (1)颜色:使用颜色的名称或者16进制代码,如
  .red { color: red; }
  .f60 { color: #f60; }
  .ff8600 { color: #ff8600; }
  (2)字体大小,直接使用"font+字体大小"作为名称,如
  .font12px { font-size: 12px; }
  .font9pt {font-size: 9pt; }
  (3)对齐样式,使用对齐目标的英文名称,如
  .left { float:left; }
  .bottom { float:bottom; }
  (4)标题栏样式,使用"类别+功能"的方式命名,如
  .barnews { }
  .barproduct { }
  
  
注意事项:
  1.一律小写;
  2.尽量用英文;
  3.不加中杠和下划线;
(我倒是经常加)
  4.尽量不缩写,除非一看就明白的单词.
(偷懒经常缩写)
  主要的 master.css 模块 module.css 基本共用 base.css
  主题 themes.css 专栏 columns.css 打印 print.css
  文字 font.css 表单 forms.css 补丁 mend.css
  布局,版面 layout.css