理解CSS | 青训营笔记

183 阅读10分钟

理解CSS

这是我参与「第五届青训营 」笔记创作活动的第2天

本堂课重点内容

  • CSSd代码构成
  • CSS使用方法
  • CSS流程之选择器组、文本渲染
  • 调试CSS
  • CSS 选择器的特异度
  • CSS继承
  • CSS 求值过程解析
  • CSS布局方式及相关技术

详细知识点介绍

代码构成

h1 {
    color:white;
    font-size:14px;
}
  • h1为选择器 —— 选择为哪些元素添加样式
  • colorfont-size为样式属性
  • white14px为属性值
  • color:white;,属性加属性值的模块叫做声明

使用方法

  1. 外链

    创建CSS文件,编写相关样式,在HTML文件中引入

    <link rel="stylesheet" href="/assets/style.css">
    
  2. 嵌入式

    在HTML文件中通过<style>标签添加样式

    <style>
        li {
            margin:0;
            list-style:none;
        }
    </style>
    
  3. 内联式

    HTML标签中都有style属性,可直接在标签中添加

    <P style="margin: 1em 0">
        Example Content
    </P>
    

CSS流程之选择器组、文本渲染

CSS是如何工作的:

image-20230116111510026.png

选择器

  • 找出页面中对应的元素,以便给它们设置样式

  • 使用多种方式选择元素

    • 按照标签名、类名或id
    • 按照属性
    • 按照DOM树的位置
通配选择器

为所有元素添加样式,会匹配页面所有的元素,降低页面相应速度,不建议随便使用。

* {
    font-size:20px;
}

我们一般通过通配选择器来清除标签的默认边距

* {
    margin:0;
    padding:0;
}
id选择器

模板:

#id值 {
    
}
<h1 id="logo">
    理解CSS
</h1><style>
    #logo {
        font-size:60px;
        font-weight:200;
    }
</style>

在HTML文件中id一般是唯一的,如果id不唯一,虽然CSS样式会生效,但是最后的结果可能会不符合预期(多个重复的id,可能会书写多份样式,造成样式覆盖,最后出现问题)

类选择器

使用场景:多个元素的样式相同

模板:

.class值 {
    
}
<ul>
    <li class="done">learn HTML</li>
    <li class="done">learn CSS</li>
</ul>
<style>
    .done {
        color:gray;
        text-decoration:line-through;
    }
</style>
属性选择器
/* 存在 title 属性的<a> 元素 */
a[title] {
  color: purple;
}
​
/* 存在 href 属性并且属性值匹配"https://example.org"的<a> 元素 */
a[href="https://example.org"] {
  color: green;
}
​
/* 存在 href 属性并且属性值包含"example"的<a> 元素 */
a[href*="example"] {
  font-size: 2em;
}
​
/* 存在 href 属性并且属性值开头是"http"的<a> 元素 */
a[href^="http"] {
    font-size: 1em;
}
​
/* 存在 href 属性并且属性值结尾是".org"的<a> 元素 */
a[href$=".org"] {
  font-style: italic;
}
​
/* 存在 class 属性并且属性值包含以空格分隔的"logo"的<a>元素 */
a[class~="logo"] {
  padding: 2px;
}
伪类
  • 不急于标签和属性定位元素

  • 分类

    • 状态伪类
    • 结构性伪类

状态伪类: 比如a标签,访问过与未访问的状态

a:link {
    color:black;
}
​
a:visited {
    color:gray;
}

结构伪类:

根据DOM节点的位置来选择元素

<ul>
    <li>阿凡达</li>
    <li>泰坦尼克号</li>
    <li>星球大战</li>
    <li>复仇者联盟</li>
</ul>
/*li元素且是第一个子节点*/
li:first-child {
    color:coral;
}
​
/*li元素且是最后一个子节点*/
li:last-child {
    border-bottom:none
}
组合
名称语法说明示例
直接组合AB满足A同时满足Binput:focus
后代组合A B选中B,如果他是A的子孙nav a
亲子组合A>B选中B,如果他是A的子元素section>p
兄弟选择器A~B选中B,如果它在A后且和A同级h2~p
相邻选择器A+B选中B,如果它紧跟在A后面h2+p

文本渲染

颜色
  1. RGB:rgb(0,0,0)#000000的写法

  2. HSL:hsl(0,100%,50%)

    image-20230116134336411.png

    HSL形式在调节饱和度和亮度方面比RGB形式更方便

不透明度

不透明度值范围[0,1]

  • #ff000078

  • rgba(255,0,0,0.47)

  • hsla(0,100%,50%,0.47)

字体 font-family
body {
    font-family: Optima, Georgia, serif;
}

我们会在font-family中放入多种字体名称,这是因为:不同的用户可以使用的字体是不同的,比如以上代码,Optima字体无法使用,将会尝试Georgia字体,最后会有一个通用免费的字体用于兜底

使用Web Fonts

我们可以先从网上下载对应的字体,后在样式中使用,但是对性能有一定的影响

<h1>Web fonts are awesome!</h1><style>
    @font-face {
        font-family: "Megrim";
        src: url(https://fonts.gstatic.com/s/megrim/v11/46kulbz5WjvLqJZVam_hVUdI1w.woff2) format('woff2');
    }
​
    h1 {
        font-family: Megrim, Cursive;
    }
</style>

提示:

在中英文都需要引入字体的情况下,英文字体放在中文字体的前面。这是为了防止使用中文字体渲染英文

字体大小
  • 关键字

    • small
    • medium
    • large
  • 长度

    • px
    • em
  • 百分数

    • 相对于父元素字体大小
字重(粗细)
  • 关键字:

    • normal(400)、bold(700)、bolder
  • 数字

    • [100,900],整百

修改字重发现变化不大,可能是因为该字体在设计中并没有那么多字重

字体行高

两行文字基准线的距离

.content {
    line-height:18px;
}

我们一般使用line-height:1.6来表示行高是字体的1.6倍

文本对齐
/* Keyword values */
text-align: left;
text-align: right;
text-align: center;
text-align: justify;
text-align: justify-all;
text-align: start;
text-align: end;
text-align: match-parent;
​
/* Block alignment values (Non-standard syntax) */
text-align: -moz-center;
text-align: -webkit-center;
​
/* Global values */
text-align: inherit;
text-align: initial;
text-align: unset;
  • start

    如果内容方向是左至右,则等于left,反之则为right

  • end

    如果内容方向是左至右,则等于right,反之则为left

  • left

    行内内容向左侧边对齐。

  • right

    行内内容向右侧边对齐。

  • center

    行内内容居中。

  • justify

    文字向两侧对齐,对最后一行无效。

  • justify-all

    和 justify 一致,但是强制使最后一行两端对齐。

间距
  • letter-spacing字母间距
  • word-spacing单词间距
.text {
    letter-spacing:2px;
    word-spacing:4px;
}
首行缩进
.text {
    text-indent:5px;
}

首行缩进2个字符:

.text {
    text-indent:2em;
}

em是相对长度单位,1em = 一个字体的大小,所以无论字体大小怎么设置,都是自适应缩进2个字符

文本修饰
text-decoration: underline dotted red 5px;

text-decoration 属性是一种简写属性,并且可以使用普通属性三个值中的任何一个。普通属性如下:text-decoration-linetext-decoration-colortext-decoration-style

空格处理

white-space CSS 属性是用来设置如何处理元素中的空白

  • nomal

    连续的空白符会被合并,换行符会被当作空白符来处理。

  • nowrap

    连续的空白符会被合并,但文本内的换行无效

  • pre

    连续的空白符会被保留。在遇到换行符或者<br>元素时才会换行。

  • pre-wrap

    连续的空白符会被保留。在遇到换行符或者<br>元素,或者需要为了填充时才会换行。

  • pre-line

    连续的空白符会被合并。在遇到换行符或者<br>元素,或者需要为了填充时才会换行。

调试CSS

右键点击页面,选择检查

CSS 选择器的特异度

image-20230116151456197.png

image-20230116151640360.png 因为122 > 22,所以第一个选择器的优先级较高

<button class="btn">普通按钮</button>
<button class="btn primary">主要按钮</button>
<style>
  .btn {
    display: inline-block;
    padding: .36em .8em;
    margin-right: .5em;
    line-height: 1.5;
    text-align: center;
    cursor: pointer;
    border-radius: .3em;
    border: none;
    background: #e6e6e6;
    color: #333;
  }
  .btn.primary {
    color: #fff;
    background: #218de6;
  }
</style>

image.png

我们发现两个按钮的背景色和字体颜色,.btn.primary选择器的样式覆盖了.btn选择器中的样式

CSS继承

有些属性会自动继承父元素的计算值,如果父级没有可以继承的属性,那么会继续向上查找,如果到顶部仍未有可继承的计算值,那么就会使用到属性的初始值,除非用现实的一个值进行覆盖

<p>This is a <em>test</em> of <strong>inherit</strong></p>

<style>
  body {
    font-size: 20px;
  }
  p {
    color: blue;
  }
  em {
    color: red;
  }
</style>

但是对于盒模型相关的属性大多数都是不能继承的,对于不能自动继承的属性,我们可以使用inherit进行显示继承

* {
    box-sizing:inherit;
}

html {
    box-sizing:border-box;
}

.some-widget {
    box-sizing:content-box;
}
  1. 通配选择器,使box-sizing能过被继承
  2. 在文档的最外层<html>设置样式box-sizing:border-box;,那么页面中的所有标签的盒模型都是按照border-box进行计算的
  3. 如果需要使用content-box进行计算,那么就需要指定一个值来覆盖它

初始值:

  • CSS中,每个属性都有一个初始值

    • background-color的初始值为transparent
    • margin-left的初始值为0
  • 可以使用initial关键字显示重置为初始值

    • background-color:initial

CSS求值过程解析

image.png

CSS 布局方式及相关技术

image.png

如果padding|margin的属性值为百分数,那么尺寸是依据容器的宽度计算的

边距重叠问题:

<div class="a"></div>
<div class="b"></div>

<style>
  .a {
    background: lightblue;
    height: 100px;
    margin-bottom: 100px;
  }

  .b {
    background: coral;
    height: 100px;
    margin-top: 100px;
  }
</style>

image.png 两个元素各自设置了上下边距为100px,但是从效果上看,两个元素之间的距离只有100px,而不是预期的200px,两个元素的距离取决于margin的最大值 行级排版上下文

  • Inline Formmatting Context(IFC)
  • 有包含行级盒子的容器会创建一个IFC
  • IFC内的排版规则:
    • 盒子在一行内水平摆放
    • 一行放不下,换行显示
    • text-align决定一行内的水平对齐
    • vertical-align决定一个盒子在行内的垂直对齐
    • 避开浮动(float)元素

块级排版上下文

  • Block Formatting Context(BFC)
  • 某些容器会创建一个BFC
    • 根元素
    • 浮动、绝对定位、inline-block
    • Flex子项和Grid子项
    • overflow值不是visible的快盒
    • display:flow-root;
  • 排版规则:
    • 盒子从上到下排放
    • 垂直margin合并
    • BFC内盒子的margin不会于外部的合并
    • BFC不会和浮动元素重叠
<span>
  This is a text and
  <div>block</div>
  and other text.
</span>

<style>
  span {
    line-height: 3;
    border: 2px solid red;
    background: coral;
  }

  div {
    line-height: 1.5;
    background: lime;
  }
</style>

image.png span本身是一个行级的盒子,里面嵌套一个块级的盒子,浏览器不允许行级盒子块级和行级并存,所以会创建两个匿名盒子对<span>标签进行包裹

发现:两个文本被一个块级盒子隔断,第一个文本没有右边框,第二个文本没有左边框

Flex Box是什么:

  • 一种新的排版上下文
  • 它可以控制子级盒子的:
    • 摆放的流向
    • 摆放的顺序
    • 盒子宽度和高度
    • 水平和垂直的对齐
    • 是否允许换行

可参考阮一峰的文章:Flex布局教程

属性介绍: image.png

  1. flex-direction决定主轴及方向

    image.png

  2. justify-content定义主轴上的对齐方式 image.png

  3. align-items定义侧轴上的对齐方式 image.png

  4. align-self覆盖侧轴上的对齐方式
    image.png

  5. order定义排列书讯

    image.png

Flexibility:

  • 可以设置子项的弹性:当容器有剩余空间时,会伸展;容器空间不够时,会收缩。

  • flex-grow:有剩余空间时的伸展能力

    <div class="container">
      <div class="a">A</div>
      <div class="b">B</div>
      <div class="c">C</div>
    </div>
    
    <style>
      .container {
        display: flex;
      }
    
      .a, .b, .c {
        width: 100px;
      }
    
      .a {
        flex-grow: 2;
      }
    
      .b {
        flex-grow: 1;
      }
    </style>
    

    image.png A、B、C三个元素都是100px,但是容器还有剩余空间,那么就会按照伸缩能力来决定宽度的大小

  • flex-shrink:容器空间不足时收缩的能力

    <div class="container">
      <div class="a">A</div>
      <div class="b">B</div>
      <div class="c">C</div>
    </div>
    
    <style>
      .container {
        display: flex;
      }
    
      .a, .b, .c {
        width: 400px;
      }
    
      .a {
        flex-shrink: 0;
      }
    </style>
    

    A、B、C三个元素宽度都为400px,但是容器宽度不足,因为A元素flex-shrink: 0;,缩放能力为0,不能进行缩放,所以B、C缩放相同的比例至满足容器的宽度

  • flex-basis:没有伸缩或收缩时的基础长度

Grid布局:

  • display:grid使元素生成一个块级Grid容器
  • 使用grid-template相关属性将容器划分为网格
    • grid-template-columns:定义每个列的宽度
    • grid-template-rows:定义每个行的高度
  • 设置每一个子项占哪些行/列
    .a {
      grid-area: 2/2/4/4;
    }
    .b {
      grid-area: 1/1/3/3;
    }
    

Float

有了Flex布局与Grid布局,Float更多的使用是在图文关系上

<section>
  <img src="https://p4.ssl.qhimg.com/t017aec0e7edc961740.jpg" width="300" alt="mojave" />
  <p>莫哈韦沙漠不仅纬度较高,而且温度要稍微低些,是命名该公园的短叶丝兰——约书亚树的特殊栖息地。约书亚树以从茂密的森林到远远间隔的实例等各种形式出现。除了约书亚树森林之外,该公园的西部包括加州沙漠里发现的最有趣的地质外观。
  </p>
</section>

<style>
  img {
    float: left;
  }

  p {
    font-size: 20px;
    line-height: 1.8;
  }
</style>

image.png Position

position属性

  • static默认值,非定位元素
  • relative 相对自身原本位置偏移,不脱离文档流
  • absolute 绝对定位,相对非static祖先元素定位
  • fixed 相对于视口绝对定位

课后个人总结

  • 根据老师讲解的内容,再次查找MDN上的相关资料,重拾遗忘的知识,学到一些新的内容