大有学问# #头条创作挑战赛#
在html代码中是以文字元素的形式出现,但在网页渲染时却以图片的形式显示的小图标就叫做字体图标。
常见形式:地址、电话、登录窗口的头像等。
字体图标比精灵图更为轻量化,在网页中加载速度更快;
精灵图在实际使用中,图片放大或缩小时图片会失真。
精灵图是一张多个图标整合的一个大图片,后续添加或修改图标不方便。
注:
虽然字体图标好处多多,但是它并不能替代精灵图。
当小图标形式简单且个数较少时适合使用字体图标;
当小图标形式复杂且个数较多时适合使用精灵图。
icomoon网站:https://icomoon.io/。
阿里iconfont字库:https://www.iconfont.cn/。
以icomoon网站为例。
从网站中下载图标压缩包:点击右上角“IcoMoon App”按钮,进入字体图标选择页面。
icomoon网站首页
选中需要的图标(选中状态的图标,背景颜色会变白且出现黄色边框)后,个数可以选择1个,也可以选择多个。选好图标后,点击右下角“Generate Font ”按钮进入下载页面。
字体图标选择页面
点击右下角“download”按钮进行下载。
icomoon网站图标下载页面
解压下载好的压缩包。
字体图标下载文件解压后的文件夹
将解压好的文件夹整体添加到项目文件夹中,我没有单独设置字体文件夹,直接放在素材图片文件夹了。
项目文件夹目录
打开字体图标文件夹中style.css,
复制字体声明到html文件的style样式中,改变url的图标文件存放位置。
span标签中字体样式需要与字体声明中样式保持一致。
字体图标调用
在html文件中,span标签的内容是需要从网站中直接粘贴复制过来使用。在网站下载页面,鼠标点击就是选中状态,直接ctrl+c复制即可。
字体图标的代码样式调用
如此就是完整的字体图标使用过程。另外有阿里iconfont也可以使用,也是免费的。有兴趣可自行了解。
<style>
/* 字体声明 :从下载字体图标的文件夹中style.css文件上复制过来的*/
@font-face {
font-family: 'icomoon';
src: url('../images/icomoon/fonts/icomoon.eot?49yzcu');
src: url('../images/icomoon/fonts/icomoon.eot?49yzcu#iefix') format('embedded-opentype'),
url('../images/icomoon/fonts/icomoon.ttf?49yzcu') format('truetype'),
url('../images/icomoon/fonts/icomoon.woff?49yzcu') format('woff'),
url('../images/icomoon/fonts/icomoon.svg?49yzcu#icomoon') format('svg');
font-weight: normal;
font-style: normal;
font-display: block;
}
span {
font-family: 'icomoon';
font-size: 100px;
color: antiquewhite;
}
</style>
span标签的内容就是从字体图标上粘贴下来的
代码运行效果图
好了,今天的学习就到这里了,下回学习CSS三角~
全是干货的技术殿堂
文章收录在我的 GitHub 仓库,欢迎Star/fork: Java-Interview-Tutorial
https://github.com/Wasabi1234/Java-Interview-Tutorial
this 是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用。
教科书般的解释,字都认识,怎么连在一起还是不知道啥意思呢?
函数的不同场合,this有不同值。
总的来说,this就是函数运行时所在的环境对象。
函数的最通常用法,属全局性调用,因此this就代表全局对象。
函数还可以作为某个对象的方法调用,这时this就指这个上级对象。
记住一条:当function被作为method调用时,this指向调用对象。另外,JavaScript并不是OO的,而是object based的一种语言。
所谓构造函数,就是通过这个函数,可以生成一个新对象。这时,this就指这个新对象。
运行结果为1。为了表明这时this不是全局对象,我们对代码做一些改变:
运行结果为2,表明全局变量x的值根本没变。
apply()是函数的一个方法,作用是改变函数的调用对象。它的第一个参数就表示改变后的调用这个函数的对象。因此,这时this指的就是这第一个参数。
apply()的参数为空时,默认调用全局对象。因此,这时的运行结果为0,证明this指的是全局对象。
如果把最后一行代码修改为
运行结果就变成了1,证明了这时this代表的是对象obj。
学懂 JavaScript 语言,一个标志就是理解下面两种写法,可能有不一样的结果。
上面代码中,虽然obj.foo和foo指向同一个函数,但是执行结果可能不一样。请看下面的例子。
为什么会这样?函数的运行环境到底是谁决定的?为什么obj.foo()就是在obj环境执行,而一旦var foo=obj.foo,foo()就变成全局环境执行了?
带着灵魂的思考,我们深入解析下
上面的代码将一个对象赋值给变量obj.
变量obj是一个地址(reference)。后面如果要读取obj.foo,引擎先从obj拿到内存地址,然后再从该地址读出原始的对象,返回它的foo属性。
原始的对象以字典结构保存,每一个属性名都对应一个属性描述对象。举例来说,上面例子的foo属性,实际上是以下面的形式保存的。
{
foo: {
[[value]]: 5
[[writable]]: true
[[enumerable]]: true
[[configurable]]: true
}
}
注意,foo属性的值保存在属性描述对象的value属性里面。
这样的结构是很清晰的,问题在于属性的值可能是一个函数。
{
foo: {
[[value]]: 函数的地址
...
}
}
由于函数是一个单独的值,所以它可以在不同的环境(上下文)执行。
JavaScript 允许在函数体内部,引用当前环境的其他变量。
上面代码中,函数体里面使用了变量x。该变量由运行环境提供。
现在问题就来了,由于函数可以在不同的运行环境执行,所以需要有一种机制,能够在函数体内部获得当前的运行环境(context)。所以,this就出现了,它的设计目的就是在函数体内部,指代函数当前的运行环境。
上面代码中,函数体里面的this.x就是指当前运行环境的x。
var f=function () {
console.log(this.x);
}
var x=1;
var obj={
f: f,
x: 2,
};
// 单独执行
f() // 1
// obj 环境执行
obj.f() // 2
上面代码中,函数f在全局环境执行,this.x指向全局环境的x。
在obj环境执行,this.x指向obj.x。
回到本文开头提出的问题,obj.foo()是通过obj找到foo,所以就是在obj环境执行。一旦var foo=obj.foo,变量foo就直接指向函数本身,所以foo()就变成在全局环境执行。
使用图片和 CSS 精灵制作 web 图标的日子一去不复返了。随着 web 字体的爆发,图标字体已经成为在你的 web 项目中显示图标的第一解决方案。
字体是矢量,所以你无须担心分辨率的问题。他们和文本一样因为拥有 CSS 属性,那就意味着,你完全可以应用 size
、 color
和 style
。你可以添加转换、特效和装饰,比如旋转、下划线或者阴影。
怪不得类似 Font Awesome 这类项目仅仅在 npm 至今已经被下载了超过 1500 万次。
可是图标字体并不完美, 这就是为什么越来越多的人使用行内 SVG 。CSS Tricks 写了图标字体劣于原生 SVG 元素的地方:锐利度、定位或者是因为跨域加载、特定浏览器错误和广告屏蔽器等原因导致的失败。现在你可以规避绝大多数这些问题了,总体上使用图标字体是一个安全的选择。
然而,还是有一件事情对于图标字体来说是绝对不可能的:多色支持。只有 SVG 可以做到。
摘要 :这篇博文深入阐述怎么做和为什么。如果你想理解整个思维过程,推荐阅读。否则你可以直接在 CodePen 看最终代码。
设置 SVG 标志图标
行内 SVG 的问题是,它会非常冗长。你肯定不想每次使用同一个图标的时候,还需要复制/粘贴所有坐标。这将会非常重复,很难阅读,更难维护。
通过 SVG 符号图标,你只需拥有一个 SVG 元素,然后在每个需要的地方引用就好了。
先添加行内 SVG ,隐藏它之后,再用 <symbol>
包裹它,用 id
对其进行识别。
<svg xmlns="http://www.w3.org/2000/svg" style="display: none"> <symbol id="my-first-icon" viewBox="0 0 20 20"> <title>my-first-icon</title> <path d="..." /> </symbol> </svg>
整个 SVG 标记被一次性包裹并且在 HTML 中被隐藏。
然后,所有你要做的是用一个 <use>
标签将图标实例化。
<svg> <use xlink:href="#my-first-icon" /> </svg>
这将会显示一个初始 SVG 图标的副本。
**就是这样了!**看起来很棒,是吧?
你可能注意到了这个有趣的 xlink:href
属性:这是你的实例与初始 SVG 之间的链接。
需要提到的是 xlink:href
是一个弃用的 SVG 属性。尽管大多数浏览器仍然支持,你应该用 **href**
替代。现在的问题是,一些浏览器比如 Safari 不支持使用 href
进行 SVG 资源引用,因此你仍然需要提供 xlink:href
选项。
安全起见,两个都用吧。
添加一些颜色
不像是字体, color
对于 SVG 图标没有任何作用:你必须使用 fill
属性来定义一个颜色。这意味着他们将不会像图标字体一样继承父文本颜色,但是你仍然可以在 CSS 中定义它们的样式。
// HTML <svg class="icon"> <use xlink:href="#my-first-icon" /> </svg> // CSS .icon { width: 100px; height: 100px; fill: red; }
在这里,你可以使用不同的填充颜色创建同一个图标的不同实例。
// HTML <svg class="icon icon-red"> <use xlink:href="#my-first-icon" /> </svg> <svg class="icon icon-blue"> <use xlink:href="#my-first-icon" /> </svg> // CSS .icon { width: 100px; height: 100px; } .icon-red { fill: red; } .icon-blue { fill: blue; }
这样就可以生效了,但是不完全符合我们的预期。目前为止,我们所有做的事情可以使用一个普通的图标字体来实现。我们想要的是在图标的位置可以有不同的颜色。我们想要向每个路径上填充不同颜色,而不需要改变其他实例,我们想要能够在必要的时候重写它。
首先,你可能会受到依赖于特性的诱惑。
// HTML <svg xmlns="http://www.w3.org/2000/svg" style="display: none"> <symbol id="my-first-icon" viewBox="0 0 20 20"> <title>my-first-icon</title> <path class="path1" d="..." /> <path class="path2" d="..." /> <path class="path3" d="..." /> </symbol> </svg> <svg class="icon icon-colors"> <use xlink:href="#my-first-icon" /> </svg> // CSS .icon-colors .path1 { fill: red; } .icon-colors .path2 { fill: green; } .icon-colors .path3 { fill: blue; }
不起作用。
我们尝试设置 .path1
、 .path2
和 .path3
的样式,仿佛他们被嵌套在 .icon-colors
里,但是严格来说,并非如此。 <use>
标签不是一个会被你的 SVG 定义替代的占位符。这是一个引用将它所指向内容复制为 shadow DOM 。
**那接下来我们该怎么办?**当子项不在 DOM 中时,我们如何才能用一个区域性的方式影响子项?
CSS 变量拯救世界
在 CSS 中,一些属性从父元素继承给子元素。如果你将一个文本颜色分配给 body
,这一页中所有文本将会继承那个颜色直到被重写。父元素没有意识到子元素,但是可继承的样式仍然继续传播。
在我们之前的例子里,我们继承了填充属性。回头看,你会看到我们声明填充颜色的类被附加在了实例上,而不是定义上。这就是我们能够为同一定义的每个不同实体赋予不同颜色的原因。
现在有个问题:我们想传递不同颜色给原始 SVG 的不同路径,但是只能从一个 fill
属性里继承。
这就需要 CSS 变量了。
就像任何其它属性一样, CSS 变量在规则集里被声明。你可以用任意命名,分配任何有效的 CSS 值。然后,你为它自己或者其它子属性,像一个值一样声明它,并且这将被继承。
.parent { --custom-property: red; color: var(--custom-property); }
所有 .parent
的子项都有红色文本。
.parent { --custom-property: red; } .child { color: var(--custom-property); }
所有嵌套在 .parent
标签里的 .child
都有红色文本。
现在,让我们把这个概念应用到 SVG 符号里去。我们将在 SVG 定义的每个部分使用 fill
属性,并且设置成不同的 CSS 变量。然后,我们将给它们分配不同的颜色。
// HTML <svg xmlns="http://www.w3.org/2000/svg" style="display: none"> <symbol id="my-first-icon" viewBox="0 0 20 20"> <title>my-first-icon</title> <path fill="var(--color-1)" d="..." /> <path fill="var(--color-2)" d="..." /> <path fill="var(--color-3)" d="..." /> </symbol> </svg> <svg class="icon icon-colors"> <use xlink:href="#my-first-icon" /> </svg> // CSS .icon-colors { --color-1: #c13127; --color-2: #ef5b49; --color-3: #cacaea; }
然后… 生效了 !
现在开始,为了用不同的颜色方案创建实例,我们所需要做的是创建一个新类。
// HTML <svg class="icon icon-colors-alt"> <use xlink:href="#my-first-icon" /> </svg> // CSS .icon-colors-alt { --color-1: brown; --color-2: yellow; --color-3: pink; }
如果你仍然想有单色图标,你不必在每个 CSS 变量中重复同样的颜色。相反,你可以声明一个单一 fill
规则:因为如果 CSS 变量没有被定义,它将会回到你的 fill
声明。
.icon-monochrome { fill: grey; }
你的 fill
声明将会生效,因为初始 SVG 的 fill
属性被未设置的 CSS 变量值定义。
怎样命名我的 CSS 变量?
当提到在 CSS 中命名,通常有两条途径:描述的或者语义的。描述的意思是告诉一个颜色是什么:如果你存储了 #ff0000
你可以叫它 --red
。语义的意思是告诉颜色它将会被如何应用:如果你使用 #ff0000
来给一个咖啡杯把手赋予颜色,你可以叫它 --cup-handle-color
。
描述的命名也许是你的本能。看起来更干脆,因为#ff0000
除了咖啡杯把手还有更多地方可以被使用。一个 --red
CSS 变量可被复用于其他需要变成红色的图标路径。毕竟,这是实用主义在 CSS 中的工作方式。并且是一个良好的系统。
问题是,在我们的案例里,我们不能把零散的类应用于我们想设置样式的标签。实用主义原则不能应用,因为我们对于每个图标有单独的引用,我们不得不通过类的变化来设置样式。
使用语义类命名,例如 --cup-handle-color
,对于这个情况更有用。当你想改变图标一部分的颜色时,你立即知道这是什么以及需要重写什么。无论你分配什么颜色,类命名将会一直关联。
默认还是不要默认,这是个问题
将你的图标的多色版本设置成默认状态是很有诱惑力的选择。这样,你无需设置额外样式,只需要在必要的时候可以添加你自己的类。
有两个方法可以实现::root 和 var() default 。
:root
在 :root
选择器中你可以定义所有你的 CSS 变量。这将会把它们统一放在一个位置,允许你『分享』相似的颜色。 :root
拥有最低的优先度,因此可以很容易地被重写。
:root { --color-1: red; --color-2: green; --color-3: blue; --color-4: var(--color-1); } .icon-colors-alt { --color-1: brown; --color-2: yellow; --color-3: pink; --color-4: orange; }
然而,这个方法有一个主要缺点。首先,将颜色定义与各自的图标分离可能会有些让人疑惑。当你决定重写他们,你必须在类与 :root
选择器之间来回操作。但是更重要的是,它不允许你去关联你的 CSS 变量,因此让你不能复用同一个名字。
大多数时候,当一个图标只用一种颜色,我用 --fill-color
名称。简单,易懂,对于所有仅需要一种颜色的图标非常有意义。如果我必须在 :root
声明中声明所有变量,我就不会有几个 --fill-color
。我将会被迫定义 --fill-color-1
, --fill-color-2
或者使用类似 --star-fill-color
, --cup-fill-color
的命名空间。
var() 默认
你可以用 var()
功能来把一个 CSS 变量分配给一个属性,并且它的第二个参数可以设置为某个默认值。
<svg xmlns="http://www.w3.org/2000/svg" style="display: none"> <symbol id="my-first-icon" viewBox="0 0 20 20"> <title>my-first-icon</title> <path fill="var(--color-1, red)" d="..." /> <path fill="var(--color-2, blue)" d="..." /> <path fill="var(--color-3, green)" d="..." /> </symbol> </svg>
在你定义完成 --color-1
, --color-2
和 --color-3
之前,图标将会使用你为每个 <path>
设置的默认值。这解决了当我们使用 :root
时的全局关联问题,但是请小心:你现在有一个默认值,并且它将会生效。结果是,你再也不能使用单一的 fill
声明来定义单色图标了。你将不得不一个接一个地给每个使用于这个图标的 CSS 变量分配颜色。
设置默认值会很有用,但是这是一个折中方案。我建议你不要形成习惯,只在对给定项目有帮助的时候做这件事情。
How browser-friendly is all that?
CSS 变量与大多数现代浏览器兼容,但是就像你想的那样, Internet Explorer 完全不兼容。因为微软要支持 Edge 终止了 IE11 开发, IE 以后也没有机会赶上时代了。
现在,仅仅是因为一个功能不被某个浏览器(而你必须适配)兼容,这不意味着你必须全盘放弃它。在这种情况下,考虑下优雅降级:给现代浏览器提供多彩图标,给落后浏览器提供备份的填充颜色。
你想要做的是设置一个仅在 CSS 变量不被支持时触发的声明。这可以通过设置备份颜色的 fill
属性实现:如果 CSS 变量不被支持,它甚至不会被纳入考虑。如果它们不能被支持,你的 fill
声明将会生效。
如果你使用 Sass 的话,这个可以被抽象为一个 @mixin
。
@mixin icon-colors($fallback: black) { fill: $fallback; @content; }
现在,你可以任意定义颜色方案而无需考虑浏览器兼容问题了。
.cup { @include icon-colors() { --cup-color: red; --smoke-color: grey; }; } .cup-alt { @include icon-colors(green) { --cup-color: green; --smoke-color: grey; }; }
在 mixin 中通过 @content
传递 CSS 变量也是一个可选项。如果你在外面做这件事,被编译的 CSS 将会变得一样。但是它有助于被打包在一起:你可以在你编辑器中折叠片段然后用眼睛分辨在一起的声明。
在不同的浏览器中查看这个 pen 。在最新版本的 Firefox , Chrome 和 Safari 中,最后两只杯子各自拥有红色杯身灰色烟气和蓝色杯身灰色烟气。在 IE 和 版本号小于 15 的 Edge 中,第三个杯子的杯身与烟气全部都是红色,第四个则全部是蓝色! ?
*请认真填写需求信息,我们会在24小时内与您取得联系。