CSS概述 | 青训营笔记

108 阅读5分钟

简要发展史

在HTML出现后提出,CSS全称 Cascading Style Sheet 意为层叠样式表。

  • CSS1:1996年发布,解决网页排版布局和装饰问题
  • CSS2:1998年发布,CSS做表现,HTML负责内容
  • CSS2.1:对CSS2的扩展和修正,在CSS3出现之前的规范
  • CSS3:规范模块化发展,性能和可维护性均有所提升。(有些模块已经发展至4或5,但处于习惯仍称CSS3为规范)

基础知识

层叠(Cascading)、优先级

层叠三大规则(序号越大优先程度越低):

  1. 样式表来源

    1. 用户代理样式表中的 !important

    2. 用户样式表中的 !important

    3. 作者样式表中的 !important

    4. 作者样式表(开发者写的.css文件)

    5. 用户样式表(由浏览器的用户提供,如浏览器提供的扩展浏览器默认样式表的选项供用户选择扩展样式表)

1.  用户代理样式表(浏览器默认样式)
  1. 选择器优先级(越具体的优先级越高)

    • 内联 > id > class=attribute=pseudo-class > type=pseudo-element
    • !important > 内联样式 > id选择器 > 类选择器 > 元素选择器
    • 通用选择器(*)、组合符(+>~、空格)和调整优先级的选择器(:where())不会影响优先级。
    • 否定(:not())和任意匹配(:is())伪类本身对优先级没有影响,但它们的参数则会带来影响。参数中,对优先级算法有贡献的参数的优先级的最大值将作为该伪类选择器的优先级。
    • 越具体的选择器优先级越高。

    优先级计算:由三个不同的值(或分量)相加,可以认为是百(ID)十(类)个(元素)——三位数的三个位数:

    • ID:选择器中包含 ID 选择器则百位得一分。
    • 类:选择器中包含类选择器属性选择器或者伪类则十位得一分。
    • 元素:选择器中包含元素伪元素选择器则个位得一分。
  2. 源码位置

    • 同级别的样式,声明在样式表后面的样式将覆盖声明在前面的样式。

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

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

      <head>
      	<style>
      		.red{
      			color: red;
      		}
      	</style>
      	<link rel="stylesheet" href="./index.css" type="text/css">
      </head>
      <body>
      	<h1 class="green blue red">A Tittle</h1>
      </body>
      
      /* ./index.css */
      .blue{
      	color: blue;
      }
      
      .green{
      	color: green;
      }
      

      最终,h1中的文本颜色为green。因为在document中link引入的样式表在后,而在外联样式表中green类在后面声明,会覆盖blue中的声明。

选择器类别:

多个类被应用于一个元素时,可以不加空格的将所有类连在一起。

  • :root 是CSS中级别最高的选择器。

  • 基础选择器

    • #id:ID选择器
    • tagName:类型选择器
    • .class:类选择器
    • *:通用选择器
  • 组合选择器

    • 后代(包含)选择器:空格
    • 子组合器>:匹配是其他元素的直接后代的目标元素。选择直接子元素,继承关系中更远的后代不匹配。eg..parent>.child{}
    • 相邻兄弟组合器+:匹配紧跟在其他元素后的目标元素。eg.h1 + p{} 紧随h1的同级p元素
    • 通用兄弟组合器~:选择所有在指定元素之后的兄弟元素,即使不邻接。
    • 复合选择器:多个基础选择器可以连起来使用,h1.page
  • 属性选择器:通过约束属性值选择元素

    /*包含某一属性的元素*/
    a[title]{}
    /*包含某一属性且值为指定值的元素 `i`表示匹配时不区分大小写*/a[href="value" i]{}
    a[attr~="value"]{}  /*匹配至少一个值,值通过空格分隔*/
    a[attr|="value"]{}  /*匹配值,或以value-开头的值*/
    /*子字符串匹配选择器*/
    [attr^=value]  开头
    [attr$=value]  结尾
    [attr*=value]  任意位置出现
    
  • 伪类选择器: :用于选择处于特定状态或相对于其父级或兄弟元素的位置的元素。

    a:hover { }
    :first-child  第一个子元素
    :last-child
    :only-child(没有兄弟元素)
    :invalid
    :nth-child(an+b)
    :nth-of-type(an+b)
    /*用户行为伪类*/:hover、:focus ……
    
  • 伪元素选择器:: :匹配在文档中没有直接对应HTML的特定部分或插入内容。选择的是一个元素的某个部分而不是元素自己。

    .container::after {  
    	content: "";  /*生成内容*/ 
    	width: 860px;
    }
    ::before
    ::first-line 第一行
    
  • 逻辑选择器:较新的选择器

    • :is():选择列表中任意一个选择器可以选择的元素。不能用 :is() 来选取 ::before 和 ::after 两个伪元素
    • :where():选择所有能被该选择器列表中任何一条规则选中的元素。类似:is(),区别在于:where()的优先级总是为0。
    • :has():选择一个元素,其给定的选择器参数至少匹配一个元素。可以用于选择父元素。
    • :not():用来匹配不符合一组选择器的元素。它的作用是防止特定的元素被选中。

❗Tips:

  • 选择器尽量少用id(不便于复用和样式覆盖,并且解析成本高)
  • 尽量不使用 !important (增加调试难度、降低样式灵活性)
  • 自己的样式加载在引用库样式的后面(可覆盖库样式)

继承

  • 大部分具有继承特性的属性根文本有关:color、font、font-family、line-height、text-align、white-space、word-spacing……
  • 可使用inherit关键字显式指定一个属性值从其父元素继承

控制继承的通用属性值

  • inherit:设置该属性会使子元素属性和父元素相同,开启继承
  • initial:将应用于选定元素的属性值设置为该属性的初始值
  • revert :将应用于选定元素的属性值重置为浏览器的默认样式,而不是应用于该属性的默认值。在许多情况下,此值的作用类似于 unset。
  • revert-layer :将应用于选定元素的属性值重置为在上一个层叠层中建立的值。
  • unset:将属性重置为自然值,也就是如果属性是自然继承那么就是 inherit,否则和 initial 一样。

图片.png

在这个例子中,最终第一个h1的字体大小为28px,第二个h1的字体大小因为样式优先级较高,继承为24px。

CSS的值和单位

图片.png

值:

  • 文字类:颜色、位置、关键字等
  • 数值类:数字、但又单位的数值、百分比等
  • 函数生成:calc()min()max()

单位:

  • 长度

    • 绝对长度

      图片.png

    • 相对长度

    图片.png

    • %:一般指相对于父元素大小。如果将元素的字体大小设置为百分比,那么它将是元素父元素字体大小的百分比。如果使用百分比作为宽度值,那么它将是父值宽度的百分比。

      使用百分比作为元素外边距(margin)或填充(padding)的单位时,值是以包含块的内联尺寸进行计算的,也就是元素的水平宽度

    • fr:仅在table布局下可用,代表网格容器中可用空间的一份。

    • em:相对于元素的字体大小来计算

      • 1em = 1 font-size
      • 会根据字体大小的改变而改变
    • rem:相对于根元素的字体大小来计算

  • 时间:s,ms

  • 角度:deg、grad、rad、turn

  • 分辨率:dpi、dpcm、dppx

盒模型

浏览器根据视觉格式化模型将所有元素表示为盒子模型,css通过盒模型做layout。

图片.png

盒模型指:围绕元素 内容 添加任何内边距、边界和外边距来布置单个元素盒子。

外边距(margin)+ border(边框) + 内边距(padding不能为负)+ content(内容)

👉 box-sizing的两种属性值:

  • border-box怪异盒模型。边框盒子,设置长宽包含 paddingcontentborder 在内总共的长宽。
  • content-box标准盒模型(默认)。内容盒子,设置的长宽为内容区域

实现三角形 border

// html
<div class="triangle-bottom"></div>
//css
.triangle-bottom {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid red;
}

实现固定比例矩形

使用百分比或新特性aspect-ratio

实现水平居中

margin:10px auto;

实现渐变框

// html
<div class=" awesome-border"></div>

// css
.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);
}

padding、border、margin中,只有margin可以设置负值。margin负值最终减少的是外界可感知的该元素的高度。

图片.png

布局和定位

CSS3之前常用的布局:

  • 常规流

    常规布局流(normal flow)是指在不对页面进行任何布局控制时,浏览器默认的 HTML 布局方式。有块级格式上下文(BFC)和内联格式上下文(IFC)

  • 浮动流

    float属性控制,浮动元素会脱离文档流,做横向布局。

  • 定位流

    position属性控制,当设置值为fixedabsolute时,元素会脱离文档流。

CSS3之后新增的布局:

  • Flex 弹性盒子布局:一维布局
  • Grid 网格布局:二维布局
  • Multicol 多列布局

常规流布局

在默认的横板书写模式中,块级元素默认从上至下堆叠排列(默认是占满一行的),内联元素从左到右从上至下排列。

任意盒子的display分为:

  • 外部显示类型(display-outside):规定盒子如何与同一格式上下文中的其他元素一起显示。
  • 内部显示类型(display-inside):规定盒子内部的布局方式

比如:display:flex,其外部显示是block,参与BFC;display:inline-flex,则外部显示是inline,参与IFC。他们内部的盒子参与弹性盒布局。

图片.png

块级格式上下文 BFC

格式化上下文的布局规范为:

图片.png

包含块:

  • 正常情况下,包含块就是离当前元素最近的祖先块元素
  • 绝对定位的包含块:是离它最近的开启了定位的祖先元素。若所有都没开启定位,则是根元素html。

BFC(block formatting context)是什么?

块级格式上下文 BFC本身是一种格式规范。当说一个盒子是BFC或有BFC特性,此时它表示的是block formatting context root 。其内部显示类型是flow-root,盒子内部形成了一个新的块级格式化上下文,是一块独立渲染的区域,内部元素不会影响外部的元素

BFC的特性:

  • BFC不会被浮动元素所覆盖。
  • 父元素开启BFC后,子元素和父元素的外边距不会重叠
  • 开启BFC的元素可以包含浮动的子元素

BFC开启方式(满足一条即可):

  • display: flow-root | inline-block;
  • position: absolute | fixed;
  • float: 不为none;
  • overflow: 不为visible

外边距塌陷出现的情况:

图片.png

  • 两个兄弟元素之间相邻的上下外边距
  • 父子元素之间相邻的上下外边距
  • 内容为空的元素自己上下外边距相邻

消除外边距塌陷的方法:

图片.png

  • 在两个相邻的上下边距之间增加border、padding或者内联元素,使它们不相邻;
  • 在父子元素重叠时,除了上述方法还可以将父元素设为BFC,使得父子不在同级BFC中。

高度塌陷

浮动布局中,父元素的高度默认是被子元素撑开的,当子元素浮动后,其会从文档流中脱离,将无法撑起父元素的高度,导致父元素的高度丢失,其下的元素会上移,导致页面布局混乱。也可以通过设置父元素为BFC来解决。

内联格式上下文 IFC

图片.png

IFC是规定内部内联元素摆放规则的一个独立的环境。

  • 在一个行内格式化上下文中,盒是一个接一个水平放置
  • 盒之间的水平margin,border和padding都有效
  • 盒可能以不同的方式竖直对齐:以它们的底部或者顶部对齐,或者以它们里面的文本的基线对齐
  • 行内块级元素之间默认留有间隙
  • 矩形区域包含着来自一行的盒子叫做line box,line box的宽度由浮动情况和它的包含块决定,高度由line-height的计算结果决定。

图片.png

内联元素的高度分为两类:content area区域的高度,line-height。参与line box计算的时line-height。

line-height - content area的高度 = leading,leading会被均分为两部分

❓单行文字居中:

利用line-height的垂直居中特性。

// html
<div class="title">我是标题</div>
// CSS
.title {
background: antiquewhite;
font-size: 18px;
**line-height: 36px;**
height: 36px; // 可以省略
}

❓文字和icon垂直对齐:

利用了line box中计算高度的原理和vertical-align的设置,垂直对齐,但不是完全垂直居中。

如果设置父元素font-size:0,基线和中线重叠,则居中对齐。

//html
<div class="wrap">
<img class="image" src="dy.png">
<span class="text">抖音同款能力</span>
</div>
// CSS
.image {
width: 24px;
height: 24px;
**vertical-align: middle;**
}
.text {
font-size: 16px;
**line-height: 32px;**
margin-left: 4px;
**vertical-align: middle;**
}

弹性盒子布局

在即便是宽高未知的情况下,也能排列和分割一个盒子内部的布局。而且在不同布局方向(横向/纵向) 的调整更为灵活。

图片.png

  • 主轴(main axis)是沿着 flex 元素放置的方向延伸的轴(比如页面上的横向的行、纵向的列)。该轴的开始和结束被称为 main startmain end
  • 交叉轴(cross axis)是垂直于 flex 元素放置方向的轴。该轴的开始和结束被称为 cross startcross end
  • 设置了 display: flex 的父元素被称之为 flex 容器(flex container)。
  • 在 flex 容器中表现为弹性的盒子的元素被称之为 flex 项flex item)。

在父元素使用的属性:

  • display:flex | inline-flex

  • flex-direction:指定主轴方向。值可为:row(default)、row-reversecolumncolumn-reverse

  • 🔥 flex-wrap:决定flex项的换行。规定flex容器是单行或者多行,同时cross轴的方向决定了新行堆叠的方向。wrap

  • flex-flow

     flex-direction: row;
     flex-wrap: wrap;
     /*可替换为:*/
     flex-flow: row wrap;
    
  • 🔥 justify-content :沿main轴方向的位置。

    • flex-start:使所有flex项位于主轴起始处。
    • flex-end:让flex项到结尾处。
    • center:让 flex 项在主轴居中。
    • space-around:使所有 flex 项沿着主轴均匀地分布,在任意一端都会留有一点空间。
    • space-between:使所有 flex 项沿着主轴均匀地分布,不会在两端留下任何空间。
  • 🔥 align-items:控制子项在cross轴上的位置。

    • stretch:使所有 flex 项沿着交叉轴的方向拉伸以填充父容器。如果父容器在交叉轴方向上没有固定宽度(即高度),则所有 flex 项将变得与最长的 flex 项一样长(即高度保持一致)。
    • center:保持其原有的高度,在cross轴居中。
    • flex-startflex-end :使 flex 项在交叉轴的开始或结束处对齐所有的值。
  • gaprow-gapcolumn-gap:设置行和列之间的间隙

在子元素中使用的属性:

  • flex:控制flex 项的动态尺寸,在子元素中声明。其值为数字时代表每个元素占用的比例,为带单位的值时代表指定flex的最小值。

     flex: 1 200px;
    

    flex是可以指定最多三个不同值的缩写属性:

    • flex-grow:第一个无单位比例。有剩余空间时,对item的分配比例。
    • flex-shrink:第二个无单位比例,一般用于溢出容器的 flex 项。空间不足时,对item的压缩比例
    • flex-basis:第三个最小值,item未缩放之前的默认大小
  • order:规定item沿主轴显示的顺序。flex项排序,可以改变 flex 项的布局位置的功能,而不会影响到源顺序(即 dom 树里元素的顺序)。

    • 所有项的默认 order值为0
    • order值大的项比order值小的在显示顺序中更靠后。(大项靠后
    • 相同的order值按源顺序显示。
    • order值也可以为负。
  • align-self: auto | center | flex-start |…:单个item在交叉轴上的位置。

网格布局

Grid 布局则被设计用于同时两个维度上把元素按行和列排列整齐。网格是由一系列水平及垂直的线构成的一种布局模式,设计一系列具有固定位置以及宽度的元素的页面,使网站页面更加统一。

一个网格通常具有许多的列(column)行(row) ,以及行与行、列与列之间的间隙,这个间隙一般被称为沟槽(gutter)

图片.png

display: grid; 👈【直接子项】会变为网格项

grid-template-columns: 1fr 1fr 1fr;  也可用: repeat(3, 1fr);
grid-template-rows: 100px 100px;
grid-gap: 10px;
gap: 10px;

图片.png

无需再在子元素上指定任何规则,它们会自动地排列到创建的格子当中。(2*3的格子)

在父元素中使用的属性:

  • display: grid | inline-grid

  • grid-template-columns:指定格子的列数。

  • grid-template-rows:指定格子的行高和行数。

  • grid-gap:指定格子间的间距。间隙距离可以用任何长度单位包括百分比来表示,但不能使用fr单位。

    • grid-column-gap:列间隙
    • grid-row-gap:行间隙
  • repeat()函数:可用于自动多列填充。使用auto-fill代替确切的重复次数。

     grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    
  • grid-template-areas:用于放置元素,需要命名一些元素并在属性中使用这些名字作为一个区域。

    • 所有名字只能出现在一个连续的区域,不能在不同的位置出现
    • 一个连续的区域必须是一个矩形
    • 使用 . 符号,让一个格子留空
     .container {
       display: grid;
       grid-template-areas:👈
         "header header"
         "sidebar content"
         "footer footer";
       grid-template-columns: 1fr 3fr;
       gap: 20px;
     }
     
     header {
       grid-area: header;👈
     }
     
     article {
       grid-area: content;
     }
     
     aside {
       grid-area: sidebar;
     }
     
     footer {
       grid-area: footer;
     }
    
  • grid-auto-flow:规定默认的排序方向。

  • ……

在子元素中使用的属性:

  • grid-columngrid-row:用来指定每一个子元素应该从哪一行/列开始,并在哪一行/列结束。基于线的元素放置

    • grid-column-start
    • grid-column-end
    • grid-row-start
    • grid-row-end
     .box1 {
         grid-column: 2 / 4;
         grid-row: 1;
     }
    
  • grid-area:规定占用的area。

图片.png

定位 position

图片.png

相对定位 relative

特点:

  • 元素开启相对定位后,不设置偏移量的话,元素不会发生任何变化
  • 相对定位是参照于元素在文档流中位置进行定位的
  • 相对定位会提升元素的层级
  • 相对定位不会使元素脱离文档流
  • 相对定位不会改变元素的性质,块还是块,行内还是行内

偏移量:

开启定位以后,通过设置偏移量来设置元素的位置。

  • 垂直方向:通常只使用一种

    • top:定位元素和定位位置上边的距离
    • bottom:定位元素和定位位置下边的距离
  • left:定位元素和定位位置左边的距离

  • right:定位元素和定位位置右边的距离

绝对定位 absolute

特点:

  • 开启绝对定位后,如果不设置偏移量,元素的位置不会发生变化
  • 开启绝对定位后,元素会从文档流中脱离(影响布局)
  • 开启绝对定位后,会改变元素的性质,行内变成块,块的宽高被内容撑开
  • 绝对定位会使元素提升一个层级
  • 绝对定位元素是相对于其包含块进行定位的。

包含块:

  • 正常情况下,包含块就是离当前元素最近的祖先块元素
  • 绝对定位的包含块:包含块就是离它最近的开启了定位的祖先元素。若所有都没开启定位,则是根元素html。

固定定位 fixed

也是一种绝对定位。因此,元素也会脱离文档流。

与绝对定位不同的是,固定定位永远参照于浏览器的视口进行定位。

固定定位的元素不会随网页滚动。

粘滞定位 sticky

粘滞定位和相对定位的特点基本一致,不同的是元素相对于它的**最近滚动祖先(overflow是scroll/hidden/auto)**的视口进行定位,当元素到达某个位置时,将其位置固定。不会脱离文档流

层叠上下文(The stacking context)

层叠上下文是对HTML元素的三位构想,将元素沿着垂直屏幕的虚构的Z轴排开。

一个新的层叠上下文渲染时会对应一个浏览器渲染时的render layer(渲染层,不是使用开发者工具看到的图层)。

形成新的层叠上下文的条件:

  • position: relative或absolute; 并且z-index不是auto CSS3之前
  • position: fixed或sticky
  • flex 或grid的子元素;并且z-index不是auto

(CSS3之前)

  • opacity 的值小于1
  • transform 的值不为none
  • will-change的值不为 通用值
  • ……

层叠顺序

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

图片.png

图片.png

  • z-index只在同一个层叠上下文内比较
  • 子元素的z-index无法超越父元素z-index的显示顺序

图片.png

z-index的编写建议:

  • 使用css变量 或者 预处理语言的变量,管理z-index的值
  • 将预设间隔设置成10或100,方便后续的插入

变形、过渡、动画

变形(transform

❗通过CSS来改变元素的形状或位置。变形不会影响到页面布局。每个元素只有一个transform。

2D相关属性:

  • transform:translate(移动)、rotate、scale、matrix(变形矩阵)等
  • transform-origin:right top、center等,变形时依据的原点。

3D相关属性:

  • transform:translate3d、rotate3d、scale3d、matrix3d等

  • transform-origin:right top、50px 30px等

  • transform-style:flat、preserve-3d

  • perspective:观看点距离z=0这个平面的距离

  • perspective-origin:观看者的位置,如top、bottom等

  • backface-visibility:元素背面是否可见

  • 平移

    平移元素,百分比是相对于自身计算的。

transform: translate(0);
transform: translate(42px, 18px);
// 百分比值由变换框属性【相对于自身】的宽高决定
transform: translate(50%, 50%);
transform: translateX(50%);
transform: translateY(20px);
transform: translateZ(10px);
  • Z轴平移:正常情况下,就是调整元素和人眼间的距离(近大远小)。默认情况下网页不支持透视,需要指定视距perspective
// 设置视距:人眼距网页的距离。
html {
	perspective: 800px;
}

.box {
	transform: translateZ(10px);
}
  • 旋转
// 使元素绕着x、y、z轴旋转一定的角度
rotateX(45deg)
rotateY(1turn);   // 一圈
rotateZ()
// 是否显示元素背面
backface-visibility: hidden;

过渡 transition

通过过渡可以指定一个属性发生变化时的切换方式。

transition: all 2s;
transition: height 2s;
// 拆解开有
1.指定执行过渡的属性,大部分属性都支持过渡效果(值可以计算的)
transition-property: width,height;
2.指定过渡效果持续时间s,ms
transition-duration: 2s;
3.指定过渡的时序函数 
	ease:慢速开始,先加速,再减速
	linear:匀速
	ease-in:加速运动
	ease-out:减速运动
	ease-in-out:先加速,后减速
	cubic-bezier():指定时序函数
	steps(n[, end/start]):分步执行,在时间开始或结束时执行
transition-timing-function: ease;
4.指定等待时间
transition-delay: 2s;

动画 animation

动画可以自动触发,而transition需要有属性变化才能触发。动画需要设置关键帧。

// 对当前元素生效的关键帧的名字
animation-name: keyframe-name;

// 动画持续时间
animation-duration: 2s;
animation-timing-function: ease;

指定等待时间
animation-delay: 2s;

动画执行的次数
animation-iteration-count: 10/infinite;

动画方向
	normal:从fromto,每次都一样
	reverse:从tofrom,每次都这样
	alternate:从fromto,重复执行时反向
	alternate-reverse:从tofrom,重复执行时反向
animation-direction: alternate;

设置动画的执行状态
	running 执行(默认)
	paused 暂停
animation-play-state: running;

动画的填充模式
	none 执行完毕,元素回到原位
	forwards 执行完毕,元素停在动画结束的位置
	backwards 动画延时等待时,元素就会处于开始from位置
	both 结合两种,开始就在from,结束后不回到原位
animation-fill-mode:none;

关键帧 @keyframe

@keyframe name {
	// 动画开始的位置 也可以使用 0%
	from{
		margin-left: 0;
	}
	// 动画结束的位置 也可以使用 100%
	to{
		margin-left: 100px;
	}
}

性能相关

浏览器渲染的三个阶段:

图片.png

提高动画性能的方法:

  • 尽量不使用触发reflow(回流)的属性(布局变化需要重新计算)
  • 在遇到性能问题时可以触发硬件加速,如设置will-change属性、transform3d等
  • 尽量使用transform和opacity去写动画

响应式设计

响应式设计原则:

  • 优先选用流式布局,如百分比、flex、 grid等
  • 使用响应式图片,匹配尺寸,节省带宽
  • 使用媒体查询为不同的设备类型做适配
  • 给移动端设备设置简单、统一的视口
  • 使用相对长度,em、rem、ww 做为长度度量

媒体查询

媒体查询允许某些样式只在页面满足特定条件时才生效。可以将媒体类型(screen、print)以及媒体特性(视口宽度、屏幕比例、设备方向)作为约束条件。

引入媒体查询和更改布局的点称为断点 (breakpoints)。

@media: The @media at-rule, also known as a media query, is used to conditionally apply CSS. Media queries are commonly used to apply CSS based on the viewport width using the max-width and min-width properties.

 @media media-type and (media-feature-rule) {
   .card {
     padding: 2rem;
   }
 }
 @media (min-width: 500px) and (max-width: 1000px){
 }
  • 媒体类型 **media-type可选**:

    • all
    • print
    • screen
    • speech
  • 媒体特征规则 **media-feature-rule**

    • min-width:视口宽度大于某个大小应用CSS规则

    • max-width:视口宽度小于某个大小应用CSS规则

    • width:视口宽度等于某个大小应用CSS规则

    • orientation:设备处于竖放(portrait mode)和横放(landscape mode)模式

       @media (orientation: landscape) {
           body {
               color: rebeccapurple;
           }
       }
      
    • hover:用户是否能在一个元素上悬浮,使用某种指点设备。

    • pointer:可取三个值:nonefinecoarse

      • fine指针是类似于鼠标或者触控板的东西,它让用户可以精确指向一片小区域。
      • coarse指针是你在触摸屏上的手指。
      • none值意味着,用户没有指点设备,也许是他们正只使用键盘导航,或者是语音命令。
  • 媒体查询中的”与“逻辑:and

  • 媒体查询中的”或“逻辑:,

  • 媒体查询中的”非“逻辑:not

媒体查询使用的一些Tips:

  • 媒体查询同样遵循cascading层叠覆盖原则,min- 和max-选择一个
  • 由于设备的多样化逐渐不可枚举,断点的选择尽量根据内容选择
  • 由于断点的增加会增加样式处理的复杂度,所以尽量减少断点

设备像素、参考像素和移动设备视口

设备像素(物理像素)

显示器上绘制的最小单位,显示屏通过控制每个像素点的颜色,使屏幕显示出不同的图像。设备像素和设备相关,屏幕从工厂出来那天起,它上面的物理像素点就固定不变了。

DPI & PPI

dpi(dots per inch):每英寸多少点。

ppi(pixels per inch):每英寸多少像素数。

当用于描述显示器设备时ppi与dpi是同一个概念,说的是每英寸多少物理像素及显示器设备的点距。

图片.png

参考像素(CSS像素)

CSS像素是一个视角单位。1css像素是从一臂之遥看解析度为96DPI(即1英寸96点)的设备输出时,1点(1/96英寸)的视角。

图片.png

通常认为常人臂长为28英寸,那么视线与水平线的夹角是:

(1/96)in/ (28in* 2* PI/ 360deg) = 0.0213度

css像素存在的目的是为了保证阅读体验一致,所以对不同的物理设备, CSS使得浏览器中1css像素的大小在不同物理设备上看去大小总是差不多一个参考像素不等于一设备像素。真正实现时,为了方便基本都是根据设备像素换算的。浏览器根据硬件设备能够直接获取css像素。

DPR设备像素比

描述未缩放状态下,设备像素和css像素的初始比例关系。

DPR=设备像素css像素DPR=\frac{设备像素}{css像素}

移动端的viewport

布局视口(viewport)是页面中html元素(根元素)的包含块,默认情况下,window.document.documentElement.clientWidth 就是viewport的宽度。 在移动设备中,默认的布局视口由于历史兼容pc屏幕的原因,并不符合需求,经常需要用<meta>标签对viewport进行设定,来完成移动端设备的适配。

<meta>标签中的属性:

  • width
  • height
  • initial-scale
  • minimum-scale
  • maximum-scale
  • user-scalabe

图片.png

相对长度

  • em: 可以让展示区域根据展示字号的不同,做出放缩调整。

    • 非font-size属性中使用是相对于自身的字体大小
    • font-size上使用是相对于父元素的字体大小(一般不用,存在多重嵌套,产生混乱的问题)
  • rem:根元素的字体大小。不存在多重嵌套问题,可以进行适配放缩,用来做响应式布局。

图片.png

  • vwvh:视口宽度(高度)的1%,也是响应式布局的基准单位。

图片.png

CSS生态相关

语言增强 — CSS预处理器

图片.png

图片.png

图片.png

语言增强 — CSS后处理器

是一系列的plugin。

postcss机制:

图片.png

工程架构 — CSS模块化

是为了解决全局污染问题出现的解决方案,本质上是保证样式集合对应的选择器是唯一的。

单纯针对防止全局污染的方案:

图片.png

工程架构 — CSS-in-JS

css-in-js:将应用的CSS样式写在JavaScript文件里,利用js动态生成css。

  • inline-style(抛弃)
  • unique classname

styled-component 机制:

图片.png

优点:

  • 有效避免样式全局污染
  • 复杂交互样式可以更灵活的编写。
  • 首屏渲染无多余css阻塞

缺点:

  • 有一定的学习成本
  • 存在运行时的消耗
  • css-in-js的库导致打包体积增大
  • 代码的可读性降低

工程架构 — 原子化CSS

原子化CSS是一种CSS架构方式,倾向于小巧且用途单一的class,并以视觉效果进行命名。

Tailwind、Windicss、Tachyons unocss……

Tailwind的做法:

图片.png

优点:

  • 减少css体积
  • 原子类复用率高
  • 移动和删除节点变得容易
  • 减少classname的命名复杂度

缺点:

  • 增加html类名长度
  • 初始使用时有学习和记忆成本
  • 样式库的定义成本