本文参与青训营笔记创作活动
问题:我们为什么要学习CSS?
回答:使页面展示更丰富的信息,更精准的传递开发者想传递的信息。
CSS简要发展历史:
基础知识
层叠(Cascading)、优先级
如上图,多个样式作用于同一元素,那么此时哪条声明规则会生效呢,这就需要一系列声明规则来解决冲突
层叠三大规则(优先程度自上而下递减):
- 样式表来源
- 选择器优先级
内联
>id>class=attribute=pseudo-class>type=pseudo-element
3. 源码位置
谁离声明元素距离“近”谁权重高
由层叠引出的CSS代码规范:
- 选择器尽量少用id
- 尽量不用!important
- 自己的样式在加载在引用库样式之后
继承
值和单位
盒模型
- margin负值最终减少的是外界可感知的宽高
- 尽量不要高频使用margin,防止
布局坍塌
布局
概述
- 常规流布局中,所有盒子被分为
块级盒子和内联盒子 块级盒子一个独占一行,参与BFC;内联盒子不具有自身宽高,参与IFC- 每种盒子只能参与BFC或IFC的一种,
内联盒子不参与BFC的原因是该行自动生成一个默认盒子包裹,参与BFC,而其内部所有的内联盒子只参与互相之间的IFC
块级格式化上下文(block formating context)
块级格式化上下文(Block Formatting Context)是Web页面中的一种CSS渲染模式,它决定了元素如何布局和相互作用。
具体来说,当一个HTML元素形成了BFC时,它会创建一个独立的渲染区域,在这个区域内的元素布局不会影响到外部元素。这也就意味着,同一个BFC区域内的元素会按照一定的规则进行垂直方向的布局,而且它们之间的边距、浮动等属性也会受到特殊的处理。
除了根body生成的一个默认大BFC,我们还要额外触发BFC的化,常见的触发条件包括:
- 根元素
- 浮动元素(float属性不为none)
- 绝对定位元素(position为absolute或fixed)
- display属性值为inline-block、table-cell、table-caption、flex、inline-flex的元素
- overflow属性值不为visible的元素
在实际开发中,我们可以利用BFC的特性,来解决一些布局上的难题,如清除浮动、避免margin重叠等问题。同时,BFC还可以提高页面渲染的效率和性能。
外边距塌陷:
内联级格式化上下文(Inline Formatting Context)
内联级格式化上下文(Inline Formatting Context)是Web页面中的另一种CSS渲染模式,它定义了内联元素(inline-level boxes)如何排列和相互作用。
具体来说,当一个HTML元素形成了IFC时,它会创建一个独立的渲染区域,其中内联元素会按照一定的规则进行水平方向的布局,同时也会受到特殊的处理,例如可以通过vertical-align属性来控制它们在垂直方向上的对齐方式。
常见触发IFC的条件包括:
- 根元素
- display属性值为inline、inline-block、inline-table、inline-flex的元素
- 设置了text-align、vertical-align、line-height属性的元素
- 在块级元素中的文本内容
在实际开发中,我们可以利用IFC的特性,来解决一些布局上的问题,如水平居中、文本垂直居中等。同时,IFC还可以提高页面渲染的效率和性能。因此,在理解和应用BFC的基础上,深入理解IFC同样是很有必要的。
一些例子
Flex弹性盒子布局
flex是 flexible Box 的缩写,意思为 弹性布局,用来为盒状模型提供最大灵活性,任何一个容器都可以指定为flex布局
- 当我们为父盒子设为flex布局以后,子元素的float、clear和vertical-align属性将失效
- 采用flex布局的元素,称为flex容器(flex container),简称 容器。它的所有子元素自动成为容器成员,称为flex项目,简称 项目
- 子容器可以横向排列也可以纵向排列
总结flex布局原理: 通过给父盒子添加flex属性,来控制子盒子的位置和排列方式
-
Flex父元素常见属性 | 属性 | 属性值 | 介绍 | | -------------- | -------------- | ------------------------ | | flex-direction | row(默认) / row-reverse / column / column-reverse | 设置主轴方向:从左到右 / 相反 / 从上到下 / 相反| | justify-content | flex-start(默认) / flex-end / center / space-around / space-between | 设置主轴上的子元素排列方式:主轴为X从左到右 / 从右到左 / 居中对齐 / 平分剩余空间 / 两边盒子贴边,中间平分剩余空间 | | align-items | flex-start(默认) / flex-end / center / stretch | 设置侧轴上的子元素排列方式(单行):侧轴为Y从上到下 / 从下到上 / 垂直居中对齐 / 拉伸 | | align-content | flex-start(默认) / flex-end / center / space-around / space-between / stretch | 设置侧轴上的子元素排列方式(多行):默认值在侧轴的头部开始排列 / 尾部开始排列 / 侧轴中间显示 / 子项在侧轴平分剩余空间 / 子项在侧轴先分布在两头,再平分剩余空间 / 设置子项元素高度平分父元素高度| | flex-wrap | nowrap(默认)/ wrap | 设置子元素是否换行:换行 / 不换行 |
-
Flex子元素常见属性 | 属性 | 属性值 | 介绍 | | -------------- | -------------- | ------------------------ | | flex-basis | auto(默认) / 长度值 | 规定item未放缩之前的默认大小| | flex-grow | number(默认)| 规定有剩余空间时,对item的分配比例| | flex-shrink | number(默认)| 规定空间不够时,对item的压缩比例| | flex | number(默认)| 以上三项缩写,定义子项目分配剩余的空间,用flex来表示占多少份数| | align-self | auto(默认)/ flex-start / flex-end / center / baseline / stretch | 允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性| | order | number(默认) | 定义项目的排列顺序。数值越小,排列越靠前,默认为0|
布局实例
Grid网格布局
CSS Grid Layout是CSS的一项新特性,它可以帮助我们灵活、高效地构建网页布局。GRID布局简单来说就是基于行和列进行定位而构成自适应的二维网格。
以下是使用Grid布局实现网页布局的基本步骤:
- 在父容器中定义grid环境:通过给父元素设置display: grid属性,创建一个grid环境。
- 划分行与列:通过grid-template-rows、grid-template-columns属性划分出网格的行与列,并可设置其大小等信息。
- 定义子元素位置:通过grid-row、grid-column属性指定每个子元素要占据哪些行与列,或者使用grid-area属性直接为每个子元素指定代表区域。
- 调整子元素大小:通过使用grid-row-span、grid-column-span、grid-row-start、grid-row-end、grid-column-start、grid-column-end等属性,对子元素进行跨行或跨列操作、或者调整子元素的尺寸。
- 完善样式:对子元素进行样式调整,如添加背景色、边框等,使之更符合设计要求。
学习和使用CSS Grid布局可以优化网页排版布局,增强网页的美观度和交互性。同时,该技术也在不断完善和发展中,为Web开发提供更多的可能性。
示例 :
Grid和Flex的对比
定位
| 定位属性 | 作用描述 |
|---|---|
position: static | 默认值,元素在正常流中位置不受影响 |
position: relative | 相对定位,元素的位置相对于其正常位置进行偏移,但仍保持在正常流中 |
position: absolute | 绝对定位,元素的位置相对于最近的非static祖先元素确定,如果不存在,则相对于初始包含块。会从正常流中删除,并不保留原本位置的空白 |
position: fixed | 固定定位,元素的位置相对于viewport(浏览器窗口)进行偏移,不随滚动条滚动,会从正常流中删除,并不占据空间 |
position: sticky | 粘性定位,元素在跨越特定阈值前为相对定位,之后为固定定位 |
层叠上下文
概念
CSS层叠上下文(CSS Stacking Context)是CSS rendering的一个重要概念,它定义了元素如何根据z-index属性进行层次叠加。
具体来说,每个层叠上下文由一组HTML元素和它们的子元素构成,并且这些元素按照一定的规则垂直地贴合在一起形成平面。在这个平面中,每个层叠上下文都有自己的层级关系,即z轴方向的顺序。
在同一个层叠上下文中,具有较高z-index值的元素会被放置在具有较低z-index值的元素上方;而在不同层叠上下文中,其z-index值的比较就不仅仅局限于自身了,如以下几种情况:
- 层叠上下文父元素的背景色:当两个层叠上下文相互重叠时,如果父元素的背景色与子元素不同,则背景色优先于 z-index 判断。
- 层叠上下文的层级分离: 在不同层叠上下文之间,即使后者的位置在前者之下,元素的层级也可能反转,也就是说放在前面的元素可能被遮挡。
- 根据文档流的顺序:在相同层叠上下文中,后面出现的元素会覆盖在前面出现的元素之上。
形成层叠上下文的条件
形成层叠上下文的条件包括:
- 根元素即HTML元素
- position属性值为absolute、relative、fixed、sticky的元素
- display属性值为flex、inline-flex、grid、inline-grid的元素
- opacity属性值不为1的元素
- transform属性值不为none的元素
- mix-blend-mode属性值不为normal的元素
- filter属性值不为none的元素
- z-index属性值为除auto以外的数字的元素
- isolation属性值为isolate的元素
- -webkit-overflow-scrolling属性值为touch的元素
当一个元素形成了层叠上下文时,它就具有了一定的独立性和优先级,其子孙元素会在该元素内部形成自己的层叠关系,并且不会影响到其他元素。同时,该元素也可以通过z-index属性与其他元素进行相对位置调整。
层叠上下文的顺序
编写z-index 的建议
变形、过渡、动画
变形transform
过渡transtion
CSS 中提供了 5 个有关过渡的属性,如下所示:
| 属性名 | 属性值 | 属性解释 |
|---|---|---|
| transition-property | none / all / property | 设置元素中参与过渡的属性 |
| transition-duration | number,默认是0 | 设置元素过渡的持续时间 |
| transition-timing-function | linear(匀速) / ease(逐渐变慢) / ease-in(加速)/ ease-out (减速)/ ease-in-out(先加速再减速)/ cubic-bezier(n, n, n, n)(使用 cubic-bezier() 函数来定义自己的值,每个参数的取值范围在 0 到 1 之间) | 设置过渡效果的时间曲线 |
| transition-delay | number | 设置过渡效果延迟的时间,默认为 0 |
| transition | 属性名 过渡时间 时间曲线 延迟时间,(各属性间逗号分隔) | 简写属性,用于同时设置上面的四个过渡属性。 |
动画
- @keyframes 规则
要创建 CSS 动画,需要了解 @keyframes 规则,@keyframes 规则用来定义动画各个阶段的属性值,类似于 flash 动画中的关键帧,语法格式如下:
frames animationName {
/* 1.from:定义动画的开头,相当于 0%; */
from {
/* 2.properties:不同的样式属性名称,例如 color、left、width 等等。 */
properties: value;
}
/* 3.percentage:定义动画的各个阶段,为百分比值,可以添加多个; */
percentage {
properties: value;
}
/* 4.to:定义动画的结尾,相当于 100%;*/
to {
properties: value;
}
}
// 或者
/* animationName :表示动画的名称 */
@keyframes animationName {
0% {
properties: value;
}
percentage {
properties: value;
}
100% {
properties: value;
}
}
复制代码
语法说明如下:
animationName:表示动画的名称;from:定义动画的开头,相当于 0%;percentage:定义动画的各个阶段,为百分比值,可以添加多个;to:定义动画的结尾,相当于 100%;properties:不同的样式属性名称,例如 color、left、width 等等。
- CSS 中的动画属性
性能相关
响应式设计
遵循的原则
媒体查询
设备像素,参考像素 移动设备视口
CSS像素
DPR设备像素比
移动端的viewport
CSS常用单位
当开发网页时,CSS单位是一项非常重要的知识。下面是一些常见的CSS单位及其解释:
| 单位名称 | 含义 |
|---|---|
| px(像素) | 一个基本的屏幕上的点,通常用于定义元素的具体大小。 |
| em | 相对大小,相对于父元素的字号大小而言。如:font-size: 1.2em; 表示当前元素字号是父亲的1.2倍。 |
| rem | 相对大小,与根元素(即 html)的字号大小有关。这个单位不受浏览器 font-size 调节的影响,因此是线性的。 |
| %(百分比) | 相对于父元素的宽度/高度而言,可以用于设置元素的宽度、高度、内边距、外边距等。 |
| vw/vh | 视口宽度单位(Viewport Width / Viewport Height),视口指窗口显示内容区域的大小。vw表示视口宽度的1/100,vh表示视口高度的1/100。 |
| pt(磅) | 印刷单位,1pt=1/72英寸;用于打印样式表中。 |
| mm/cm/in | 计量单位,毫米/厘米/英寸,用于打印样式表中。 |
CSS生态相关
语言增强 : 预处理器 后处理器
工程架构: css模块化, css-in-js , Atomic Css
预处理器
后处理器- PostCSS
PostCSS是一个用JavaScript编写的工具,它可以在CSS代码被浏览器解析之前对其进行转换和处理。PostCSS可以扩展CSS语言,使其更加强大、灵活、易于维护。
PostCSS的工作机制主要由以下三个步骤组成:
- 将CSS代码解析为一个抽象语法树(Abstract Syntax Tree,AST)。
- 在这个AST中执行各种插件进行相应的转换或者处理工作。这些插件可以改变CSS规则或者生成新的CSS规则。
- 将处理完毕的CSS代码重新生成成普通的CSS文件,可以是通过压缩、格式化等方式。
PostCSS与其他CSS预处理器如Sass和Less的不同之处在于,PostCSS不需要创建自己的语言或者语法,而是可以直接使用CSS原生的语法和属性。同时,PostCSS的插件也具有高度的可复用性,因为它们只需要操作AST而非独立的样式表。
总体来说,PostCSS的工作机制可以让开发者更加方便地实现各种高级的CSS功能和效果,并且它还可以根据实际需求来选择使用不同的插件,自由度很高。
工程架构
1. 模块化
2. CSS in JS
CSS in JS是一种利用JavaScript代码定义CSS样式的技术,而不是将样式定义在单独的CSS文件中。这种方法允许开发人员编写可重用的UI组件并具有封装样式和行为的特点,可以帮助减少类名冲突并提高大型代码库的可维护性。
有多个流行的库和框架支持CSS in JS,例如styled-components、emotion和glamorous。这些工具提供了在JavaScript代码中使用熟悉的CSS语法定义样式的机制,并且还提供诸如主题、基于props或state的动态样式等功能以及服务器端渲染等功能。
虽然CSS in JS具有一些优点,但也有批评者认为它可能会引入性能问题并使调试变得更加困难。与任何架构决策一样,在决定是否在特定项目中使用CSS in JS之前,应仔细考虑其利弊。
原子化CSS
原子化CSS是一种CSS编写方式,旨在通过使用单个CSS属性的小类(即“原子”)来构建样式,使得样式表更加可复用和易于维护。这些小类通常包含了单一的样式规则,并根据需要进行组合。
相对于传统的CSS编写方式,即将样式按照元素和类名进行组织,原子化CSS更加精细和模块化。由于样式规则被拆分为单个原子,它们可以更加灵活地应用于不同的元素和组件中,从而减少代码冗余并提高可重用性。此外,由于原子化CSS的每个类都具有特定的含义,因此也增强了代码的可读性。
原子化CSS通常与CSS预处理器如Less、Stylus等结合使用,以便能够更容易地生成CSS类。另外,在React等JavaScript库中使用JSS(JavaScript Style Sheets)或Emotion等CSS in JS技术也可以实现类似的效果。不过,使用原子化CSS也可能会带来一些不利因素,例如类名冲突问题和难以覆盖一些较复杂的样式需求。