为了账号安全,请及时绑定邮箱和手机立即绑定

如何编写高质量的 HTML 代码

编者寄言:
本文主要为编者读书笔记,在文章里面很多话是掺杂了编者自己的见解,如果有哪里出现错误或者用词不严谨,请友善留言,编者会及时去更改。

本文很多地方只是简单说了一下应该注意的地方,具体代码部分请自行上网查找,给您带来的困扰,非常抱歉。

这篇文章的主要目的是给一些自学 以及 对 HTML 5刚刚入门的朋友提供一些从编码习惯方面的帮助,如果您觉得这篇文章对您有帮助,请给编者点赞留言,鄙人感激不尽。

第零章 前言
web 前端开发是从网页制作演变而来的,在名称上有很明显的时代特征。

网页制作是 Web1.0时代的产物,网站内容主要是静态的,用户使用网站的行为也以浏览为主。

2005年进入 Web2.0时代,网页不再只承载单一的文字和图片,网页上软件化的交互形式为用户提供了更好的使用体验,这些都是基于前端技术实现的。

以前会 PS 和 Dreamweaver 就可以进行开发,而现在的网页制作更接近传统的网站后台开发,所以现在叫做 Web 前端开发。

Web 前端开发人员

主要职责:把网站的界面更好的呈现给用户

1.掌握基本的 web 前端开发技术
    HTML
    CSS
    DOM
    BOM
    Ajax
    JS
    还需要清楚的了解它们在不同浏览器中的兼容情况,渲染原理以及存在的 BUG
2.一名合格的前端工程师知识结构中
    网站性能优化
    SEO
    服务器端基础知识
3.学会运用各种工具进行辅助开发
4.除了掌握技术层面知识,还需要掌握理论层面的知识
    代码的可维护性
    组件的易用性
    分层语义模板
    浏览器分级支持

之前包括新浪,搜狐,BAT 等各种规模公司都对自己的网站进行了重构,因为如下两点原因。

1.根据 W3C 标准结构重构之后,可以让前端代码组织更有序,显著改善网站的性能,还可以提高可维护性,对搜索引擎也更友好;

2.重构后的网站能带来更好的用户体验,重构之后的网站,文件更小,下载速度更快
而我们的 DHTML 让用户操作更炫,Ajax 可以实现无刷新的数据交换,操作更流畅,这也给我们现在的前端开发带来了新的体验。

第一章:从网站重构说起
Web 标准 --------- 结构,样式和行为的分离

分割成 .html .css .js 三个文件

而我们现在前端开发的现状

浏览器层面
    各大浏览器之间存在非常多的差异问题
技术层面
    标准出现时间不长,对某些效果没有特定的解决方案,每个人对好的网站标准都不一致
团队合作层面
    合作不好,页面可能出现各种漏洞,需要不停的打补丁,到最后代码千疮百孔,没人愿意去维护

而我们在混乱的浏览器环境下,我们依旧要去打造高品质前端代码,提高代码的可维护性,想要做到提高品质我们可以从以下三点出发。

精简:减小文件体积,帮助客户端更快下载
重用:代码更精简,提升开发速度
有序:更清晰组织代码,使代码更易维护,有效应对变化

而具体如何去做到 HTML 代码的精简,提高重用,做到有序,我们会在之后的代码中一一给大家解释。

第二章:团队合作
首先我们先来揭秘一下,什么是前端开发工程师?

2.1 CSS 布局是前端开发工程师的基本功
日常工作中 CSS 的使用比重占到了所有技能的50%~70%,甚至有的公司只要求会用 CSS,
但是需要注意兼容问题
2.2 对 JS 使用有要求
不仅仅会原生 JS,还要会使用 JS 类库和 Ajax

JS:浏览器默认支持的脚本语言

Ajax:一种利用 JS 和 XMLHttpRequest 对象在客户端和服务器端传送数据的技术,因为 XMLHttpRequest 对象也是用 JS 去创建的对象,所以某种意义上来说,Ajax 是 JS 的一个子集

注意:Ajax 只是一种提交数据的方式,与传统的表单提交方式确实有所不同,但是核心的内容非常少,学起来并不难

JS 类库:浏览器默认支持的 JS 会因为浏览器的不同而有所差异,同时 JS 原生提供的方法有些不那么好用,所以出现了 JS 类库这个东西,JS类库只是在原生 JS 中封装了跨浏览器兼容的特性并拓展了一些原生 JS 没有的功能
2.3 要了解后台语言
1.知道服务器端工程师在生产页面时会如何去进行输出,以便方便他们套脚本的模版

2.在写 Ajax 应用的是时候,可以自己模拟服务器端输出,方便调试

3.对前端和服务器端如何配合有清晰的大局观认识,了解数据传递的整个流程,
以配合工程师共同制定复杂效果的实现方案
2.4 欲精一行,先通十行

图片描述
2.5 增加代码的可读性——注释
直接团队合作

间接团队合作
2.6 提高重用性——公共组件和私有组件的维护
避免 A 为了实现某种效果,去写了一段代码,而 B 又去从新写了一遍

提升代码的重用度

公共组件
    保持接口弹性
    高度模块化
    使用人比较多,不要轻易修改
    给其他人只读的权限,例如 SVN

私有组件
    自己用,但是还是要注意代码可读性

2.7 冗余和精简的矛盾——选择集中还是分散
所有公共组件全部放在一起,统一去加载,但是会造成冗余代码
例如 JQuery

所有组件精确划分,之后按需求去加载,但是使用太麻烦
例如 YUI
YUI----雅虎的前端框架

第三章:高质量的 HTML
3.1 标签的语义

图片描述
图片描述
3.2 为什么使用语义化标签
搜索引擎看不到视觉效果,看到的只是代码,只能通过标签来判断内容的语义
3.3 如何判断你的标签是否语义良好
去掉样式,看网页结构是否组织良好有序,是否仍然有很好的可读性
推荐一个FireFox插件,WebDeveloper,可以去掉界面中的 CSS 样式,以此来查看你的代码的稳定程度
3.4 语义化标签应注意的一些其他问题
尽可能的少使用无语义标签 div 和 span

在语义不明显,既可以用p 也可以使用 div 的地方,尽量用 p ,
因为 p 默认情况下有上下间距,去掉样式后可读性更好,对兼容特殊终端有利

不要使用纯样式标签,如 b,font,u 等,改用 CSS 设置
第四章:高质量的 CSS
4.1 为了确保向后兼容,浏览器厂商发明了标准模式和怪异模式这两种方法来解析网页
怪异模式通常模拟老式浏览器以防止老站点无法工作

4.2 怪异模式如何被触发?
与 DTD 有关,即文档定义类型,例如下面介绍的几种。

4.2.1 html:4s HTML4.01严格型

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
</head>
<body>

</body>
</html>

4.2.2 html:xt XHTML严格型

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
</head>
<body>

</body>
</html>

如果漏写 DTD 声明,Firefox 仍然会按照标准模式来解析网页,但是在 IE6/7/8 中会触发怪异模式

4.3 如何组织 CSS
一部分是 CCSS 的 API,重点是如何控制页面内元素的样式,但是这些知识都是基础,有对错的明显区别。

另外一部分是 CSS 框架,重点是对 CSS 进行组织,相反,这些则是一些高级的用法,没有明显的对错,只有更加优化。

4.4 常见组织CSS 的方式
4.4.1 一般形式

控制字体:font.css
控制颜色:color.css
控制布局:layout.css
4.4.2 另外一种形式
头部样式:head.css
底部样式:foot.css
侧边栏样式:sidebar.css
主题样式:main.css
4.4.3 推荐形式
page.css

三者中重用度最低的内容,高度重用的内容我们会放在 common 中,
而一般重用度低的内容我们放在 page 中。

page 层专门用于提供页面级别的样式内容,可以根据页面中的内容去任意修改,增添

page 可以根据个人用户的需求去任意添加,但是需要注意命名的规范,
不要多个人使用了相同的名字

common.css

三者中间层,提供组件级的 CSS 类

我们在设计 common 类的时候,首先需要将我们的界面里面的内容进行“模块化”,
有一些模块是很少去使用的,而另外一些是经常会使用的内容,
而我们则需要将里面的内容进行提取出来,放在 common 中

common 一般是网站级别的,不同的网站有不同的基础样式风格,
所以我们的 common 一般推荐由团队中的某一个人去进行维护,统一管理

base.css

三者最低层,用于提供 reset 功能和粒度最小的通用类———原子类

这一层会被所有界面引用,是页面样式所有需依赖的最底层

base 层设计的内容会被不同的页面共同使用,所以代码内容一定要通用性强,精简

base 层相对稳定,基本不需要进行维护

例子:帮助理解

base 是房子的地基,一旦确定,轻易不会去进行更改

common 是房子内部的一些基础组件,例如门的形状,窗户的大小等这些会经常被使用,
但是不同的房子,使用的样式有各不相同的内容

page 是我们房子内部使用的具体内容,例如我们使用的灯是什么样子的,我们使用的桌子
是什么样子的,这些都是我们根据我们具体的页面需要去进行特定的设置的内容

4.4.4 page.css 中需要注意的内容
首先是进行 reset

不要去使用通配符,首先性能很低,其次会导致 css 的继承性,
设置样式的时候会多写很多额外的代码

其次是进行 通用原子类

例如:
.f12{font-size:12px}

    通用性:任何页面都可以使用
    原子性:一个类只设置一个样式,不可再分

特殊说明

.fl 和 .fr 类 (float:left float:right)

在设置浮动的同时还需要进行设置,display:inline
    为了解决 IE6 的双倍边距 BUG

    在 IE 6之下,对元素设置了浮动,
    又设置了 margin-left 或者 margin-right 的时候,
    我们的 margin 会加倍

.bc 类 (.blockCenter)

在使块级元素进行居中的时候,我们直接使用并不足以让内容居中,
我们还需要设置宽度,需要与其他设置了宽度的类去进行连用

<div class= “bc w100”></div>
.bc{ margin-left:auto;margin-right:auto;}
.w100{width:100px;}

.clearfix 类

.clearfix:after{ content:”.”;display:block;height:0;clear:both;visibility:hidden}
.clearfix:after{ content:”.”;display:block;height:0;clear:both;overflow:hidden}

我们需要在 content 中放置一定的内容
推荐使用 overflow:hidden 去清除内容
.zoom 类

.zoom{ zoom:1}

不是 CSS 中标准属性,而是 IE 中专有属性
目的是触发hasLayout这个 BUG

因为 IE 6 会将 height 按照 min-height 解析

IE 7 出现之前推荐使用的触发方式是 height:1%;

但是 IE 7 发布之后上面的方式就不适用了,而是改为 zoom:1(页面倍率1倍)

4.5模块化 CSS ———在 CSS 中引入面向对象的编程思想
4.5.1 不要滥用子选择符

团队开发的时候,如果你经常使用子选择符,当别人去接手你的代码的时候可能会让别人直接以你经常使用的那个子选择符作为选择符,可能会导致一些出乎意料的以外发生
4.5.2 命名注意的事项
驼峰命名
用于区分不同的单词
划线
表明从属关系
4.5.3 多用组合,少用继承
我们在之前的开发过程中经常喜欢对每一个类去单独设置一个样式

实际上当我们的内容非常多的时候,会造成我们的 CSS 样式呈现爆炸式的增长

在面向对象的思想中,非常重要的一点就是“多用组合,少用继承”

将多个样式进行拆分,让单一的CSS 样式类去控制特定的 CSS 样式

利用 Class 选择器可以同时挂多个名字来实现多样式的组合控制
4.5.4 处理上下级的 Margin
需要注意,如果我们不确定模块上下的 Margin是否是固定的,

最好不要将它直接写到模块的类中,而是去使用类的组合,

单独为上下的 margin 去设置相应的边距,

而且最好不要混用 margin-top 和 margin-bottom,小心“吃边距”
4.5.5 低权重原则———避免滥用子选择器
我们都知道,当不同选择符的样式设置有冲突的时候,会采用权重高的选择符设置样样式

那么我们设置样式的时候就一定是越精确就越好么?

当然不是,当我们对之前的一个属性设置了某种样式,那么在下面,我们去再去修改它的样式,

就要将我们的权重设置的更加高一些,这样当代码量上升到一定程度之后,

有可能会造成,我们每次去设置一个新的属性,都必须先去设置一堆代码

所以我们为了保证我们的样式容易被覆盖,提升可维护性,CSS 选择符的权重应该尽可能的保持低
4.5.6 CSS sprite
我们在设置页面的导航条的时候,经常会遇到一个效果,

就是当我们的鼠标放在我们的导航条上的时候,我们的默认背景图片去改变颜色

基础的改变方法是使用 hover ,但是会产生一个问题,hover 并不会立马被加载,

而是当我们的鼠标划过的时候,才开始加载,在网速差的情况下,我们的背景都会显示为空白的

这时候我们就可以使用另外一个特性,就是我们的 background-position

将我们的默认状态图片和滑动状态图片合并成一张图片,在滑动的是去更改定位位置,

我们称这种技术为图片翻转技术,演化到最后就是我们的 CSS sprite

好处不止是解决了图片空白的问题,还减少了服务器压力,

大型网站基本都采用了这种方式去进行页面设置
但是需要注意

它能进行合并的只能是用于背景的图片,如果使用 img 时也去使用这种技术,会降低我们的页面的可读性

对于横向和纵向平铺的图片,也不能去使用 CSS sprite

其次就是,既然使用了定位,对位置坐标的要求就非常精准,
这会一定程度上影响我们的开发进程,
另外一个问题就是会极大的降低代码的可拓展性和可维护性。

是否使用这种技术主要是取决于网站的流量
4.5.7 CSS常见问题
4.5.7.1 CSS 的编码风格问题

单行式
阅读性会差一些,但是可以有效减少 CSS 文件的行数,提高开发速度,也能减少 CSS 文件的大小

多行式
可读性强,但是会使 CSS 文件的行数过多,编辑时需要来回去拖动,影响效率,其次就是过多的换行会影响 CSS 文件的大小

具体哪种好,还是看个人喜好以及公司要求
4.5.7.2 尽量多去使用 Class ,少用 ID
1.ID 只能出现一次,class 可以出现多次

2.ID选择器权重是100 , 而 Class选择器是 10

3.原生 JS 提供 getElementById()方法,但是 原生 JS 不支持 对应到相关 HTMLLIElement

4.如果我们的页面中对某个模块通过ID 去进行了绑定,那么当我们的需求改变,需要从新去增添一个相同的内容时,我们不能直接重用

所以我们有选择的情况下,尽量去用 class
4.5.7.3 CSS hack
不了解的同学可以先百度一下

CSS hack的解释

我们在使用 hack 的时候,常用的一般有三种方法。

IE 条件注释法

因为 IE 在 CSS 解析上存在很多的问题,
所以有时候我们需要针对不同 IE 版本去进行特定的 CSS 文件加载,
这时候我们就可以去使用官方的 hack 方法———IE 条件注释

只在 IE 下生效
    <!-- [if IE]>
    <![endif]-->

只在 IE 6 下生效
    <!-- [if IE 6]>
    <![endif]-->

只在 IE 6 以上版本生效
    <!-- [if gt IE 6]>
    <![endif]-->

        lte:小于等于
        lt:小于
        gte:大于等于
        !:不等于

选择符前缀法

在选择符前面加上一些只有特定浏览器才能看懂的前缀,以针对特定的浏览器生效

只针对 IE 6
    *html .test{width:100px;}
只针对 IE 7
    *+html .test{width:100px;}

需要注意,选择符前缀法不能用于内联样式表中
使用选择符前缀法时,对后面的浏览器兼容可能会出现问题

样式属性前缀法

在选择符前面加上一些只有特定浏览器才能看懂的前缀,以针对特定的浏览器生效

只针对 IE 6
.test{_width:100px;}
IE 6 和 IE 7
.text{*width:100px;}
使用样式属性前缀法时,对后面的浏览器兼容可能会出现问题

样式属性前缀法可以用于内联样式表

总结:虽然说理论上推荐使用 IE 条件注释法,但是实际工作中更常用的还是选择符前缀法和样式属性前缀法

4.5.7.4 解决超链接访问后 hover 样式不出现问题
有时候我们发现我们设置 hover 之后,第一次生效之后再次触发,
我们发现触发的并不是我们想要的效果

我们在写那四个伪类的时候,是存在一个 love hate 原则的。

love hate 原则(link visited hover active)

即首先需要设置 link ,之后依次是 visited hover active
4.5.7.5 hasLayout
在IE 中有时候会发生一个 BUG ,设置 border 的时候会发现 border 会断开,
而当我们滑动的时候又会发现我们之前断裂的部分又会连接起来

这个就是因为IE 专有属性 hasLayout 所引起的,hasLayout 是用于 CSS 解析引擎

现在一般使用 zoom:1 去触发 hasLayout

但是在使用DHTML 时,会失效

这时候我们需要 position:relative来触发,但是会带来副作用,这点需要注意。
4.5.7.6 relative , absolute 和 float
position:relative 和 position:absolute 都可以改变元素在文档流中的位置,
同时激活 top,right,bottom,left 和 z-index属性,这在未激活之前是无效的

网页虽然看起来是平面的二维结构,但是实际上它是存在 Z 轴的,
Z 轴的大小由 z-index 来决定,默认情况下所有的元素都是在 z-index 这一层的。

元素根据自己的 display 类型,
长宽以及内外边距等属性来排列在 z-index :0 这一层里,我们称之为 文档流

设置了相对定位和绝对定位之后,我们的元素会“浮”起来,也就是 z-index 大于 0 ,
它会改变正常状态下的文档流,但是相对定位会保留自己在 z-index 的位置,
虽然偏离了自己原来的位置,但是还是处于 z-index 这一层的。
但是绝对定位会完全脱离文档流,不在 z-index:0这一层保留占位符

而我们的 float 则不会让元素“上浮”到另外一层,
它仍然还在 z-index:0 这一层进行排列,
但是它还是会改变正常的文档流排列,影响到周围的元素,我们一般称之为提升半级。
下面是我自己画的图,如果理解有问题,请及时私信我。

图片描述
4.5.7.7 居中
水平居中

文本,图片等行内元素水平居中

给父元素设置 text-align:center;可以实现文本,图片等行内元素的水平居中
确定宽度的块级元素的水平居中

通过 margin-left:auto; 和 margin-right:auto; 来实现
不确定宽度的块级元素水平居中

以网页底部的分页模型来举例子,因为页面的分页个数是不确定的,所以没法直接用 auto 来实现居中
1.我们可以借助一个 table 标签来实现居中,因为 table 本身并不是一个块级元素,
如果不设置宽度的时候,宽度由内部元素去撑开,
这样我们即使不设置宽度也可以直接设置居中效果,但是这种做法增加了无语义标签,
而且加深了标签的嵌套层数

2.可以去改变块级元素的 display:inline 类型,
  之后去使用 text-align 去实现居中,这样我们虽然不用去增添无意义标签了,
  但是相对应的,我们就没有办法设置宽度和高度等,
  在某些特殊需求的 CSS 中可能会带来一些问题

3.我们可以去给父元素设置 float,
  然后父元素设置 position:relative 和 left:50%,
  子元素设置 position:relative 和 left:-50% 来实现水平居中。
  这样会保留块元素特性,而且不会增添无意义标签,也不会增加嵌套深度,
  但是由于设置了相对定位,在接下来的内容再使用定位可能会出现问题

竖直居中

父元素高度不确定文本,图片,块级元素的竖直居中

父元素高度不确定的文本,图片,块级元素的竖直居中是通过给父容器设置相同的上下边距实现的
父元素高度确定的单行文本的竖直居中

父元素高度确定的单行文本的竖直居中是通过给父元素设置 line-height来实现的,line-height 和 父元素的高度相同
父元素高度确定的多行文本的竖直居中

CSS 中存在一个用于竖直居中的属性,vertical-align,但只有父元素为td 或者 th 时,
才会生效,对于其他块级元素默认状态下是不支持 vertical-align 的,
如果想要使用,需要设置 display:table-cell,
但是display:table-cell 里面是不支持这个属性的,所以我们也可以直接去使用表格,
但是这样又会造成添加无语义标签,增加了嵌套的深度

所以我们可以迂回一下,在支持display:table-cell的浏览器中直接去设置,
在不支持display:table-cell的网页中,我们去使用 hack,去区别对待 IE 6 ,IE 7 ,
通过给父子两层元素设置 top:50%;和 top:-50%;来设置居中,
但是会造成后期维护困难,另外就是使用 hack 需要去设置绝对定位和相对定位,
这对后面的程序可能会造成不可预知的错误
4.5.7.8 z-index 的相关问题
设置 z-index 可以更改元素放置的位置

可以设置数值

正数
数值大的,会在上方去显示
0
正常
负数
显示的内容会存在于文档流下方,但是需要注意,
当我们设置 z-index 之后,我们这个区域的点击事件会被透明的 body 遮挡
4.5.7.9 margin 引起的元素位置重叠
我们的 margin 可以设置负数,以此也会产生边距的重叠,谁浮在上面,
取决于 HTML 标签出现的先后,后出现的标签浮于先出现的标签之上
4.5.7.10 flash 显示问题
flash 从插入网页中,如果和其他元素有重叠,那么我们无论设置什么 z-index ,
flash 都会浮在其他元素之上。
原因是浏览器在解析网页时,会首先判断元素的类型,如果是窗口类型的,
会优于非窗口类型的元素,显示在网页最顶端,如果同属于非窗口类型的,
才会去判断 z-index 的大小

flash 嵌入网页中有个 wmode 属性,用于指定窗口模式,其值有 window(窗口),
opaque(非窗口不透明),transparent(非窗口透明)三种。
其中 window 是以窗口形式显示,opaque和transparent 是以非窗口形式展示,
所以我们的解决方案就是设置 opaque和transparent,来取消窗口类型。
但是需要注意,flash 在IE 和 Firefox 中是用不同的标签去嵌入的,
所以我们需要对于两种标签去分别设置(IE用 object,Firefox 是以 embed 标签嵌入的)
4.5.7.11 select 显示问题
select 在 IE 6下同样是以窗口形式去显示的,这实际是 IE 6 的一个 BUG

我们可以用一个和test 同样大小的 iframe 放在 test 下面,
select 上面用 iframe 遮挡住 select

4.5.7.12 插入PNG 图片
png 格式因为其优秀的压缩算法和对透明度的完美支持,成为 web 中最流行的格式之一,
但是也存在一个问题,在 IE 6 中对 png 的透明支持并不好,
在原本应该透明的地方,在 IE 6 下会以浅蓝色去显示

我们可以使用IE 下私有的滤镜功能来解决这个问题

progid:DXImageTransform.Microsoft.AlphaImageLoader(src=‘png图片路径’,sizingMethod=‘crop’)

4.5.7.13 多版本 IE 并存方案
在实际生活中,IE 6,IE 7,IE 8还是占有着不小的市场份额,我们需要对不同的版本去进行兼容
在这里介绍一个神器:IETester,它可以提供 IE 5.5,IE 8多个 IE 版本共存,
而且 IETester 安装完成之后,桌面只有一个快捷方式,IE 的不同版本是通过标签的形式实现的。
文/MR_LP(简书作者)

点击查看更多内容
42人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消