理解css(一) | 字节青训营笔记

97 阅读13分钟

理解CSS

先在这里放一个网址,可以通过这个网址去查关于HTML、CSS、JS、HTTP的相关知识,知识准确度很高,而且很多都有中文版的,方便大家使用。

网址:developer.mozilla.org/zh-CN/ image.png

本文内容包含: image.png

1.为什么学习css

1996年苹果官网: image.png

2023年苹果官网: image.png

通过以上两张图能够发现,现在的页面具有以下特点:

  • 更丰富的交互行为和视觉效果
  • 能够承载和展现更多的信息量
  • 更精准的传递信息

2. css发展史

  • CSS 1 :始于1966年。
  • CSS 2 :诞生于1998年,添加定位,Z-index,media 属性。
  • CSS 2.1:诞生于2004~2011年,目前使用最广泛的版本(IE支持)
  • CSS 3:1999年开始起草,把CSS模块化,独立升级各功能。 image.png

3.基础知识

CSS:Cascading Style Sheet,层叠样式表。

3.1Cascading规则

cascading层叠规则: image.png 我们一般写的样式都归类在作者样式表,作者样式表根据书写位置又分为三类:行内式、内嵌式、外部链接式,这三类样式的优先级要根据选择器的优先级确定。

<!-- html代码 -->
<!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>
    </head>
    <style>
        #title {
            color: red;
        }
    </style>
    <link rel="stylesheet" href="./test.css" type="text/css">
    <body>
        <h1 id="title" style="color: green;">title title title</h1>
    </body>
</html>
复制代码
/* css样式 */
h1 {
    color: blue;
    font-size: 48px;
}
复制代码

image.png

3.2 选择器

内联样式(写在标签内部的)1000,id选择器100,类和伪类10,元素选择器1,通配选择器0.当选择器中包含多种选择器时,需要将各种选择器的优先级相加然后再比较,但是多个相同级的选择器相加的结果不会超过上一个级别的优先级。(选择越详细精确,权重越高,优先级越高)

image.png

image.png

对于@import的样式,根据@import的顺序

对于link和style标签的样式,根据在document中的顺序决定

基础选择器:

  • *{ }:通配符选择器。选择所有的元素
  • E{ }:元素选择器。其中 E 为任何一个元素,如html、body、p、div等。
  • .class{ }:类选择器。定义时为class="classname",class值可以有多个,用空格隔开。
  • #id{ }:id选择器。定义时为id="idname",相同 id 只能有一个。
  • s1, s2, s3...sn{ }:群组选择器。一次性选择 多个选择器 所对应的元素。
  • s1s2s3...sn{ }:交集选择器。如选择 class 值为 hello 的 div 元素:div.hello{ }

关系选择器:

  • E F{ }:后代选择器。选择 E 元素的一个或多个和 F 相同的后代元素。
  • E>F{ }:子选择器。选择 E 元素的子元素 F。
  • E+F{ }:相邻兄弟选择器。选择紧挨着 E 元素的后一个兄弟 F 元素,如果 F 元素不是 E 元素的后一个兄弟元素,则选择不成功。
  • E~F{ }:兄弟选择器。选择 E 元素后面的所有 F 兄弟元素。
  •   <div class="父元素">
          <span class="子元素 元素1"></span>
          <span class="子元素 元素2 元素1的兄弟元素"></span>
          <span class="子元素 元素3 元素1的兄弟元素"></span>
      </div>
    复制代码
    

特性选择器:

  • E[att]:选择具有 att 特性的 E 元素,不考虑特性的值。如选择具有class属性的div元素div[class]
  • E[att="val"]:选择具有 att 特性且特性值等于 val 的 E 元素。如选择具有class属性为且 class 值为 name 的 div 元素div[class="name"]
  • E[att~="val"]:选择具有 att 特性且特性值为 用空格分隔的单词,其中一个单词为 val 的 E 元素(如<p class="my val">xdy</p>
  • E[att|="val"]:选择具有 att 特性且特性值为 用连接符分隔的字符串,并以 val 开头的 E 元素(如<h1 lang="en">hello<h1>或者<p lang="en-us">hello</p>都能被*[lang|="en"]选择,即选择特性 lang 的值为“en”或以“en-”开头的元素)
  • E[att^="val"]:选择具有 att 特性且特性值 以 val 开头的 E 元素。
  • E[att$="val"]:选择具有 att 特性且特性值为 以 val 结尾的字符串的 E 元素。
  • E[att*="val"]:选择具体 att 特性且特性值为 包含 val 的字符串的 E 元素。
  • ......

伪元素选择器(用::符号。一般会创建一个新的元素。所以是 伪的):

  • E::first-letter:设置元素内容第一个字符的样式(仅作用于块元素,一般用于制作首字下沉的效果)
  • E::before:设置在元素显示前发生的内容(一般将它和CSS的content属性一起使用,且所添加的内容无法选中)
  • E::after:设置在元素显示后发生的内容(一般将它和CSS的content属性一起使用,同before,可解决高度塌陷问题)
  • ......

伪类选择器:(用:符号。表示选择处于某一种特殊状态的元素)

  • E:nth-child(n):(n 表示第 n 个元素,从 0 开始的)(even 表示偶数位置的元素)(odd 表示奇数位置的元素)选择父元素的第几个子元素且该元素为 E。-child是在所有子元素中找匹配的元素,而-of-type 是在同类型中找匹配的元素
  • E:not(F):用于剔除含 F 属性的元素。
  • ......

开发小提示:

选择器尽量少用 id;

尽量不要用 !important;

自己的样式加在引用库样式的后面。

隐藏福利~ 关注gong zhong hao【安酱xx】,输入【js高级学习笔记】获取3万多字的js高级笔记噢~,输入【html+css】获取html+css学习笔记(这个是早期记录的笔记,有点混乱~)

3.3 继承

image.png

3.4 值和单位

image.png

3.5 盒模型

image.png 外边距(margin): 可正可负可auto

  • 提供4个数据:(如margin:20px 20% 0.2em 20px;)将依次作用于上,右,下,左。(顺时针)
  • 提供3个数据:将依次作用于上,左右,下
  • 提供2个数据:将依次作用于上下,左右
  • 提供1个数据:将依次作用于上下左右

margin负值最终减少的是外界可感知的宽高。

image.png

不提倡使用负外边距,因为这会增加代码复杂度。

内边距(padding): 不可为负,其余同上。

由盒模型的特性能够实现一些展现形式: image.png

<!-- 三角形 -->
<div class="triangle-bottom"></div>

.triangle-bottom{
    width: 0;
    height: 0;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 50px solid red;
}
复制代码
<!-- 固定比例矩形,也可以使用新特性aspect-ratio:https://developer.mozilla.org/zh-CN/docs/Web/CSS/aspect-ratio -->
<div class="ratio-box"></div>

.ratio-box{
    /* 新特性写法 */
    /* aspect-ratio: 4 / 3;
    background-color: greenyellow; */
    
    background-color: cadetblue;
    width: 100%;
    height: 0;
    padding: 0;
    /* 是父元素宽度的75% */
    padding-bottom: 75%;
}
复制代码
<!-- 水平居中 -->
    <div class="wrap">
        <div class="h-center"></div>
    </div>
    
.wrap{
    width: 100%;
    height: 100%;
    border: 1px dashed grey;
}
.h-center{
    width: 100px;
    height: 50px;
    background-color: navajowhite;
    /* 使用auto将左右2侧的剩余空间均分 */
    margin: 10px auto;
}
复制代码
<!-- 渐变边框,这块有点疑问 -->
<div class="awesome-border"></div>

.awesome-border{
    width: 150px;
    height: 100px;
    border: 8px solid transparent;
    border-radius: 12px;
    background-clip: padding-box,border-box;
    background-origin: padding-box,border-box;
    background-image: linear-gradient(to right,#fff,#fff),linear-gradient(135deg,#e941ab,#a557ef);
}
复制代码

4. 布局和定位

image.png image.png

常规流中的任意盒子都只会参与一种格式化上下文。 image.png

4.1 BFC

image.png

外边距塌陷或外边距重叠问题: image.png

4.2 IFC

内联格式化上下文: image.png

实现单行元素居中对齐常用方式:

  • line-heightheight设置为相同的高度即可
  • 使用flex布局的align-items:center即可

4.3 flex布局

flex布局学习参考地址:www.ruanyifeng.com/blog/2015/0…

flex布局实例地址:www.ruanyifeng.com/blog/2015/0…

开启了 flex 布局的元素叫 flex container;flex container 里面的直接子元素flex item

flex item 的布局将受 flex container 属性的设置来进行控制和布局;flex item 不再严格区分块级元素和行内元素;flex item 默认情况下是包裹内容的,但是可以设置宽度和高度。

display: flex:flex container 以 block-level 形式存在,即块元素。

display: inline-flex:flex container 以 inline-level 形式存在,即行内元素。

flex 模型示意图:

1660569413024.png

flex-container 父元素属性

flex-direction:该属性决定主轴的方向,有 4 种取值:row(默认值)、row-reverse、column、column-reverse。

1660570251171.png

flex-wrap:决定元素单行显示还是多行显示。有 3 种取值:nowrap(默认值)、wrap(单行显示)、wrap-reverse(修改了交叉轴,即从下到上排列)。

如果一行显示不下,那么其宽度或者高度将会被压缩。也就是设置的宽度与其显示的真正宽度没有必然关系

flex-flow:是 flex-direction 和 flex-wrap 的简写属性。任何顺序,都是可省略的。

justify-content:该属性决定了 flex-item 在 main axis 上的对齐方式。 有以下常见可选值: 1660572086740.png

align-items:该属性决定了 flex-item 在 cross axis 上的对齐方式。 有以下常见可选值:

1660573608967.png

基准线是 flex-item 中的文本底部的水平线。

align-content:space-evenly 有兼容性问题。 在 flex container 设置高度后有剩余空间才可能会设置该属性,但是一般开发中都不会设置盒子的高度,而是由内容撑开。(多行)

1660616599539.png

flex-item 子元素属性

order:决定 flex-items 的显示顺序。(使用 css 来决定显示的顺序)

值为任意整数(正整数,负整数,0),默认值为 0;顺序按照值从小到大依次排。

align-self:单独设置某一个 flex-item 在 cross axis 上的排布方式。

有 6 种取值:auto(默认值)、stretch、flex-start、flex-end、center、baseline。

flex-grow:决定 了 flex items 如何扩展或拉伸或成长

值为任意非负数字(正整数、正小数,0),默认值为 0 。(设置小数有不一样的效果)

注意:当 flex container 在 main axis 上有剩余空间时,flex-grow 属性才会有效。 flex items 扩展后的最终 size 不能超过 max-width 或者 max-height 。

flex-shrink:决定了 flex items 如何缩小。 值为任意非负数字(正整数、正小数,0),默认值为 1

注意:当 flex items 在 main axis 方向上超过了 flex container 的 size ,flex-shrink 才会生效。 flex items 缩小后的最终 size 不能小于 min-width 或者 min-height

flex-basis:用来设置 flex items 在 mian axis 方向上的 base size(基本尺寸)。 值:auto(默认值),具体的宽度数值。

注意:如果设置了 flex-basis 之后,一个内容在设置的宽度中不能全部显示,则会被拉伸。最终显示的大小会被如下顺序因素影响(优先级从高到低):

  1. max-width、max-height、min-width、min-height。
  2. flex-basis
  3. width、height
  4. 内容本身的 size

flex:是 flex-grow 、flex-basis 和 flex-shrink 的缩写属性。 值:none | auto | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] (该语法可通过将鼠标悬浮在属性上进行查看) 1660621356412.png

浏览器可快捷查看各个属性的显示样式: image.png

查看属性的具体效果: image.png

4.4 grid布局

2017年推出的布局方式,可以定义由行和列组成二维布局,然后将元素放置到网格中。元素可以只占其中一个单元格,也可以占据多行或多列。

通过 grid-template-columns 和 grid-template-rows 属性来定义网格中的列和行。如现在创建了一个网格,包含了三个 200 像素宽的列轨道。子元素将在网格上每个网格单元中展开。

<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>
复制代码
.wrapper {
  display: grid;
  grid-template-columns: 200px 200px 200px;
}
复制代码

image.png

轨道可以使用任何长度单位进行定义。网格还引入了一个另外的长度单位来帮助我们创建灵活的网格轨道。新的fr单位代表网格容器中可用空间的一等份。

.wrapper {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
}
复制代码

image.png

grid-template-areas CSS 属性是网格区域 grid areas 在 CSS 中的特定命名。 image.png

学习更多建议查看以下 MDN 学习地址。

MDN 学习地址:developer.mozilla.org/zh-CN/docs/…

4.5 grid和flex布局的使用策略

使用建议: image.png

学习参考地址:developer.mozilla.org/zh-CN/docs/…

4.6 position定位

为了我们可以在文档流的基础上,让元素移动,做出更多灵活的改变。当position属性的取值非static的时候,可以使用top, right, bottom, left对其进行定位。 image.png

5. 层叠上下文

层叠上下文:The Stacking Context。是对HTML元素的三维构想,将元素沿着垂直屏幕的虚构的 Z 轴排开。 image.png

浏览器渲染部分过程示意图(英文):www.chromium.org/developers/…

5.1 形成条件

文档中的层叠上下文由满足以下任意一个条件的元素形成:

  • 文档根元素(<html>);

  • css3之前

    • position 值为 absolute(绝对定位)或 relative(相对定位)且 z-index 值不为 auto 的元素;
    • position 值为 fixed(固定定位)或 sticky(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持);
    • flex (flex) 容器的子元素,且 z-index 值不为 auto
    • grid (grid) 容器的子元素,且 z-index 值不为 auto
  • opacity 属性值小于 1 的元素(参见 the specification for opacity);

  • mix-blend-mode 属性值不为 normal 的元素;

  • 以下任意属性值不为 none 的元素:

  • isolation 属性值为 isolate 的元素;

  • will-change 值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素(参考这篇文章);

  • contain 属性值为 layoutpaint 或包含它们其中之一的合成值(比如 contain: strictcontain: content)的元素。

在层叠上下文中,子元素同样也按照上面解释的规则进行层叠。重要的是,其子级层叠上下文的 z-index 值只在父级中才有意义。子级层叠上下文被自动视为父级层叠上下文的一个独立单元。

总结:

  • 层叠上下文可以包含在其他层叠上下文中,并且一起创建一个层叠上下文的层级。
  • 每个层叠上下文都完全独立于它的兄弟元素:当处理层叠时只考虑子元素。
  • 每个层叠上下文都是自包含的:当一个元素的内容发生层叠后,该元素将被作为整体在父级层叠上下文中按顺序进行层叠。

层叠上下文介绍:developer.mozilla.org/zh-CN/docs/…

5.2 层叠顺序

层叠顺序不仅指不同的层叠上下文的顺序,同一个层叠上下文内,元素间也有顺序: image.png

z-index 只在同一个层叠上下文内比较

子元素的z-index无法超越父元素的z-index显示顺序 image.png

编写 z-index 的建议: image.png

6. 变形、过渡、动画

6.1 transform 变形

image.png

image.png

在线试一试: codepen.io/yao-mo/pen/…

6.2 transition 过渡

通过指定某些元素属性从一种起始状态,在-段时间内以某种变化节奏,过渡到终止状态。

语法:transition: <property> <duration> <timing-function> <delay> image.png

6.3 animation 动画

image.png

animation 属性参考:developer.mozilla.org/zh-CN/docs/…

css 动画样式参考:animate.style/

6.4 transform、transition、animation性能

image.png

重绘(repaint) :是指一个元素外观属性的变化触发浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。

回流(reflow) :当渲染树中的一部分(或全部)因为元素的规模尺寸、布局、隐藏等改变需要重新构建,这就是回流。每个页面至少需要一次回流,就是在页面第一次加载的时候。

重绘和回流的关系:在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程称为重绘。

所以,回流必定会引发重绘,但重绘不一定会引发回流

硬件加速详情:www.chromium.org/developers/…

动画性能相关深入了解:fed.taobao.org/blog/taofed…

注: 一位好同学写的文章,写的很棒参考记录一下。