Skip to content

HTML5 并没有直接引入新的样式设计,而是通过增强 CSS(层叠样式表)和支持新的 CSS 属性来实现样式设计的改进。

HTML5 的样式设计主要通过以下几个方面:

  1. CSS3 增强:HTML5CSS3 是紧密相关的,HTML5 的出现使得 CSS3 得到更广泛的支持。CSS3 引入了许多新的样式属性和功能,如渐变、阴影、圆角、动画、过渡等,使得开发者能够实现更加复杂和独特的页面样式。

  2. 媒体查询(Media Queries):HTML5 支持媒体查询,使得开发者可以根据设备的特性(如屏幕宽度、高度、方向等)来应用不同的样式,从而实现响应式设计,使页面在不同设备上显示更加友好和适配。

  3. Web 字体(Web Fonts):HTML5 引入了 Web 字体的支持,使得开发者可以通过 @font-face 规则在页面中引入自定义字体,从而实现更丰富和独特的字体设计。

  4. CSS 预处理器(CSS Preprocessors):HTML5 的出现也推动了 CSS 预处理器的流行,如 SassLess。这些预处理器使得 CSS 的编写更加高效和易维护,支持变量、嵌套、混合等功能,帮助开发者更好地组织和管理样式。

  5. 响应式框架(Responsive Frameworks):随着 HTML5 的发展,出现了许多响应式设计的前端框架,如BootstrapFoundation等。这些框架提供了丰富的样式和组件,使得开发者能够快速构建出具有良好响应性和一致性的页面。

HTML5 的样式设计并不是独立的功能,而是通过对 CSS 的增强和支持新的 CSS 属性,使得样式设计变得更加丰富和灵活。

开发者可以借助 CSS3的特性、媒体查询、Web 字体等技术,创建更具有创意和吸引力的网页样式。同时,CSS 预处理器和响应式框架也为样式设计提供了更高效和便捷的工具和解决方案。

8-1.Web Fonts

@font-face 是CSS中的一个规则,它允许开发者在Web页面中引入自定义字体,并让浏览器下载并渲染这些字体。

通过 @font-face 规则,开发者可以在网页中使用非系统默认的字体,使得页面可以显示更丰富、更独特的字体样式。

@font-face 可设置的常用属性有:

  1. font-family 用来定义新的字体名
  2. src 用来定义字体引用
  3. font-weight 可设置字重。
  4. font-style 可设置字斜。
  5. unicode-range 可以控制字体在哪些字符范围内生效,从而减小字体文件的大小,提高网页加载性能。

关于 src 属性,可设置 local() 属性和 url() 属性。

css
@font-face {
  font-family: 'STFangsong';
  src: local('STFangsong');
}

@font-face {
  font-family: 'STFangsong';
  src: local('STFangsong') local('MLingWaiMedium-SC');
}

@font-face {
  font-family: 'STFangsong';
  src: local('STFangsong') url('./fonts/ZCOOLXiaoWei-Regular.ttf') format('truetype');
}

其中 local() 代表引用客户计算机上已安装的字体。而 url() 则是加载项目中指定路径的字体。

使用 local() 函数可以增加字体的加载效率,避免不必要的网络请求,但需要确保字体在用户计算机上存在并能正确显示所需的字体样式。

可使用 local() 或者 url() 连续定义多个字体。如果前者字体不存在,会加载后续字体,直到寻找到为止。

html
<style>
  .wrapper {
    padding: 20px 0;
  }
  .wrapper > p {
    text-align: center;
  }
  /* macos上 默认字体是苹方-简 常规体  */
  /* 华文仿宋 */
  @font-face {
    font-family: 'STFangsong';
    src: local('STFangsong') url('./fonts/ZCOOLXiaoWei-Regular.ttf') format('truetype');
    font-weight: 400;
    font-style: normal;
  }
  /* 凌慧体-简 中黑体 */
  @font-face {
    font-family: 'LingWai';
    src: local('MLingWaiMedium-SC');
    font-weight: 400;
    font-style: normal;
  }
  /* 娃娃体-简 常规体 处理书引号 */
  @font-face {
    font-family: 'Quote';
    /* src: local('STFangsong'); */
    src: local('DFWaWaSC-W5');
    unicode-range: U+300a, U+300b;
  }
</style>
<div class="wrapper" style="font-family: 'STFangsong';font-size: 24px;">
  <p><span style="font-family: 'Quote';">《</span>登高<span style="font-family: 'Quote';">》</span></p>
  <!-- <p>《登高》</p> -->
  <p>风急天高猿啸哀,渚清沙白鸟飞回。</p>
  <p>无边落木萧萧下,不尽长江滚滚来。</p>
  <p>万里悲秋常作客,百年多病独登台。</p>
  <p>艰难苦恨繁霜鬓,潦倒新停浊酒杯。</p>
</div>

上述 demomacos 上展示如下:

登高

风急天高猿啸哀,渚清沙白鸟飞回。

无边落木萧萧下,不尽长江滚滚来。

万里悲秋常作客,百年多病独登台。

艰难苦恨繁霜鬓,潦倒新停浊酒杯。

TIP

当涉及 Web Font 的格式时,主要有以下几种常见的格式:

  1. WOFF(Web Open Font Format)WOFF 是专门为 Web 优化的字体文件格式,是对 TTF 格式的压缩和优化版本,具有较小的文件大小和更好的加载性能。在现代浏览器中有广泛的支持,是在 Web 页面上使用自定义字体的首选格式。

  2. TTF(TrueType Font)TrueType 是一种常见的字体文件格式,最初由 AppleMicrosoft 联合开发,支持矢量图形,适用于桌面应用程序和操作系统。在 Web 开发中,可以作为 WOFF 的备选格式,以提供更广泛的浏览器兼容性。

  3. EOT(Embedded OpenType)EOT 是由 Microsoft 开发的一种字体文件格式,主要用于 Internet Explorer 浏览器。然而,由于现代浏览器都支持 WOFF 格式,EOT 已逐渐被弃用,不再推荐使用。

  4. SVG(Scalable Vector Graphics)SVG 是一种矢量图形格式,也可以用于存储字体数据。但由于 SVG 字体文件的体积较大,不如 WOFFTTF 文件压缩得好,因此在实际开发中较少使用。

根据目前的浏览器支持情况和字体文件的大小等因素,推荐在 Web 开发中使用 WOFF 格式的字体文件。

如果需要更广泛的浏览器兼容性,可以同时提供 TTF 格式的字体文件作为备选。

8-2.Icon Fonts

Web Fonts 指的是在计算机中使用自定义字体。

Icon Fonts 指的是在计算机中使用自定义字体图标。

通常对于网站图标,一共有 3 种处理方式:

  1. Image 引入。弊端是会增加页面请求、图片的大小和颜色不容易改变、高清晰度的图片质量越大。
  2. Sprites 引入。雪碧图相对来说,能够减少页面请求。但由于需要使用背景定位,因此对于开发和后期迭代新的雪碧图,这种方式也不理想。
  3. Icon Fonts 引入。

重点说一下 Icon Fonts 的优缺点:

优点:

  1. 可以方便地将任何 CSS 效果应用于它们。
  2. 因为它们是矢量图形,所以它们是可伸缩的。这意味着我们可以在不降低质量的情况下伸缩它们。
  3. 我们只需要发送一个或少量 HTTP 请求来加载它们,而不是像图片,可能需要多个 HTTP 请求。
  4. 由于尺寸小,它们加载速度快。
  5. 它们在所有浏览器中都得到支持(甚至支持到 IE6)。

缺点:

  1. 不能用来显示复杂图像
  2. 通常只限于一种颜色,除非应用一些 CSS 技巧
  3. 字体图标通常是根据特定的网格设计的,例如 16x16, 32×32, 48×48等。如果由于某种原因将网格系统改为 25×25,可能不会得到清晰的结果。

目前较为成熟的平台有阿里IconFont字节IconPark

由于目前项目大多数还是使用阿里的字体图标库,因此本节总结介绍下iconfont的引用方式

8-2-1.Unicode

unicode 是字体在网页端最原始的应用方式,特点是:

  1. 兼容性最好,支持 IE6+,及所有现代浏览器。
  2. 支持按字体的方式去动态调整图标大小,颜色等等。

首先引入平台上生成的 font-face 代码,设置一个 css 类,然后挑选相应图标并获取字体编码,应用于页面:

html
<style>
  @font-face {
    font-family: "iconfont"; /* Project id 4194819 */
    src:
      url("//at.alicdn.com/t/c/font_4194819_51wfkrn0vhv.woff?t=1690984463653")
        format("woff"),
      url("//at.alicdn.com/t/c/font_4194819_51wfkrn0vhv.ttf?t=1690984463653")
        format("truetype"),
      url("//at.alicdn.com/t/c/font_4194819_51wfkrn0vhv.svg?t=1690984463653#iconfont")
        format("svg");
  }
  .unicode {
    font-family:"iconfont" !important;
    font-size:16px;
    font-style:normal;
    -webkit-font-smoothing: antialiased;
    -webkit-text-stroke-width: 0.2px;
    -moz-osx-font-smoothing: grayscale;
  }
</style>

<span class="unicode" style="color: #F3AA60;">&#xe603;</span>

会展示一个点赞图标:

8-2-2.Font class

font-classunicode 使用方式的一种变种,主要是解决 unicode 书写不直观,语意不明确的问题。

unicode 使用方式相比,具有如下特点:

  1. 兼容性良好,支持 ie8+,及所有现代浏览器。
  2. 相比于 unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。
  3. 因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 unicode 引用。
  4. 不过因为本质上还是使用的字体,所以多色图标还是不支持的。

首先引入平台上生成的 link 代码,然后挑选自定义图标并引入即可:

html
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_4194819_zv32db2too.css">

<i class="iconfont icon-dianzan_active-copy-copy"></i>

会展示一个心形图标:

8-2-3.Symbol

Symbol 方式也可以称作 Svg Sprite,即 SVG 雪碧图。是一种全新的使用方式,是未来的主流。

它利用的是 SVG 中的 <symbol> 元素,提供了一系列图标集合。

与上面两种相比具有如下特点:

  1. 支持多色图标了,不再受单色限制。
  2. 通过一些技巧,支持像字体那样,通过 font-sizecolor 来调整样式。
  3. 兼容性较差,支持 ie9+ 及现代浏览器。
  4. 浏览器渲染 svg 的性能一般,还不如 png

首先同样是引入平台上生成的 symbol 代码,加入通用 css 代码(全局设置一次),然后挑选相应图标并获取类名:

html
<style type="text/css">
  .icon {
    width: 1em;
    height: 1em;
    vertical-align: -0.15em;
    fill: currentColor;
    overflow: hidden;
  }
</style>

<svg class="icon" aria-hidden="true" style="color: #2699ef;">
  <use xlink:href="#icon-dianzan_active-copy-copy"></use>
</svg>

<script src="//at.alicdn.com/t/c/font_4194819_zv32db2too.js"></script>

TIP

当从阿里图库中图标被添加至项目,如果编辑过项目图标的颜色或者图标本身是有颜色的,那么在通过 symbol 获取图标时会在 svgpath 中增加fill 属性,导致无法更改颜色。

如果需要动态修改颜色,可以采用按需求考虑一下两种方式:

  1. 下载 Js 文件后,然后查找 fill 属性,替换或者删除。

  2. iconfont.cn 上,全选项目中的文件,应用批量操作、批量去色。

8-3.Svg

SVG 的全称是 Scalable Vector Graphics

它是一种 XML 语言,类似 XHTML,可以用来绘制矢量图形,例如下面展示的图形。

SVG 可以通过定义必要的线和形状来创建一个图形,也可以修改已有的位图,或者将这两种方式结合起来创建图形。

图形和其组成部分可以形变(transformed)、合成、或者通过滤镜完全改变外观。

MDN 上对于 SVG 技术的论述,可以分作 3 部分:

  1. 基础使用
  2. 元素
  3. 属性

本节是针对 MDN 所述内容的重点归纳总结。目标是更好的理解 SVG 的元素构成和基本使用。

根本目的是为了在现实项目中更好的运用 Symbol Iconfont 以及 SVG Sprite 技术。

8-3-1.svg

<svg> 元素本身默认是 inline 行内元素。

与一般的行内元素如 span 不同的是,svg 行内元素有默认的宽高。

这一点与 canvas 元素是相同的。**在不设置宽高时,svgcanvas 元素默认的宽高都是 300 * 150

8-3-2.defs

<defs> 元素允许我们定义需要重复使用的图形元素。

defs 元素中定义的图形元素不会直接呈现。你可以在你的视口的任意地方利用 <use> 元素呈现这些元素。

我个人将 defs 元素的效果理解成 JavaScript 中的模块化。因为它将众多元素定义聚合在了一个模块内,然后可以通过 use 快速引用。

html
<svg width="150" height="100">
  <defs>
    <rect id="rect1" width="50" height="100" x="0" fill="#468B97" />
    <rect id="rect3" width="50" height="100" x="100" fill="#F3AA60" />
  </defs>
  <use xlink:href="#rect1"></use>
  <use xlink:href="#rect3"></use>
</svg>

要注意的一点,defs 元素不能使用 viewBox 属性,因此其内定义的元素必须显示的定义宽和高。

而且,经过笔者的测试,在 <use> 元素上设置 widthheight,并不能影响到引用的 defs 内元素的实际大小。

譬如,设置 <use> 的宽为 5、高为 10

html
<svg width="150" height="100" viewBox="0 0 150 100">
  <defs>
    <rect id="rect1" width="50" height="100" x="0" fill="#468B97" />
    <rect id="rect3" width="50" height="100" x="100" fill="#F3AA60" />
  </defs>
  <use xlink:href="#rect1" width="5" height="10"></use>
  <use xlink:href="#rect3"></use>
</svg>

TIP

defssymbol 元素功能很类似。但二者也有区别。

可以将 defs 理解成定义可重复使用的 SVG 元素片段

symbol 则是定义可重复使用的 SVG 图标

相对来说,symbol 元素比 defs 元素更高级一点。

8-3-3.symbol

<symbol> 元素允许我们定义一系列元素的集合。

symbol 元素中定义的图形元素不会直接呈现。你可以在你的视口的任意地方利用 <use> 元素呈现这些元素。

我个人将 symbol 元素的效果理解成 JavaScript 中的组件化。因为它将众多元素定义聚合在了一个模块内,然后可以通过 use 快速引用整个模块

html
<svg width="150" height="100">
  <symbol id="symbol">
    <rect width="50" height="100" x="0" fill="#468B97" />
    <rect width="50" height="100" x="100" fill="#F3AA60" />
  </symbol>
  <use xlink:href="#symbol"></use>
</svg>

可以发现 use 引用的是 symbol 集合,而非单个元素。

这是 symboldefs 高级的一点。

8-3-4.use

<use> 元素是 SVG(可缩放矢量图形)中的一个重要元素,用于重复使用已定义的图形。

它允许在同一文档中多次使用相同的图形或符号,从而减少了代码冗余,使得图形的维护更加简便。

html
<use xlink:href="URL" ... />

其中,xlink:href 属性指定了要重用的图形或符号的位置(URL),然后通过添加属性来调整该重用图形的位置、尺寸以及其他属性。

从以上的 demo 中,可以看出 <use> 可以结合 <defs> 或者 <symbol> 元素来使用。

SVG 的属性是严格区分大小写的

譬如 viewBoxviewbox 是不同的。

8-3-5.viewBox

可以设置 viewBox 属性的元素有 <svg><symbol><view><pattern><marker>

SVG 中的 viewBox 属性是用来定义坐标系统,而不是用来改变元素的实际尺寸。

viewBox 决定了坐标系中的哪个区域会被展示在 SVG 画布上,但它并不会改变元素的具体尺寸。

TIP

类比于 canvas 的话,可以将 viewBox 属性看做绘图面积

譬如:

html
<svg width="150" height="100"></svg>

上述代码代表的是,会绘制一个宽为 150、高为 100 的元素。

viewBox 代表的是绘图面积

基本语法为,viewBox="min-width min-height width height"

譬如:

html
<svg width="150" height="100" viewBox="0 0 3 2"></svg>

上述代码代表的是,会在 3 * 2 的盒子下绘制 svg 元素,并将它放大到 150 * 100 的比例。

html
<svg width="150" height="100" viewBox="0 0 3 2">
  <rect width="1" height="2" x="0" fill="#468B97" />
  <rect width="1" height="2" x="1" fill="#EF6262" />
  <rect width="1" height="2" x="2" fill="#F3AA60" />
</svg>

上述代码的实际效果如下:

需要注意的一点是,svg 设置了 viewBox ,但没有设置 widthheight 时,那么最终参照的宽和高会是父级元素

html
<div style="width: 300px; height: 200px;">
  <svg viewBox="0 0 3 2">
    <rect width="1" height="2" x="0" fill="#468B97" />
    <rect width="1" height="2" x="1" fill="#EF6262" />
    <rect width="1" height="2" x="2" fill="#F3AA60" />
  </svg>
</div>

实际效果会是 300 * 200

8-3-6.fill

属性 fill 可以用来设置元素的填充色。

譬如:

html
<svg width="150" height="100" viewBox="0 0 3 2">
  <rect width="3" height="2" x="0" fill="#468B97" />
</svg>

该属性也可以通过 css 来设置:

html
<svg width="150" height="100" viewBox="0 0 3 2" style="fill: #EF6262;">
  <rect width="3" height="2" x="0" />
</svg>

在实际开发中,会将 fillcurrentColor 结合起来,这样直接使用 color 来设置 svg 颜色,更接近开发习惯:

html
<style>
  svg {
    fill: currentColor;
  }
</style>

<svg width="150" height="100" viewBox="0 0 3 2" style="color: #EF6262;">
  <rect width="1" height="2" x="0" />
  <rect width="2" height="2" x="1" fill="#F3AA60" />
</svg>

8-3-7.工程化项目应用

在如今的工程化项目中,除了使用第三方 Icon Fonts,也可以直接在 webpack 项目中利用svg-sprite-loader使用 svg

svg-sprite-loader 其实利用的就是 svgsymbol 元素。

它会在 <body> 标签的顶部生成如下结构:

具体的使用方式步骤:

  1. 在项目中准备好 svgxml 文件,并在项目中的 main.js 全局引入, import @/assets/icons

之所以能使用上述语法,是因为在 src/assets/icons/index.js 中利用了 webpack 的导入:

js
const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('../icons', false, /\.svg$/)
requireAll(req)
  1. 利用 svg-sprite-loader 处理 svg 文件的解析:
js
{
  test: /\.svg$/,
  loader: 'svg-sprite-loader',
  include: [resolve('src/assets/icons')],
  options: {
    symbolId: 'icon-[name]'
  }
},
{
  test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
  loader: 'url-loader',
  options: {
    limit: 10000,
    name: utils.assetsPath('img/[name].[hash:7].[ext]')
  },
  // 注意 url-loader 中要将 icons 文件夹排除, 不让 url-loader 处理该文件夹
  exclude: [resolve('src/assets/icons')]
}
  1. 如果使用的是 vue-cli,则可以这样配置:
js
chainWebpack: config => {
  const svgRule = config.module.rule('svg')
  // 清空默认svg规则
  svgRule.uses.clear()
  //针对svg文件添加svg-sprite-loader规则
  svgRule
    .test(/\.svg$/)
    .use('svg-sprite-loader')
    .loader('svg-sprite-loader')
    .options({
      symbolId: 'icon-[name]'
    })
}

有可能在实际业务中,svg 不单单是组件式应用,也可能是背景图片或者 image 等等。

为了保证后述场景的正常进行,可以对上面的规则进行二次改造:

js
chainWebpack: config => {
  // 原有的svg图像处理loader添加exclude
  config.module.rule('svg')
   .exclude.add(resolve('src/assets/icons')).end()

  // 针对svg文件添加svg-sprite-loader规则
  config.module.rule('svgIcon')
    .test(/\.svg$/)
    .include.add(resolve('src/assets/icons')).end()
    .use('svg-sprite-loader')
    .loader('svg-sprite-loader')
    .options({
      symbolId: 'icon-[name]'
    })
}
  1. 封装引入 svg 的组件,以 vue 项目创建一个 SvgIcon 组件为例:
vue
<template>
	<svg
		aria-hidden="true"
		class="svg-icon">
		<use :xlink:href="iconName"></use>
	</svg>
</template>

<script>
export default {
	name: 'SvgIcon',
	props: {
		name: {
			type: String,
			required: true
		}
	},
	computed: {
		iconName() {
			return `#icon-${this.name}`
		}
	}
}
</script>

<style scoped>
.svg-icon {
	width: 1em;
	height: 1em;
	vertical-align: -0.15em;
	fill: currentColor;
	overflow: hidden;
}
</style>
  1. 可以全局注册 SvgIcon 组件,方便使用:
js
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg组件

// register globally
Vue.component('SvgIcon', SvgIcon)