了解css | 青训营笔记

160 阅读7分钟

了解css | 青训营笔记

这是我参与「第四届青训营 」笔记创作活动的的第三天。今天的课程是讲解css的相关知识。主要内容有

  • css是什么
  • 在页面中使用css
  • css是如何工作的
  • 字体族
  • 选择器的特异度
  • css继承与显示继承
  • css初始值
  • css求值过程

css是什么

用一句话概括css的话:“css是一种用来表示文件样式的计算机语言” 它可以用来页面元素的样式

  • 设置字体和颜色
  • 设置位置和大小
  • 添加动画效果

什么是css.png

在页面中使用css

页面中使用css,有三种方式

  • 外链,通过link标签引入css文件
<link rel= " stylesheet" href= " / assets/ style.css" >
  • 嵌入,在style标签中编写css代码
<style>
    li{
        margin:10px;
    }
</style>
  • 内联,直接在html标签上编写style属性
<p style= " margin: 0 " >Example Content</ p>

三种方式拥有不同的优先级,简单来说就是:内联>嵌入>外链。
在实际编写中,不推荐使用内联样式来编写css。虽然内联样式确实有它独特的优点,但是更多的是弊大于利。

css是如何工作的

css是如何工作的.png

通过这张非常基础而不完整的浏览器工作过程的图,我们可以看到。当我们打开一个页面后,浏览器会加载html,对html进行解析得到一颗dom树。在解析html的过程中,浏览器会发现通过外链、嵌入、内联所使用到的css,然后把这些css进行加载以及解析。然后通过一系列复杂的操作,把每一个dom树上的节点css属性给解析出来附加到dom树上,从而得到渲染树,即每个dom节点的位置应该在哪里,样式应该是什么样的之类的。最终渲染成真正的页面。

字体族

我们在设置字体的时候,不一定设置的字体在每个用户的设备上都有,这时候我们可以设置多个字体,使用逗号隔开。从左往右,当第一个字体没有的时候,就会去找第二个字体。

h1{
    font-family:Optima,Georgia,serif;
}
p{
    font-family:Helvetica,sans-serif;
}

上面代码中使用到的serif或sans-serif,并不是一个具体的字体,应该说它是一类字体,或者说叫通用字体族。目前浏览器支持五种通用字体族

字体族.png

例如将字体设置为sans-serif。浏览器会在系统中一个风格符合sans-serif的已存在字体进行设置。在编写代码时,除了指定我们需要的字体外,一定要在最后面还加上一个通用字体族,这样当设备中没有我们指定的字体时,会使用我们所指定的通用字体族,这样至少能保证整个网页上的字体与整个网页风格不会突兀。

就像是这样,在font-family最后面写上serif(衬线体),这样当设备上没有我们指定的字体的时候,至少展示出来的字体还是会是一个比较简洁的字体

h1{
   font-family:Optima,Georgia,serif; 
}

另外,如果在中英文混排的场景中,要将英文字体写在中文字体前面。

比如代码这样写,英文字符加载时就会使用helvetica字体(该字体中没有中文字符),而加载中文字符时,由于Helvetica字体中没中文字符,所以就会使用下一个字体,微软雅黑。

p{
    font-family:Helvetica,微软雅黑,sans-serif;
}

但是,如果把微软雅黑写在Helvetica前面,由于微软雅黑字体是包含中文与英文字符的,这时候不论是显示中文还是英文,由于微软雅黑字体都包含了该字符,于是中英文都会使用微软雅黑字体进行加载。

不过有时候我们设计会要求我们严格使用设计稿上要求的字体。这时候我们可以使用@font-face从服务器或者本地加载字体文件

@font-face{
    font-family:cusFontName;
    src:url(https://fonts.gstatic.com/s/megrim/v1/ 46kulbz5wjvLqJZVam_hvUdI1w. woff2)
    format('woff2');
}

浏览器渲染的时候会尝试从我们指定的地址去下载字体文件,然后使用该字体进行渲染。不过由于字体文件一般都比较大,而且使用从远程加载自定义字体的方式会带来额外的性能开销,甚至会出现由于字体文件过大,当字体文件还没有下载完成时网页的字体显示为默认字体,而当自定义字体加载完后又突然将网页上的字体替换成自定义字体的情况。
所以我们在使用自定义字体的时候,一般需要对字体文件进行裁切,特别是中文字体(中文字体的文件包一般都比较大)。只保留使用到的字符,减少字体文件包的体积,加快浏览器下载字体的速度。

选择器的特异度

所谓特异度,顾名思义,就是选择器的特殊程度。越特殊的选择器优先级就会越高。 如下图所示

选择器的特异度.png

我们将id、类(伪类)、标签从左只有排开。数选择器的组成,分别统计id、类(伪类)、标签的 出现次数。 如上图中的 #nav .list li a:link,id出现了1次,类(伪类)出现了2次,标签出现了2次,则得到特异度为122;又如.hd ul.links a,id出现了0次,类(伪类)出现了2次,标签出现了2次,则得到特异度为022。显然122比022要大,则如果#nav .list li a:link.hd ul.links a同时作用与同一个标签上,则生效的是特异度为122的#nav .list li a:link选择器。

再来看下面这个例子

image.png .btn的特异度为010;.btn.primary的特意度为020。显然.btn.primary的优先级会更高。所以当写下button class='btn primary'>主要按钮</button>时,.btn.primary选择器的样式会覆盖.btn选择器的样式,按钮的背景就被设置为蓝色,字体颜色为白色。

css继承与显示继承

当我们给字体设置大小、颜色等属性时,如果我们只给父级元素进行了设置,那子元素的字体样式会继承自父元素的计算值。

如下图所示,p标签被设置了文字颜色为blue,而strong标签没有设置文字颜色,则strong标签中文字颜色会继承字它的父级元素——p标签,最终文字颜色为blue。

image.png

需要注意的一点是,继承的css属性值不是我们设置的值,而是计算值。

例如:下面这段代码,i标签中的文字的大小继承自span标签,但是继承的文字大小值并非1em,而是24px(计算后的值)。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        p{
            font-size: 24px;
        }
        span{
            color: red;
            font-size: 1em;
        }

    </style>
</head>
<body>
    <p>
        我是一段文字文字文字文字文字文字文字文字文字
        <span>我是继承来的字体大小<i>666</i></span>
        我是一段文字文字文字文字文字文字文字文字文字
    </p>
</body>
</html>

一般来说,和文字相关的属性都是可以继承的。和盒子模型相关的属性都是不可以继承的。

那我们在设置盒子模型的属性时希望属性是继承的我们该怎么做呢???

image.png

如上图所示,
使用通配选择器*,将box-sizing属性的值设置为inherit,那么之后写的所有的容器的box-sizing属性值都会是inherit。当然如果我们又需要某个容器的box-sizing值不再显示继承的话,就可以利用我们上面提到的选择器的特异度,用更高优先级的选择器进行样式的覆盖。如.some-widget的特异度要高于*.some-widget选择器设置的值就会覆盖*设置的值。

css初始值

image.png

css求值过程

个人认为这堂课上使本人获益良多的就使这个知识点了。
css的样式是怎么样被计算出来的呢?这就涉及到css的求值过程中的问题了。
这个过程可以说是非常复杂,我们可以通过下面这张图来简单描述一下

css求值过程.png