HTMLandCSS基础3-印刷与图片

文字与图片

$sss^y$

Typography

Styling Fonts

网页上的字体大体可以分成三类:Serif, Sans-serif, Monospace

Serif 衬线字体族

  • 具有修饰过的笔画,向外展开的或者尖细的末端,或者是带有实际衬线的末端
  • 一笔一划末端(两头)都带点变化装饰,比如宋体笔画末端有毛笔字的感觉
  • 文字末端有差异,在小字号下仍然容易辨认。但在大字号下笔画装饰部分可能会显得模糊或带有锯齿

Sans-serif 无衬线字体族

  • 具有笔画清晰的末端–带有一点或者没有向外展开的,交错笔画,或者其它装饰
  • 与“衬线字体”相比,如果字号比较小,看起来就会有些难以分辨,尤其段落阅读时容易串行

左侧是 Sans-serif, 右侧是serif

monospace 等宽字体族

  • 每个字形都等宽,主要用于英文,中文方块字本来就等宽

font-family

我们可以通过设置 font-family来设置段落的字体。比如:

1
2
3
4
5
6
7
body {
margin: 10px;
font-family: Arial, Helvetica, sans-serif;
}
h1 {
font-family: Georgia, "Times New Roman", Times, serif;
}

这里我只设置了 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

我们可以从这些网站上下载字体,有些字体是免费的,有些字体是收费的

https://www.fontsquirrel.com/

https://www.fonts.com/

http://myfonts.com/

下载的字体文件有好几种格式: TTF OTF EOT WOFF WOFF2.0 。在网页上使用的时候,我们主要使用WOFF和WOFF2.0这两种格式。

我们下载一个免费的字体Open Sans来作为例子,下载的格式是tff。我们可以到

https://www.fontke.com/tool/convfont/ 这里将其转换为 WOFF/WOFF2格式。接下来我们要将这些字体应用于我们的网页。我们用下面这套模板来注册字体。

1
2
3
4
5
6
7
@font-face{
font-family: "opensans";
src: url("fonts/open-sans/OpenSans-Bold.woff2") format("woff2")
url("fonts/open-sans/OpenSans-Bold.woff") format("woff")/*url中放引用地址*/
font-weight: bold;
font-style: normal;
}

在使用的时候,我们需要在字体前面加上family name即可

1
2
3
4
body {
margin: 10px;
font-family:"opensans", Arial, Helvetica, sans-serif;
}

Flash of Unstyled Text

当我们使用自己下载的字体的时候,如果浏览器的渲染速度非常慢,它可能先渲染出原来的字体,然后再渲染我们下载来的字体。这叫做 Flash of Unstyled Text 这对用户的体验不是很友好。

为了解决这个问题,我们可以设置 font-display属性, 默认情况下这个属性为被设置为auto,chrome的渲染模式就是先渲染一个备用字体,然后再渲染我们定制的字体。但是不同浏览器的策略也是不同的。

我们可以将其设置为fallback,也就是说,当经过很长时间我们的定制字体还没有被下载好的话,那么就可以使用备用字体。以免在阅读途中遭遇切换字体的烦恼。

如果我们将 font-display设置成block的话,那么在我们的定制字体没有被下载好之前,文字是没有办法显现的。但这个操作十分危险,如果字体未下载成功,那么我们将看不见这些文字。

最后一个 font-display的值未 optional,这是一个较好的选择。当定制的字体还没有被下载好的时候,浏览器一开始会使用备用字体,并将其保存在浏览器的缓存当中。 当我们打开子网页的时候,浏览器就会从缓存中取出字体并使用。这能让用户在未察觉的时候切换字体。

Font Services

很多字体的使用权限非常贵。因此我们可以使用一些字体库,我们只需要按月订阅就能使用很多字体。

https://fonts.google.com/

https://fonts.adobe.com/

http://fontdeck.com/

我们以google fonts为例,讲一下怎么使用 谷歌的字体服务

在我们选择好字体之后,谷歌提供了 link和 @import两种方法来将字体导入到网页当中。

我们复制其提供的链接,然后在html的header中插入。链接一共有两个 <link>元素,第一个是告诉浏览器,我们的网页存在一个与https://fonts.gstatic.com的链接,目的是让我们尽快从字体服务网站上下载字体。

第二个网站是一张 stylesheet的链接。stylesheet是由谷歌生成的,里面是各种 @font-face 我们只管引用即可.

1
2
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&family=Roboto:wght@700&display=swap" rel="stylesheet">

同样的,我们只要在font-family后面写上”Open Sans” ,就能使用这个字体了

1
2
3
4
5
6
7
body {
margin: 10px;
font-family: "Open Sans", Arial, Helvetica, sans-serif;
}
h1 {
font-family: "Roboto", Arial, Helvetica, sans-serif;
}

System Font Stack

有了这个栈,我们就能告诉浏览器对用户的电脑使用操作系统中的默认字体

有了这个栈有几点好处:

  1. Can boost performance,因为电脑没必要去网上下载字体了
  2. 避免了Flash of unstyled text
  3. Native Look

总之,它能带给用户更好的体验。不过不同系统的 字体栈是不一样的。如果我们要强行定义网页系统的字体栈,我们可以在font-family中打一个 -

1
2
3
4
5
body {
margin: 10px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
}

Sizing Fonts

现在我们再来谈谈 字体的大小。一般我们使用px也就是 pixel来定义字体大小。但是在不同分辨率不同机器上,对pixel的大小的定义也是不同的。如果我们在Windows机器上定义字体为20px,那在mac电脑上看起来会更小一点

所以我们可以使用 相对单位。使用 rem 作为单位会更好一点。也方便我们做 media queiries:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
html{
font-size: 62.5%;
}
body {
margin: 10px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;

font-size: 1.5rem;
}
h1 {
font-family: Georgia, 'Times New Roman', Times, serif;
font-size: 2rem;

}
p {
font-weight: bold;
}


@media screen and (min-width: 768px) {
html{
font-size: 100%;
}
}

当我们窗口宽度小于 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
2
3
h1 {
margin: 3rem 0 1rem;
}

第四个位置不用写,因为会自动认为和第二个值一样。效果如下:

此外,还可以设置line-height 属性来设置行距。 但是要注意,如果同时设置 font-sizeline-height 的话,要注意 font-size不能设置的比 line-height 还要大,因为这样行和行之间就挤在一起了,非常不美观。为了解决这个问题我们可以这样写:

1
2
3
4
5
body {
margin: 10px;
font-size: 2rem;
line-height: 1.5;
}

去掉 line-height 的单位,他就表示当前字体的倍数,因此不管字体设置为多大,行距始终是1.5倍的字体大小。

Horizontal Spacing

letter-spacing

这个属性是设置字母与字母之间的距离,比如将其设置为 1rem会发生这样的结果:

因此使用px而不是rem才是正确的选择,根据字体的不同我们可以对其进行调节。

word-spacing

为了阅读方便,每一行所容纳的数字大概在50-70左右。 我们可以通过设置 width函数,用 ch作为单位,ch就是一行中可以写几个0。然后根据这个自动计算 单词之间的距离。

1
2
3
p {
width: 50ch;
}

Formatting Text

text-align

这个属性规定元素中的文本的水平对齐方式。

  • left, right,center : 把文本排列到左边(默认)/右边/中间
  • justify: 可以使文本的两端都对齐。但是这样就会导致每一行中词与词之间的间距是不同的。
  • inherit:从父元素继承 text-align的属性值

text-indent

这个属性规定文本块中首行文本的缩进。常用于建立一个“标签页”效果。允许指定负值,这会产生一种“悬挂缩进”的效果,比如说

1
2
3
p {
text-indent: 1rem;
}

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
2
3
4
5
6
7
p {
width: 50ch;
white-space: nowrap;
border: 3px solid gold;
overflow: hidden;
text-overflow: ellipsis;
}

column-*

如果我们要实现分栏,可以这样写:

1
2
3
4
5
p {
width: 50ch;
column-count: 2;
column-gap: 1rem
}

如果我们愿意,还可以在栏和栏之间加上分割线:

1
column-rule: 3px dotted #999

direction

如果把这个元素设置为 rtl,那么文字就是这样的:比较符合阿拉伯人的书写习惯

Summary

Exercise

Images

Image Types and Formats

transparency是指照片是否支持透明背景。 jpeg格式的照片是不支持透明背景的,gif只支持256种颜色。

Content Images

我们可以在html语言中插入图片。

1
2
3
<body>
<img src="images/meal.jpg" alt="A bowl of salmon and curry">
</body>

src就是图片的路径,alt 是当下载图片失败的时候,我们看到的替代图片的文字。

当我们想要插入的图片并不需要描述时,比如一个箭头之类的装饰性图片,我们可以把alt置为空字符串,但是不要删去alt,因为这样浏览器就会将alt默认设置为这张图片的名字。

我们可以设置width属性来调整图片的大小,但是放得太大会导致画面失真。

Background Images

现在我们来说说背景图。我们在css中可以设置背景图。

首先是background属性,这个属性既可以写颜色,又可以将图片设置为背景,我们只需要将url写入即可。

如果不做任何修改,那么背景图就会在浏览器窗口平铺,也就是不断重复排列。因此如果我们不希望重复排列,我们可以将background-repeat属性设置为no-repeat.

接下来,我们可以通过设置background-position 属性来调整图片在窗口中的位置。并通过 background-size 来调整背景图片的大小。

比如这样编写css:

1
2
3
4
5
6
body {
background: url("../images/bg-paper.jpg");
background-repeat: no-repeat;
background-size: 100% 100%;
height: 100vh;
}

不过,我们可以直接使用 cover值,效果和写两个100% 是一样的

1
2
3
4
5
6
body {
background: url("../images/bg-paper.jpg");
background-repeat: no-repeat;
background-size: cover;
height: 100vh;
}

现在,我们用金门大桥作为背景,然后写一个h1

现在我将height改成300vh,我们发现背景会随着滚轮一块滚动,而且图片也随之扩大了3倍。

为了固定住背景图,只让内容滚动,我们可以使用background-attachment ,将其设置为fixed。

效果如下:

CSS Sprites

我们可以在 http://flaticon.com/ 网站上下载图标

比如:

1
2
3
4
5
6
7
<body>
<img src="images/dishes.png" alt="">
<img src="images/landing.png" alt="">
<img src="images/rocketship.png" alt="">
<img src="images/saturn.png" alt="">
<img src="images/ufo.png" alt="">
</body>

但是这样一来,浏览器加载一次就需要加载五张图片。能不能通过一种方法将五张图合并起来,但是又能在不同的地方使用单个标签,这样就使得浏览器只请求一次即可。

我们可以用 CSS Sprites 工具: http://cssspritestool.com/

只需要将图片拖入,然后进行简单的设置。就可以得到一张包含五个 图标的图了。

我们还得到一个自动生成的css文件,教我们如何在网页中引用这些图标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.bg-rocketship
{
background:url('css-sprite-combined.2.png') 0px -0px;
width:100px;height:100px;
display:inline-block;
}

.bg-saturn
{
background:url('css-sprite-combined.2.png') -100px -0px;
width:100px;height:100px;
display:inline-block;
}

.bg-ufo
{
background:url('css-sprite-combined.2.png') -200px -0px;
width:100px;height:100px;
display:inline-block;
}

.bg-dishes
{
background:url('css-sprite-combined.2.png') -300px -0px;
width:100px;height:100px;
display:inline-block;
}

.bg-landing
{
background:url('css-sprite-combined.2.png') -400px -0px;
width:100px;height:100px;
display:inline-block;
}

我们只需要修改一下相对路径,然后将图片的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
2
3
.meal:hover {
filter: blur(3px) grayscale(70%);
}

我们可以在 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
2
3
4
5
6
7
8
<body>
<img src="images/meal.jpg"
alt="A bowl of salmon and curry"
class="meal"
srcset="images/meal.jpg 1x,
images/meal@2x.jpg 2x,
images/meal@3x.jpg 3x">
</body>
1
2
3
.meal {
width: 400px;
}

我在我4k以及1080p的屏幕上分别测试了一下,发现4k上用的是最高分辨率的meal@3x, 1080p上用的是最低分辨率meal

使用了这个技巧,我们就可以在不同分辨率的屏幕上展示不同大小的图片了

使用刚才的方法仍然不太方便,比如说:iPhone iPad和iMac的屏幕大小各不相同,假设他们都会选择meal@2x这张照片。

加入我的css写的只是400px,那图片仍然能保持一致,但是如果我的css写的是100vw,那么浏览器会拉长我们的图片,于是大屏的电脑和pad上的照片就会显得十分模糊。

对此,我们可以提供大小不同的三种图片,然后让浏览器根据屏幕的大小来自动选择最优图片。

我们可以将css清空,然后这样编写 html

1
2
3
4
5
6
7
8
9
10
11
12
<body>
<img src="images/meal.jpg"
alt="A bowl of salmon and curry"
class="meal"
srcset="images/meal.jpg 400w,
images/meal@2x.jpg 800w,
images/meal@3x.jpg 200w"
sizes="(max-width:500px) 100vw,
(max-width: 700px) 50vw,
33vw"
>
</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
2
3
4
5
6
7
<body>
<picture>
<source type="image/webp" src="images/meal.webp">
<source type="image/jpeg" src="images/meal.jpg">
<img src="images/meal.jpg" alt="A bowl of salmon and curry">
</picture>
</body>

Art Directions

接下来我们继续使用picture元素来实现一些酷炫的操作

1
2
3
4
5
6
7
<body>
<picture>
<source media="(max-width: 500px)" srcset="images/meal-cropped.jpg">
<source media="(min-width: 501px)" srcset="images/meal.jpg">
<img src="images/meal.jpg" alt="A bowl of salmon and curry">
</picture>
</body>

在picture中写queriemedia

Scalable Vector Graphic

Scalable Vector Graphic 就是可伸缩向量图形,其缩写就是SVG

我们可以使用 illustrator这个软件来创建SVG 文件,SVG文件小,且是永远不会失真的。 SVG也常常用于背景当中,我们可以利用 https://www.svgbackgrounds.com/ 来帮助我们选择背景。

1
2
3
body {
background: url(../images/constellation.svg);
}

Font Icons

我们可以使用 Icon font来打出很多标签符号。有很多符号库,比如 Font Awesome ,Ionicons, Material Design Icons等。这里以 https://fontawesome.com/ 为例

在我们注册之后,我们只需要将其提供给我们的\ 元素复制到html文件当中就可了

然后我们点击一个免费的图标,开始使用,然后复制其代码就可以了。

我们通过css对图标进行修改:

1
2
3
4
.icon {
font-size: 2rem;
color: dodgerblue;
}

Summary

Exercises

-------------本文结束,感谢您的阅读-------------