文字与图片
$sss^y$
Typography
Styling Fonts
网页上的字体大体可以分成三类:Serif
, Sans-serif
, Monospace
Serif 衬线字体族
- 具有修饰过的笔画,向外展开的或者尖细的末端,或者是带有实际衬线的末端
- 一笔一划末端(两头)都带点变化装饰,比如宋体笔画末端有毛笔字的感觉
- 文字末端有差异,在小字号下仍然容易辨认。但在大字号下笔画装饰部分可能会显得模糊或带有锯齿
Sans-serif 无衬线字体族
- 具有笔画清晰的末端–带有一点或者没有向外展开的,交错笔画,或者其它装饰
- 与“衬线字体”相比,如果字号比较小,看起来就会有些难以分辨,尤其段落阅读时容易串行
左侧是 Sans-serif, 右侧是serif
monospace 等宽字体族
- 每个字形都等宽,主要用于英文,中文方块字本来就等宽
font-family
我们可以通过设置 font-family来设置段落的字体。比如:
1 | body { |
这里我只设置了 body的字体,<p>
元素和 <a>
元素都会继承其父元素也就是 body 中的字体。 然后我又特别定义了 h1
的字体。
font-weight font-style
这个属性是设置字体的粗细的,可以选100-900,必须以百为单位。 默认为100也就如同第一张图。最高位900,如下图:
除了数字之外,还可以选 bold
(大概是700), bolder
,lighter
,normal
(大概是400)
font-style
属性可选 italic (也就是斜体) 或者normal
font-size
属性是字体的大小,可以选绝对单位或者是自动单位
color
属性设置字体的颜色
Embedding Web Fonts
我们可以从这些网站上下载字体,有些字体是免费的,有些字体是收费的
下载的字体文件有好几种格式: TTF OTF EOT WOFF WOFF2.0 。在网页上使用的时候,我们主要使用WOFF和WOFF2.0这两种格式。
我们下载一个免费的字体Open Sans来作为例子,下载的格式是tff。我们可以到
https://www.fontke.com/tool/convfont/ 这里将其转换为 WOFF/WOFF2格式。接下来我们要将这些字体应用于我们的网页。我们用下面这套模板来注册字体。
1 | @font-face{ |
在使用的时候,我们需要在字体前面加上family name即可
1 | body { |
Flash of Unstyled Text
当我们使用自己下载的字体的时候,如果浏览器的渲染速度非常慢,它可能先渲染出原来的字体,然后再渲染我们下载来的字体。这叫做 Flash of Unstyled Text
这对用户的体验不是很友好。
为了解决这个问题,我们可以设置 font-display
属性, 默认情况下这个属性为被设置为auto,chrome的渲染模式就是先渲染一个备用字体,然后再渲染我们定制的字体。但是不同浏览器的策略也是不同的。
我们可以将其设置为fallback,也就是说,当经过很长时间我们的定制字体还没有被下载好的话,那么就可以使用备用字体。以免在阅读途中遭遇切换字体的烦恼。
如果我们将 font-display
设置成block的话,那么在我们的定制字体没有被下载好之前,文字是没有办法显现的。但这个操作十分危险,如果字体未下载成功,那么我们将看不见这些文字。
最后一个 font-display
的值未 optional
,这是一个较好的选择。当定制的字体还没有被下载好的时候,浏览器一开始会使用备用字体,并将其保存在浏览器的缓存当中。 当我们打开子网页的时候,浏览器就会从缓存中取出字体并使用。这能让用户在未察觉的时候切换字体。
Font Services
很多字体的使用权限非常贵。因此我们可以使用一些字体库,我们只需要按月订阅就能使用很多字体。
我们以google fonts为例,讲一下怎么使用 谷歌的字体服务
在我们选择好字体之后,谷歌提供了 link和 @import两种方法来将字体导入到网页当中。
我们复制其提供的链接,然后在html的header中插入。链接一共有两个 <link>
元素,第一个是告诉浏览器,我们的网页存在一个与https://fonts.gstatic.com
的链接,目的是让我们尽快从字体服务网站上下载字体。
第二个网站是一张 stylesheet的链接。stylesheet是由谷歌生成的,里面是各种 @font-face
我们只管引用即可.
1 | <link rel="preconnect" href="https://fonts.gstatic.com"> |
同样的,我们只要在font-family后面写上”Open Sans” ,就能使用这个字体了
1 | body { |
System Font Stack
有了这个栈,我们就能告诉浏览器对用户的电脑使用操作系统中的默认字体
有了这个栈有几点好处:
- Can boost performance,因为电脑没必要去网上下载字体了
- 避免了Flash of unstyled text
- Native Look
总之,它能带给用户更好的体验。不过不同系统的 字体栈是不一样的。如果我们要强行定义网页系统的字体栈,我们可以在font-family
中打一个 -
1 | body { |
Sizing Fonts
现在我们再来谈谈 字体的大小。一般我们使用px也就是 pixel来定义字体大小。但是在不同分辨率不同机器上,对pixel的大小的定义也是不同的。如果我们在Windows机器上定义字体为20px,那在mac电脑上看起来会更小一点
所以我们可以使用 相对单位。使用 rem 作为单位会更好一点。也方便我们做 media queiries:
1 | html{ |
当我们窗口宽度小于 768px的时候, body元素采用1.5倍的当前html字体的大小。也就是 1.5X10px = 15px;当窗口宽度大于768px的时候,只需要把 html字体放大到100% 即可,这时候,body元素中的字体大小就是 1.5X16px = 24px
对于不同的heading应该取多少 rem,我们可以上这个网站查询:https://type-scale.com/
Vertical Fonts
我们现在有两段文字,我希望 <h1>
元素的上边距长一些,离<p>
元素近一些,怎么实现?
我们可以使用 margin
这个属性
1 | h1 { |
第四个位置不用写,因为会自动认为和第二个值一样。效果如下:
此外,还可以设置line-height
属性来设置行距。 但是要注意,如果同时设置 font-size
和 line-height
的话,要注意 font-size
不能设置的比 line-height
还要大,因为这样行和行之间就挤在一起了,非常不美观。为了解决这个问题我们可以这样写:
1 | body { |
去掉 line-height
的单位,他就表示当前字体的倍数,因此不管字体设置为多大,行距始终是1.5倍的字体大小。
Horizontal Spacing
letter-spacing
这个属性是设置字母与字母之间的距离,比如将其设置为 1rem会发生这样的结果:
因此使用px而不是rem才是正确的选择,根据字体的不同我们可以对其进行调节。
word-spacing
为了阅读方便,每一行所容纳的数字大概在50-70左右。 我们可以通过设置 width
函数,用 ch
作为单位,ch就是一行中可以写几个0。然后根据这个自动计算 单词之间的距离。
1 | p { |
Formatting Text
text-align
这个属性规定元素中的文本的水平对齐方式。
- left, right,center : 把文本排列到左边(默认)/右边/中间
- justify: 可以使文本的两端都对齐。但是这样就会导致每一行中词与词之间的间距是不同的。
- inherit:从父元素继承 text-align的属性值
text-indent
这个属性规定文本块中首行文本的缩进。常用于建立一个“标签页”效果。允许指定负值,这会产生一种“悬挂缩进”的效果,比如说
1 | p { |
text-decoration
顾名思义,是给文本加装饰的
值 | 描述 |
---|---|
none | 默认。定义标准的文本。 |
underline | 定义文本下的一条线。 |
overline | 定义文本上的一条线。 |
line-through | 定义穿过文本下的一条线。 |
blink | 定义闪烁的文本。 |
inherit | 规定应该从父元素继承 text-decoration 属性的值。 |
text-transform
这个属性可以调整元素中文本的大小写。如果将值设置为Capitalize,那么每个单词的第一个字母都将是大写的。
white-space
规定段落中的文本不进行换行
值 | 描述 |
---|---|
normal | 默认。空白会被浏览器忽略。 |
pre | 空白会被浏览器保留。其行为方式类似 HTML 中的<pre> 标签。 |
nowrap | 文本不会换行,文本会在在同一行上继续,直到遇到 <br> 标签为止。 |
pre-wrap | 保留空白符序列,但是正常地进行换行。 |
pre-line | 合并空白符序列,但是保留换行符。 |
inherit | 规定应该从父元素继承 white-space 属性的值 |
1 | p { |
column-*
如果我们要实现分栏,可以这样写:
1 | p { |
如果我们愿意,还可以在栏和栏之间加上分割线:
1 | column-rule: 3px dotted #999 |
direction
如果把这个元素设置为 rtl,那么文字就是这样的:比较符合阿拉伯人的书写习惯
Summary
Exercise
Images
Image Types and Formats
transparency是指照片是否支持透明背景。 jpeg格式的照片是不支持透明背景的,gif只支持256种颜色。
Content Images
我们可以在html语言中插入图片。
1 | <body> |
src就是图片的路径,alt 是当下载图片失败的时候,我们看到的替代图片的文字。
当我们想要插入的图片并不需要描述时,比如一个箭头之类的装饰性图片,我们可以把alt置为空字符串,但是不要删去alt,因为这样浏览器就会将alt默认设置为这张图片的名字。
我们可以设置width属性来调整图片的大小,但是放得太大会导致画面失真。
Background Images
现在我们来说说背景图。我们在css中可以设置背景图。
首先是background属性,这个属性既可以写颜色,又可以将图片设置为背景,我们只需要将url写入即可。
如果不做任何修改,那么背景图就会在浏览器窗口平铺,也就是不断重复排列。因此如果我们不希望重复排列,我们可以将background-repeat
属性设置为no-repeat.
接下来,我们可以通过设置background-position
属性来调整图片在窗口中的位置。并通过 background-size
来调整背景图片的大小。
比如这样编写css:
1 | body { |
不过,我们可以直接使用 cover值,效果和写两个100% 是一样的
1 | body { |
现在,我们用金门大桥作为背景,然后写一个h1
现在我将height改成300vh,我们发现背景会随着滚轮一块滚动,而且图片也随之扩大了3倍。
为了固定住背景图,只让内容滚动,我们可以使用background-attachment
,将其设置为fixed。
效果如下:
CSS Sprites
我们可以在 http://flaticon.com/ 网站上下载图标
比如:
1 | <body> |
但是这样一来,浏览器加载一次就需要加载五张图片。能不能通过一种方法将五张图合并起来,但是又能在不同的地方使用单个标签,这样就使得浏览器只请求一次即可。
我们可以用 CSS Sprites 工具: http://cssspritestool.com/
只需要将图片拖入,然后进行简单的设置。就可以得到一张包含五个 图标的图了。
我们还得到一个自动生成的css文件,教我们如何在网页中引用这些图标
1 | .bg-rocketship |
我们只需要修改一下相对路径,然后将图片的class设置成图标名称,就能使用单个图标了,实际上,css做的是一个切割的动作。
但是这样做也有缺点。
- 文件可能会很大
- 这样操作,不是很灵活,万一有新的图标加入会比较麻烦
Data URI
Data URI 是另一种减少HTTP请求的优化技巧。使用这种方法,我们可以将图片直接嵌入到一个HTML文件中去。
我们可以借助 https://www.cssportal.com/image-to-data/ 网站来实现。
当我们拖入图片后,就可以生成Data URI,在src中写入后,就能显示图片了。利用这种方法,HTTP并没有发出request请求。
但是,Data URI 也有问题
- 嵌入式的代码所占的空间比之前的图片大小还要大
- 增加了HTML文件的复杂度
- 在移动端访问较慢
Clipping
使用CSS,我们可以轻松将图片裁剪。
我们在这个网站上就能定制裁剪后的图片了。https://bennettfeely.com/clippy/
只要将生成的CSS代码复制粘贴就能用了
Filters
在css中,我们可以对图片使用很多种滤镜。
- 灰度滤镜
filter: grayscale();
括号中可以使用百分号表示灰色的程度,默认为100%
- 模糊效果
filter: blur(3px);
同样在括号中使用px来表示模糊的程度。
此外如果我们这样编写css,那么当鼠标移动到图片上的时候图片就会变灰变模糊
1 | .meal:hover { |
我们可以在 https://developer.mozilla.org/en-US/docs/Web/CSS/filter 上找到更多的滤镜函数。
Supporting High-density Screens
我们直到,苹果在手机以及自家的显示屏上都在使用 Retiina (视网膜屏),但是同一张照片,在iphone3(480x320)上和iphone4(960x640)上显示的位置是一样的,因此这势必会拉长同一幅照片,造成失真。我们可以通过 images元素中的 srcset属性来帮助我们在不同的显示屏上显示不同分辨率的照片。
首先,我们找到2388x2388分辨率的原图,然后利用Photoshop将其变为 400x400, 800x800, 1200x1200 三种分辨率的图片。分别命名为 meal.jpg/ meal@2x.jpg/ meal@3x.jpg
然后,我们这样编写html和css:
1 | <body> |
1 | .meal { |
我在我4k以及1080p的屏幕上分别测试了一下,发现4k上用的是最高分辨率的meal@3x, 1080p上用的是最低分辨率meal
使用了这个技巧,我们就可以在不同分辨率的屏幕上展示不同大小的图片了
使用刚才的方法仍然不太方便,比如说:iPhone iPad和iMac的屏幕大小各不相同,假设他们都会选择meal@2x这张照片。
加入我的css写的只是400px,那图片仍然能保持一致,但是如果我的css写的是100vw,那么浏览器会拉长我们的图片,于是大屏的电脑和pad上的照片就会显得十分模糊。
对此,我们可以提供大小不同的三种图片,然后让浏览器根据屏幕的大小来自动选择最优图片。
我们可以将css清空,然后这样编写 html
1 | <body> |
如果 width 小于 500px的话,那么使用第一张图片并撑满整个宽
如果width大于500px而小于700px的话,那么使用第二张图片,并占一半的宽
如果width大于700px,那么使用第三张图片并占三分之一的宽
我们可以使用http://reponsivebreakpoints.com/ 这个网站帮我们为” breakpoints “生成不同大小的照片,就不再需要我们使用photoshop 自己调了
Using Modern Image Formats
https://cloudconvert.com/ 这是一个很好的在线转换工具。
我们可以将之前的 JPG文件转换成 WEBP文件,会小很多,浏览器加载起来也十分方便。
但是,IE是不支持显示WEBP文件的,因此我们应该这样写:使用<picture>
元素
picture元素可以根据屏幕匹配的不同尺寸显示不同图片,如果没有匹配到或浏览器不支持 picture 属性则使用 img 元素:
1 | <body> |
Art Directions
接下来我们继续使用picture元素来实现一些酷炫的操作
1 | <body> |
在picture中写queriemedia
Scalable Vector Graphic
Scalable Vector Graphic 就是可伸缩向量图形,其缩写就是SVG
我们可以使用 illustrator这个软件来创建SVG 文件,SVG文件小,且是永远不会失真的。 SVG也常常用于背景当中,我们可以利用 https://www.svgbackgrounds.com/ 来帮助我们选择背景。
1 | body { |
Font Icons
我们可以使用 Icon font来打出很多标签符号。有很多符号库,比如 Font Awesome ,Ionicons, Material Design Icons等。这里以 https://fontawesome.com/ 为例
在我们注册之后,我们只需要将其提供给我们的\
然后我们点击一个免费的图标,开始使用,然后复制其代码就可以了。
我们通过css对图标进行修改:
1 | .icon { |
Summary