深入 CSS | 青训营笔记

222 阅读11分钟

欢迎来到 RMX08 的 金元宝集合箱!!

这是我参与「第五届青训营」伴学笔记创作活动的 第3天 ,作为一个前端微小白,希望能在接下来的一个月中收获满满的 金元宝 。

选择器特异度 Specificity

image.png

如上图,当多个选择器选择到相同的元素,并且设置相同种类的样式时,选择器的优先级便起到了作用。选择器越特殊,优先级越高

image.png

由上图,#nav .list li a:link 的特异度就 大于 .hd ul.links a

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

image.png

上述代码,.btn > .btn.primary,因此“主要按钮”的字体颜色、背景颜色会进行覆盖。

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

image.png

有上述代码,当选择器相同时,后续样式会对前面的同种样式进行覆盖。

继承

某些属性会 自动 继承其父元素的计算值,除非显式指定一个值。

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

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

image.png

上述代码中,color 属性便能自动继承。<em> 标签设置样式为红色,便显示字体颜色为红色。<strong> 标签未设置字体颜色,便会继承父级标签 <p>的字体颜色,显示蓝色字体。

一般在 CSS 中,与 字体 相关的属性都能继承,而与 盒子模型 相关是不可继承的,如 宽度

显示继承

如果要人为的要从父级继承某些属性值,便可使用 inherit ,让原本不可继承的属性变成可继承的。

image.png

初始值

每一个元素在规范里面就已经规定的属性值,倘若不能继承的属性且又没有被设置属性值,或可继承的属性但并未继承到父级属性,便会用到初始值。

image.png

CSS 求值过程

image.png

计算值与使用值得区别

  • 计算值 为浏览器在获得 CSS 后,单纯分析 CSS 就能够马上转化出来的相对值,便可在 resolving 阶段进行转化,如字体大小为20px,行间距为1.6,便可直接得出行间距得绝对值为32px。
  • 使用值 为单纯分析 CSS 后无法直接得出绝对值,便放在 formatting 阶段进行转化。如设置 <body> 标签宽度为100%,单纯看 html 或 CSS 无法得知宽度,需将其带入实际的渲染环境下,用户打开页面时浏览器的宽度是多少,才可知晓。
  • 计算值与使用值在 继承 中值得注意,一些可以继承的属性是继承于父级元素的 计算值。例如,父级中 font-size 为 1.2em,并非子元素中会继承到 1.2em,而是其 计算值

布局 Layout

image.png

布局相关技术

布局会用到三种方式:常规流浮动绝对定位image.png

  • 常规流 normal flow

    或称 文档流。其中又存在不同规则、布局方式,如 块级 便从上往下去摆,行级 便像文字一样一行行去书写。还有 FlexBoxGrid 布局

  • 浮动 可以把一些元素设计成浮动,例如将图片设置成浮动,可以做文字环绕图片的效果。

  • 绝对定位 可以直接覆盖在常规流之上,任意的去改变元素的位置,而不会对常规流造成什么影响。

常规流

盒模型 Box

image.png 可以将之理解为一个容器,每个容器里面会给内容(content)留有一些 宽度(width)还有 高度(height),除此之外还有 内边距(padding) 、边框(border) 、外边距(margin)。

默认情况下,在 CSS 中去指定高度还有宽度,其实指定的是 box 中内容的高度还有宽度。而边框和内外边距则是在内容的基础下再往外扩。

width

image.png

heigh

image.png

padding

image.png

image.png 若设置一个数值,则代表 上下左右内边距 大小皆为该数值;

若设置两个数值,则表示 上下内边距 大小为第一个数值,左右内边距 大小为第二个数值;

若设置四个数值,则表示 左内边距 依次为四个数值 (顺时针)

border

指定边框 样式 (style)、粗细 (width)、颜色(color)。

样式可分为 无边框(none)、实线(solid)、虚线(dashed)、点画线(dotted)。

  • none

    image.png

  • solid

    image.png

  • dashed

    image.png

  • dotted

    image.png

边框样式调节器 ⇨ CodePen - 青训营/CSS/border (cdpn.io)

同样,边框的四条边都可以拆分独自设立样式,以及组合设置。

image.png

当四条边框 颜色都不一样 时,四条边框分割线如下图 ↓ ↓ ↓

image.png

当 content 高度与宽度都为 0 并调整各边颜色时,会得到下图 ↓ ↓ ↓

image.png image.png

margin

image.png

倘若 左右外边距 都设置为 auto,容器便会 水平居中

<div></div>

<style>
  div {
    width: 200px;
    height: 200px;
    background: coral;
    margin-left: auto;
    margin-right: auto;
  }
</style>

image.png

  • margin collapse
<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

两个块级设置上下外边距,但放在一块时,边距并不会相加,而是 选择最大值 作为边距。

box-sizing :border-box

用来定义边框的高度和宽度,那么其中的content的高度和宽度,就要减去 border 和 padding 。

<p class="a">
  This is the behavior of width and height as specified by CSS2.1. The
  specified width and height (and respective min/max properties) apply to
  the width and height respectively of the content box of the element.
</p>
<p class="b">
  Length and percentages values for width and height (and respective min/max
  properties) on this element determine the border box of the element.
</p>

<style>
  html {
    font-size: 24px;
  }

  .a {
    width: 100%;
    padding: 1em;
    border: 3px solid #ccc;
  }

  .b {
    box-sizing: border-box;
    width: 100%;
    padding: 1em;
    border: 3px solid #ccc;
  }
</style>

image.png

如上述代码,a 容器中所设置的 width 属性便是 content 的宽度,因此整个 content 宽度与显示页面相同,边框超出,便会产生拖拉条。

b 容器中由于设置了 box-sizing :border-box ,因此其 width 属性便是指边框的宽度,正好适应显示页面。

在实际的项目中,border-box 使用更频繁。

overflow

当 content 的内容超出了所设置的高度和宽度,便可以使用 overflow 规定剩下的内容要如何展示。

  • visible

    不管高度设定,依旧显示。

    image.png

  • hidden

    多出部分直接截去。

    image.png

  • scroll

    多出的内容采用 滚动条 显示。

    image.png

盒模型中 —— 块级 vs. 行级

盒模型中 最常见 的两个布局规则。

块级盒子

  • Block Level Box
  • 不会和其他的盒子并列摆放 (放在同一行左右并)
  • 适合所有盒模型属性

行级盒子

  • Inline Level Box
  • 和其他行级盒子一起放在一行或拆开成多行
  • 某些盒模型属性 不适用,如 width 、height,行级中的高度、宽度是由内容决定的

image.png

块级元素和行级元素属于 HTML。

display 属性

image.png

  • block —— 将任意的元素转化为块级元素
  • inline —— 将任意的元素转化为行级元素
  • inline-block —— 作为 inline,可以与其他行级元素同行;作为 block,可设宽高,但只能在一行上,如一个图片只能够占据一行,而不会被拆成多行

常规流规则

image.png

行级排版上下文 IFC

image.png

<div>
  This is a paragraph of text with long word Honorificabilitudinitatibus. Here is an image
  <img src="https://assets.codepen.io/59477/cat.png" alt="cat">
  And <em>Inline Block</em>
</div>

<style>
  div {
    width: 10em;
    //overflow-wrap: break-word;
    background: #411;
  }

  em {
    display: inline-block;
    width: 3em;
    background: #33c;
  }
</style>

image.png

上述代码,<div> 本身是一个块级元素,但集中内容是 都是行级元素 ,因此 <div> 创建了一个行级盒子以及行级排版上下文。

在此盒子中,遵循文字从左到右排列,排不下了就换行。由于 Honorificabilitudinitatibus 是一个整体,不会被拆分,就会超出 <div> 设置的宽度。但可以使用 overflow-wrap: break-word,当单词超出容器时,会被强制换行。

image.png

display: inline-block 属性让 <em> 成为一个整体,不会被分割成多行。若删去,如下图↓ ↓ ↓

image.png

块级排版上下文 BFC

image.png

BFC 排版规则

image.png

  • 如果不想让垂直的 margin 合并,可以将两个盒子放在两个不同的 BFC 中,例如给其中一个元素嵌套一个 <div>,并添加属性 display:flow-root 或者 overflow = hidden,创建一个BFC,此时两个 BFC 就不会将吹至方向的 margin 合并。

块级与行级的区别

<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>本身是一个行盒,但盒子内又有文字又有块盒,此时浏览器会产生一个匿名的块级盒子 (只能在 CSS 排版引擎中看到) 来包裹上图橙色的两段文字
  • 给上述 <span> 标签设置边框后,会发现第一段文字只有上、下、左边框,第二段文字只有上、下、右边框

Flex Box

相比于前两种,更加的灵活,使用更频繁。

image.png

<div class="container">
  <div class="a">A</div>
  <div class="b">B</div>
  <div class="c">C</div>
</div>
<style>
  .container {
    display: flex;
    border: 2px solid #966;
  }

  .a, .b, .c {
    text-align: center;
    padding: 1em;
  }

  .a {
    background: #fcc;
  }

  .b {
    background: #cfc;
  }

  .c {
    background: #ccf;
  }
</style>

image.png

首先先给整个 container 设置一个 display: flex 属性,使得之后的子盒都使用 flex 的属性上下文规则排布。

flex-deraction

规定排列方式。 默认从左到右排列

image.png

主轴 与 侧轴

由于排列方向不能简单地用水平与垂直概括,于是引入 主轴侧轴 两个概念。

主轴方向 为这几个元素的流向,与主轴流向 垂直 的方向为 侧轴方向image.png

在主轴上的对齐方式 justify-content

默认值为 flex-startimage.png

  • flex-start —— 向前对齐
  • flex-end —— 向后对齐
  • center —— 中间对齐
  • space-between —— 整行分散,中间平均的加空格,两头没空格
  • space-around —— 整行分散,两头也有空格,但 两头空格小,中间空格大
  • space-evenly —— 整行分散,两头也有空格,且 两头空格与中间空格大小相等
在侧轴上的对齐方式 align-items

默认值为 stretchimage.png

  • stretch —— 将容器内元素高度撑到与容器一样高
  • baseline —— 基线对齐,容器内所有子元素
在侧轴上某个元素的对齐 align-self

image.png

按序对齐方式 order

给元素设置不同的数字 ,然后按着数字大小 从小到大 排序。可以设置负数

image.png

弹性 Flexibility

可以把 Flex 上下文中的所有子元素,理解为是有弹性的一些元素,类似于弹簧,可以压缩也可以拉伸。

image.png

  • 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 整个容器减去原先没拉伸时的大小(即300px),剩下的容器空间按照 2 :1 ,分配给 A 和 B。因此,并非是指 A :B 是 2 :1。

  • 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>

image.png 上述代码中,A 设置了 flex-shrink: 0 ,即代表了此时 A 元素已是刚性的了,不能再压缩了,而整个容器无法含下三个元素共1200px,因此 A 不进行压缩,而 B、C根据剩下的容器空间一分为二

  • flex-basis

    其属性值为不拉伸、不收缩时的大小,若不设置,则默认为设置的 width大小,因此一般不设置 flex-basis

Flex 属性集合

Flex 代表了许多Flex Box中属性的集合。

image.png

Grid 布局

由于页面的布局,并非是简单的一个方向的流式布局,有些是二维的布局方式,因此引入 Grid 布局。

image.png

Grid 布局同样通过 display 属性设置,即 display :grid

image.png

image.png

image.png

划分网络 gird-template

grid-template-columns :列宽

grid-template-rows :行宽

image.png

image.png

image.png

  • fr 为 fraction,一部分,即在列的部分,除去 A 的大小,剩下空间 B 占一份, C 占一份

  • grid line 网格线

image.png

  • grid area 网格区域

image.png

  • 划分不规则网格

grid-row-start :行的起始线

grid-column-start :列的起始线

grid-row-end :行的终止线

grid-column-end :列的终止线

image.png

可简化成以下形式 ↓ ↓ ↓

image.png

image.png

简化顺序按照上面介绍的来

Float 浮动

在有 gridflex 后,float的使用就把比较少,现在基本上用于形成文字包围图片的效果。

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

<style>
  img {
    float: left;
  }

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

image.png

position 绝对定位

image.png

static

静态的,参与流里面的布局,即一些基本的常规流中的布局

relative

由于原先空间依旧被占有,因此对其它元素没有影响

image.png

absolute

整个容器不会预留原先的空间,其他元素当作它不存在进行排版 image.png

<h1>页面标题</h1>
<div class="container">
  <div class="box"></div>
  <p>段落内容段落内容 1</p>
  <p>段落内容段落内容 2</p>
  <p>段落内容段落内容 3</p>
  <p>段落内容段落内容 4</p>
</div>

<style>
  .container {
    background: lightblue;
  }

  .box {
    position: absolute;
    top: 0;
    left: 0;
    width: 100px;
    height: 100px;
    background: red;
  }
</style>

image.png

上述代码由于 container<body><html> 都是 static 的定位(未设置即默认 static),因此 box 找不到 非 static 的祖先,于是便根据页面的边缘进行定位。

fixed

类似于 absolute,也是 脱离了常规的文档流,在布局时针对 窗口 进行定位。

<nav>
  <a href="#">首页</a>
  <a href="#">导航1</a>
  <a href="#">导航2</a>
</nav>
<main>
  <section>1</section>
  <section>2</section>
  <section>3</section>
  <section>4</section>
  <section>5</section>
</main>
<a href="#" class="go-top">返回顶部</a>

<style>
  nav {
    position: fixed;
    line-height: 3;
    background: rgba(0, 0, 0, 0.3);
    width: 100%;
  }
  
  .go-top {
    position: fixed;
    right: 1em;
    bottom: 1em;
    color: #fff;
  }

  nav a {
    padding: 0 1em;
    color: rgba(255, 255, 255, 0.7);
  }

  nav a:hover {
    color: #fff;
  }

  body {
    margin: 0;
    font-size: 14px;
  }

  a {
    color: #fff;
    text-decoration: none;
  }

  section {
    height: 100vh;
    color: #fff;
    text-align: center;
    font-size: 5em;
    line-height: 100vh;
  }

  section:nth-child(1) {
    background: #F44336;
  }

  section:nth-child(2) {
    background: #3F51B5;
  }

  section:nth-child(3) {
    background: #FFC107;
  }

  section:nth-child(4) {
    background: #607D8B;
  }

  section:nth-child(5) {
    background: #4CAF50;
  }
</style>

image.png

上述代码尽管页面在滚动时,其导航栏 <nav> 和 返回顶部 go-top相对页面是固定的。

sticky

当页面滚动时,设置为 sticky 的元素到达指定位置后便不会再随着页面滚动。

position : sticky;
top : 20px;

image.png

image.png

详情见 ⇨ position - CSS(层叠样式表) | MDN (mozilla.org)

学习CSS的几点建议

image.png