HTML5
并没有直接引入新的样式设计,而是通过增强 CSS
(层叠样式表)和支持新的 CSS
属性来实现样式设计的改进。
HTML5
的样式设计主要通过以下几个方面:
CSS3
增强:HTML5
与CSS3
是紧密相关的,HTML5
的出现使得CSS3
得到更广泛的支持。CSS3
引入了许多新的样式属性和功能,如渐变、阴影、圆角、动画、过渡等,使得开发者能够实现更加复杂和独特的页面样式。媒体查询(
Media Queries
):HTML5
支持媒体查询,使得开发者可以根据设备的特性(如屏幕宽度、高度、方向等)来应用不同的样式,从而实现响应式设计,使页面在不同设备上显示更加友好和适配。Web
字体(Web Fonts
):HTML5
引入了Web
字体的支持,使得开发者可以通过@font-face
规则在页面中引入自定义字体,从而实现更丰富和独特的字体设计。CSS
预处理器(CSS Preprocessors
):HTML5
的出现也推动了CSS
预处理器的流行,如Sass
和Less
。这些预处理器使得CSS
的编写更加高效和易维护,支持变量、嵌套、混合等功能,帮助开发者更好地组织和管理样式。响应式框架(
Responsive Frameworks
):随着HTML5
的发展,出现了许多响应式设计的前端框架,如Bootstrap
、Foundation
等。这些框架提供了丰富的样式和组件,使得开发者能够快速构建出具有良好响应性和一致性的页面。
HTML5
的样式设计并不是独立的功能,而是通过对 CSS
的增强和支持新的 CSS
属性,使得样式设计变得更加丰富和灵活。
开发者可以借助 CSS3
的特性、媒体查询、Web
字体等技术,创建更具有创意和吸引力的网页样式。同时,CSS
预处理器和响应式框架也为样式设计提供了更高效和便捷的工具和解决方案。
8-1.Web Fonts
@font-face
是CSS中的一个规则,它允许开发者在Web页面中引入自定义字体,并让浏览器下载并渲染这些字体。
通过 @font-face
规则,开发者可以在网页中使用非系统默认的字体,使得页面可以显示更丰富、更独特的字体样式。
@font-face
可设置的常用属性有:
font-family
用来定义新的字体名。src
用来定义字体引用。font-weight
可设置字重。font-style
可设置字斜。unicode-range
可以控制字体在哪些字符范围内生效,从而减小字体文件的大小,提高网页加载性能。
关于 src
属性,可设置 local()
属性和 url()
属性。
@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()
连续定义多个字体。如果前者字体不存在,会加载后续字体,直到寻找到为止。
<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>
上述 demo
在 macos
上展示如下:
《登高》
风急天高猿啸哀,渚清沙白鸟飞回。
无边落木萧萧下,不尽长江滚滚来。
万里悲秋常作客,百年多病独登台。
艰难苦恨繁霜鬓,潦倒新停浊酒杯。
TIP
当涉及 Web Font
的格式时,主要有以下几种常见的格式:
WOFF(Web Open Font Format)
:WOFF
是专门为Web
优化的字体文件格式,是对TTF
格式的压缩和优化版本,具有较小的文件大小和更好的加载性能。在现代浏览器中有广泛的支持,是在Web
页面上使用自定义字体的首选格式。TTF(TrueType Font)
:TrueType
是一种常见的字体文件格式,最初由Apple
和Microsoft
联合开发,支持矢量图形,适用于桌面应用程序和操作系统。在Web
开发中,可以作为WOFF
的备选格式,以提供更广泛的浏览器兼容性。EOT(Embedded OpenType)
:EOT
是由Microsoft
开发的一种字体文件格式,主要用于Internet Explorer
浏览器。然而,由于现代浏览器都支持WOFF
格式,EOT
已逐渐被弃用,不再推荐使用。SVG(Scalable Vector Graphics)
:SVG
是一种矢量图形格式,也可以用于存储字体数据。但由于SVG
字体文件的体积较大,不如WOFF
和TTF
文件压缩得好,因此在实际开发中较少使用。
根据目前的浏览器支持情况和字体文件的大小等因素,推荐在 Web
开发中使用 WOFF
格式的字体文件。
如果需要更广泛的浏览器兼容性,可以同时提供 TTF
格式的字体文件作为备选。
8-2.Icon Fonts
Web Fonts
指的是在计算机中使用自定义字体。
而 Icon Fonts
指的是在计算机中使用自定义字体图标。
通常对于网站图标,一共有 3
种处理方式:
Image
引入。弊端是会增加页面请求、图片的大小和颜色不容易改变、高清晰度的图片质量越大。Sprites
引入。雪碧图相对来说,能够减少页面请求。但由于需要使用背景定位,因此对于开发和后期迭代新的雪碧图,这种方式也不理想。Icon Fonts
引入。
重点说一下 Icon Fonts
的优缺点:
优点:
- 可以方便地将任何
CSS
效果应用于它们。 - 因为它们是矢量图形,所以它们是可伸缩的。这意味着我们可以在不降低质量的情况下伸缩它们。
- 我们只需要发送一个或少量
HTTP
请求来加载它们,而不是像图片,可能需要多个HTTP
请求。 - 由于尺寸小,它们加载速度快。
- 它们在所有浏览器中都得到支持(甚至支持到
IE6
)。
缺点:
- 不能用来显示复杂图像
- 通常只限于一种颜色,除非应用一些
CSS
技巧 - 字体图标通常是根据特定的网格设计的,例如
16x16
,32×32
,48×48
等。如果由于某种原因将网格系统改为25×25
,可能不会得到清晰的结果。
目前较为成熟的平台有阿里IconFont和字节IconPark。
由于目前项目大多数还是使用阿里的字体图标库,因此本节总结介绍下iconfont的引用方式。
8-2-1.Unicode
unicode
是字体在网页端最原始的应用方式,特点是:
- 兼容性最好,支持
IE6+
,及所有现代浏览器。 - 支持按字体的方式去动态调整图标大小,颜色等等。
首先引入平台上生成的 font-face
代码,设置一个 css
类,然后挑选相应图标并获取字体编码,应用于页面:
<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;"></span>
会展示一个点赞图标:
8-2-2.Font class
font-class
是 unicode
使用方式的一种变种,主要是解决 unicode
书写不直观,语意不明确的问题。
与 unicode
使用方式相比,具有如下特点:
- 兼容性良好,支持
ie8+
,及所有现代浏览器。 - 相比于
unicode
语意明确,书写更直观。可以很容易分辨这个icon
是什么。 - 因为使用
class
来定义图标,所以当要替换图标时,只需要修改class
里面的unicode
引用。 - 不过因为本质上还是使用的字体,所以多色图标还是不支持的。
首先引入平台上生成的 link
代码,然后挑选自定义图标并引入即可:
<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>
元素,提供了一系列图标集合。
与上面两种相比具有如下特点:
- 支持多色图标了,不再受单色限制。
- 通过一些技巧,支持像字体那样,通过
font-size
、color
来调整样式。 - 兼容性较差,支持
ie9+
及现代浏览器。 - 浏览器渲染
svg
的性能一般,还不如png
。
首先同样是引入平台上生成的 symbol
代码,加入通用 css
代码(全局设置一次),然后挑选相应图标并获取类名:
<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
获取图标时会在 svg
的 path
中增加fill
属性,导致无法更改颜色。
如果需要动态修改颜色,可以采用按需求考虑一下两种方式:
下载
Js
文件后,然后查找fill
属性,替换或者删除。在
iconfont.cn
上,全选项目中的文件,应用批量操作、批量去色。
8-3.Svg
SVG
的全称是 Scalable Vector Graphics
。
它是一种 XML
语言,类似 XHTML
,可以用来绘制矢量图形,例如下面展示的图形。
SVG
可以通过定义必要的线和形状来创建一个图形,也可以修改已有的位图,或者将这两种方式结合起来创建图形。
图形和其组成部分可以形变(transformed
)、合成、或者通过滤镜完全改变外观。
在 MDN
上对于 SVG
技术的论述,可以分作 3
部分:
本节是针对 MDN
所述内容的重点归纳总结。目标是更好的理解 SVG
的元素构成和基本使用。
根本目的是为了在现实项目中更好的运用 Symbol Iconfont
以及 SVG Sprite
技术。
8-3-1.svg
<svg>
元素本身默认是 inline
行内元素。
与一般的行内元素如 span
不同的是,svg
行内元素有默认的宽高。
这一点与 canvas
元素是相同的。**在不设置宽高时,svg
和 canvas
元素默认的宽高都是 300 * 150
。
8-3-2.defs
<defs>
元素允许我们定义需要重复使用的图形元素。
在 defs
元素中定义的图形元素不会直接呈现。你可以在你的视口的任意地方利用 <use>
元素呈现这些元素。
我个人将 defs
元素的效果理解成 JavaScript
中的模块化。因为它将众多元素定义聚合在了一个模块内,然后可以通过 use
快速引用。
<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>
元素上设置 width
和 height
,并不能影响到引用的 defs
内元素的实际大小。
譬如,设置 <use>
的宽为 5
、高为 10
:
<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
defs
和 symbol
元素功能很类似。但二者也有区别。
可以将 defs
理解成定义可重复使用的 SVG
元素片段。
而 symbol
则是定义可重复使用的 SVG
图标。
相对来说,symbol
元素比 defs
元素更高级一点。
8-3-3.symbol
<symbol>
元素允许我们定义一系列元素的集合。
在 symbol
元素中定义的图形元素不会直接呈现。你可以在你的视口的任意地方利用 <use>
元素呈现这些元素。
我个人将 symbol
元素的效果理解成 JavaScript
中的组件化。因为它将众多元素定义聚合在了一个模块内,然后可以通过 use
快速引用整个模块。
<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
集合,而非单个元素。
这是 symbol
比 defs
高级的一点。
8-3-4.use
<use>
元素是 SVG
(可缩放矢量图形)中的一个重要元素,用于重复使用已定义的图形。
它允许在同一文档中多次使用相同的图形或符号,从而减少了代码冗余,使得图形的维护更加简便。
<use xlink:href="URL" ... />
其中,xlink:href
属性指定了要重用的图形或符号的位置(URL
),然后通过添加属性来调整该重用图形的位置、尺寸以及其他属性。
从以上的 demo
中,可以看出 <use>
可以结合 <defs>
或者 <symbol>
元素来使用。
SVG
的属性是严格区分大小写的。
譬如 viewBox
与 viewbox
是不同的。
8-3-5.viewBox
可以设置 viewBox
属性的元素有 <svg>
、<symbol>
、<view>
、<pattern>
、<marker>
。
SVG
中的 viewBox
属性是用来定义坐标系统,而不是用来改变元素的实际尺寸。
viewBox
决定了坐标系中的哪个区域会被展示在 SVG
画布上,但它并不会改变元素的具体尺寸。
TIP
类比于 canvas
的话,可以将 viewBox
属性看做绘图面积。
譬如:
<svg width="150" height="100"></svg>
上述代码代表的是,会绘制一个宽为 150
、高为 100
的元素。
而 viewBox
代表的是绘图面积。
基本语法为,viewBox="min-width min-height width height"
。
譬如:
<svg width="150" height="100" viewBox="0 0 3 2"></svg>
上述代码代表的是,会在 3 * 2
的盒子下绘制 svg
元素,并将它放大到 150 * 100
的比例。
<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
,但没有设置 width
和 height
时,那么最终参照的宽和高会是父级元素。
<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
可以用来设置元素的填充色。
譬如:
<svg width="150" height="100" viewBox="0 0 3 2">
<rect width="3" height="2" x="0" fill="#468B97" />
</svg>
该属性也可以通过 css
来设置:
<svg width="150" height="100" viewBox="0 0 3 2" style="fill: #EF6262;">
<rect width="3" height="2" x="0" />
</svg>
在实际开发中,会将 fill
与 currentColor
结合起来,这样直接使用 color
来设置 svg
颜色,更接近开发习惯:
<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
其实利用的就是 svg
的 symbol
元素。
它会在 <body>
标签的顶部生成如下结构:
具体的使用方式步骤:
- 在项目中准备好
svg
的xml
文件,并在项目中的main.js
全局引入,import @/assets/icons
。
之所以能使用上述语法,是因为在 src/assets/icons/index.js
中利用了 webpack
的导入:
const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('../icons', false, /\.svg$/)
requireAll(req)
- 利用
svg-sprite-loader
处理svg
文件的解析:
{
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')]
}
- 如果使用的是
vue-cli
,则可以这样配置:
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
等等。
为了保证后述场景的正常进行,可以对上面的规则进行二次改造:
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]'
})
}
- 封装引入
svg
的组件,以vue
项目创建一个SvgIcon
组件为例:
<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>
- 可以全局注册
SvgIcon
组件,方便使用:
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg组件
// register globally
Vue.component('SvgIcon', SvgIcon)