css知识串烧
css基础
- 选择器
css的选择器有多种为,元素选择器,类选择器,id选择器,伪类选择器,伪元素选择器,可以嵌套使用,嵌套使用可以增加此样式的权重,越特殊的样式权重越高
css深入
- 权重计算
每一个html元素生来都具有所有样式属性以确定其样式,元素的样式是可以人为的改变的,所以在样式层叠过程中需要计算各种写出来的样式的权重,权重计算有几个顺序:- 比较重要性
重要性由低到高为:浏览器默认样式-》作者样式表普通样式-》作者样式表中的!important样式 - 比较特殊性
特殊性即选中范围,越小越特殊,会计算出一个四位数数位进位是逢256进1,细节如下:- 千位:如果是内联样式,记1,否则记0
- 百位:等于选择器中所有id选择器的数量
- 十位:等于选择器中所有类选择器、属性选择器、伪类选择器的数量
- 个位:等于选择器中所有元素选择器、伪元素选择器的数量
- 比较源次序
即代码越靠后权重越高
- 比较重要性
- css样式确定过程
一个元素的样式的确定流程为线性的如下- 确定声明值
即在样式表样式中无样式冲突的样式先确定下来 - 层叠冲突
对样式表中有冲突的样式进行权重计算确定有冲突的样式 - 继承
样式表中并未声明的可继承的样式通过继承确认 - 使用默认值
没有声明也无法继承的样式使用默认
- 确定声明值
- 盒模型
每个可展示元素都会在页面中生成一个矩形的渲染区域,此矩形根据盒子类型不同有不同的渲染规则即为盒模型,每个盒子都有4部分组成,内容盒,内边距,边框盒,外边距,盒模型现在可以分为五类:- 行盒
行内盒子不会从新的一行开始,而是尽可能地紧挨着前一个元素排列,直到一行放不下再换行。
宽度和高度设置对行内盒子不起作用,水平的内边距、边框和外边距可以改变空间,但垂直方向上的这些属性不会影响周围元素的布局(意思是无论上下的padding设的多高都相当于空气)。 - 块盒
独占一行 - 行块盒
可以设置宽度和高度,并且像行内盒子一样,可以在同一行内与其他元素并排显示。
内边距、边框和外边距在所有方向上都有效。 - 弹性盒
弹性盒子是一种一维布局模型,旨在更好地处理复杂的应用布局而无需使用浮动或定位
它允许子元素根据容器的空间自动调整大小,并提供强大的对齐控制能力。 - 网格盒
网格布局是一种二维布局系统,同时处理列和行,使得更加容易设计复杂的网页布局。
它提供了对页面布局前所未有的控制力,能够定义网格轨道(行和列)、网格区域以及网格单元之间的间距。
- 行盒
- 视觉格式化模型
- 常规流
规定了所有元素在正常状态下在文档中的布局规则,如块盒需要独占一行等- 常规流块盒的一些布局规则
- 每个块盒的总宽度,必须刚好等于包含块的宽度,即撑满父元素宽度
- 外边距合并
常规流块盒如果上下外边距相邻其外边距就会合并,数值取大值
- 常规流块盒的一些布局规则
- 浮动
- 实现浮动
将元素的float修改,当一个元素浮动后此元素必定为块盒,其布局位置会参考父元素的内容盒 - 浮动盒子的特点
- 当一个元素浮动后此元素必定为块盒,其布局位置会参考父元素的内容盒
- 当宽度为auto时他不需要撑满包含块而是依据内容撑开,高度为auto则适应内容(同常规流)
- margin在设置为auto时相当于设置为0
- 浮动盒子会靠上靠左排列
- 浮动盒子在包含块中排列时会避开常规流盒子,,并且浮动盒子会漂浮在常规流块盒上方
- **行盒在排列时会避开浮动盒子(文字环绕原理)**p元素实现图片文本环绕时p元素自身是块盒,所以它排列时会无视前边的浮动元素,但是p元素内部的文本会隐式生成行盒,根据这条规则文本就实现了环绕(用其他元素可实现同样的效果)
- 高度坍塌
- 原因
常规流块盒在计算高度时不会考虑浮动盒子 - 解决方案
- 清除浮动
left表示该盒子必须出现在前边所有左浮动盒子的下方(其原理和在浮动盒子后边加一个必须计算浮动元素高度的元素以撑开父元素)
- 清除浮动
- 原因
- 浮动盒子的顶边不得高于上一个盒子的顶边(换行后如果上一行有空间则下一个浮动盒子依然会换行,因为他的顶边不会超过上一个元素的顶边)
- 浮动盒子在排列时若空间不足则会自定换行
- 实现浮动
- 定位
- 相对定位
未脱离文档流,偏转依然会影响其他元素 - 绝对定位
脱离文档流,其他元素摆放时会无视该元素 - 固定定位
相对于视口定位 - 粘性定位
相对于滚动元素定位
绝对定位元素不存在外边距合并
- 常规流
块级格式化上下文
- 是什么
为一块独立的渲染区域,规定了该区域内常规流块盒的布局规则,它隔绝了包含块的内外部,内部的布局不会影响到外部 - 如何创建
- 根元素会创建bfc
- 浮动和绝对定位元素
- overflow不为visible的元素
- 规则
- 创建bfc的元素的自动高度需要计算浮动元素
- 他的边框盒不会和浮动元素重叠(会避开浮动元素)
- 不会与他的子元素外边距合并(处在同一个bfc中的元素会发生外边距合并,不同bfc中的元素不会发生外边距合并)
body元素的背景
给body设置背景色会整个视口都覆盖,但是body的高度是没有的,其原因是浏览器在渲染的时候会准备一块画布,话不的最小宽高为视口,html元素的背景是覆盖视口的,而body的背景规则较为复杂
- 如果HTML元素有背景,BODY元素正常(背景覆盖边框盒)
- 如果HTML元素没有背景,BODY元素的背景覆盖画布
这就是为什么body设置背景会出现异常 - 画布背景规则
- 背景图的宽度百分比,相对于视口
- 背景图的高度百分比,相对于网页高度
- 背景图的横向位置百分比、预设值,相对于视口
- 背景图的纵向位置百分比、预设值,相对于网页高度
图片的底部白边
- 原因
衬线字体 - 解决办法
- 设置父元素的字体大小为0
- 将图片设置为块盒
衬线字体
- 文字的制作
文字是通过一些软件制作出来的,制作时会有几条参考线,不同字体的参考线是不同的,一个文字制作时会存在如下几根线- 虚拟区top线
- 顶线
- 上基线
- 基线
- 下基线
- 底线
- 虚拟区bottom线
- fontsize
设置的是文字的相对大小,所谓相对大小就是在印刷的时候,文字是放在一个金属框里的(印),要缩放一个文字就要了解文字相对于金属框的比例,比如area字体当整个框的大小是2048那么文字的大小就是顶线到基线距离为1884,底线到基线的距离为514,文字的实际占地大小就是顶线到底线,在计算机中很多情况下文字实际大小是要超过框的大小的
而一个文字在前端中的具体大小计算就是 文字实际大小/方块大小*像素如一个16像素的area具体大小就是 (1884+514)/2048*16
这里算的是文字高度,文字宽度是不一样的- content-area
文本从顶线到底线的高度即为文字的实际大小,设置文字大小时设置的不是content-area而是文本的相对大小(文字实际大小/方块大小*像素),行盒的背景,覆盖content-area - virtual-area(虚拟区域line height)
顶线向上延伸的一定空间(gap)的那条线(top)和底线向下延伸的那段距离的线(bottom),两线之间的距离即为virtual-area,此区域是可调整的(不是由字体设计者决定)这个区域就是行高
我们设置行高其实就是在间接设置gap- 文本行内居中原理
当把文本的行高设置为盒子高度的时候文本往往是会垂直居中的,其原因就是整个文本的virtual-area和盒子高度一致上下gap均分content-area以外的高度,就造成了文本垂直居中 - 行与行之间文本重叠原因
当把行高设置成1的时候可能会出现文本高度超出父元素高度的情况 这里的原因是p元素的高度是span文本的content-area撑开的,当把span的行高设置成1的时候实际就是让行高等于200,这时文本的内容区的高度是200,而虚拟区总高度也是200,那么虚拟线就会向下塌陷到内容区顶线和底线之下p元素的高度是span的内容区所以p的高度就会低于文本高度<p style="background-color: red;"> <span style="font-size: 100px;background-color: #008c8c;">M</span> </p>
行与行之间发生重叠的原因就是这个
- 文本行内居中原理
- vertical-aline原理
我们要首先知道所有行盒都会在内部生成参考线,多行盒重叠的情况下默认是基线对齐,原因是浏览器默认行盒的基线默认与父元素的基线对齐(baseline),- baseline:该元素的基线与父元素的基线对齐
- super: 该元素的基线与父元素的上基线对齐
- sub:该元素的基线与父元素的下基线对齐
- text-top: 该元素的virtual-area的顶边,对齐父元素的text-top
- text-bottom: 该元素的virtual-area的底边,对齐父元素的text-bottom
- top:该元素的virtual-area的定边,对齐line-box的顶边
- bottom:该元素的virtual-area的底边,对齐line-box的底边
- middle: 该元素的中线(content-area的一半),与父元素的X字母高度一半的位置对齐
vertical-aline的取值可以为数值和百分比,取值为相对于基线的偏移量(百分比是相对于自身virtual-area的高度)
- linebox
行盒组合起来,可以形成多行,每一行的区域叫做line-box,line-box的顶边是该行内所有行盒最高顶边,底边是该行行盒的最低底边(最低外bottom线,有的行盒可能会向下偏移)。
即多个行盒排列在一行,文本大小不同,那么所有行盒的顶边各线的对齐基准线就是以最高的那个行盒的基准线进行对齐
line-box是承载文字内容的必要条件,以下情况不生成行框:- 某元素内部没有任何行盒
- 某元素字体大小为0
- 可替换元素和行块盒的基线
图片:基线位置位于图片的下外边距。
表单元素:基线位置在内容底边- 行块盒:
- 行块盒最后一行有line-box,用最后一行的基线作为整个行块盒的基线。
- 如果行块盒内部没有行盒,则使用下外边距作为基线
- 图片白边的原理
当一个元素内产生行盒那么该元素也会生成参考线,img元素是行盒那么他也会生成参考线,他的参考线和父元素的基线对齐,就产生了底部白边,解决方法如下- 将父元素的fontsize设置为0
- 讲图片设置为块盒
- 行块盒:
- content-area
堆叠上下文
- 创建堆叠上下文的元素
- html元素(根元素)
- 设置了z-index(非auto)数值的定位元素
- 同一个堆叠上下文中元素在Z轴上的排列
- 创建堆叠上下文的元素的背景和边框(创建堆叠上下文的元素)
- 堆叠级别(z-index, stack level)为负值的堆叠上下文
- 常规流非定位的块盒
- 非定位的浮动盒子
- 常规流非定位行盒
- 任何 z-index 是 auto 的定位子元素,以及 z-index 是 0 的堆叠上下文
- 堆叠级别为正值的堆叠上下文
svg
数据连接
- 什么是数据连接
将目标文件的数据直接书写到路径位置,即直接将文件的数据作为url书写到页面上 - 语法
data:MIME,数据div { background: url("data:image/png;base64,数据" } - 优缺点
- 减少了浏览器中的请求
- 减少了请求中浪费的时间
- 有利于动态生成数据
- 增加了资源的体积
- 不利于浏览器的缓存
浏览器兼容性与渐近增强 和 优雅降级
- 渐近增强 和 优雅降级
- 渐近增强:先适应大部分浏览器,然后针对新版本浏览器加入新的样式,书写代码时,先尽量避免书写有兼容性问题的代码,完成之后,再逐步加入新标准中的代码。(以老浏览器的兼容性为准)
- 优雅降级:先制作完整的功能,然后针对低版本浏览器进行特殊处理,书写代码时,先不用特别在意兼容性,完成整个功能之后,再针对低版本浏览器处理样式。(以新版为主,再向上兼容)
边框
- border-radius
实际上是速写属性,如果设置四个值则表示从左上角开始的四个角,如果是两个值则表示从左上角开始的对角,如果是三个值那么依然代表从左上开始的三个角而剩余那个角则为其对角- 圆角原理
如果将复合属性拆开单独给某一个角设置远角的话,最多可以设置两个值,分别表示在该角处内接一个椭圆,该椭圆的水平半径和垂直半径,故可以设置两个值
当设置水平半径或垂直半径大于元素宽度或高度时,为了将内接的椭圆放进元素就会用 变长/(水平半径+垂直半径) 算出缩小比例,然后用 对应边长*缩小比例 获得新的元素边长(内接半径)
- 圆角原理
- border-image
- border-image-souse
图片路径 - border-image-slice
图片切割方式,设置边框图片的时候会将给定的图片按照给定的值拉出四条线将图片分割成九块,分别将分割的图片填入这个九宫格的九个位置(默认中间不填充) - border-image-width
设置边框的宽度(切割后图片的宽度,超出边框宽度会向内压缩宽度) - border-image-outset
也是设置边框宽度但是当超出的时候会向外扩张 - border-image-repeat
当切割的图片的宽度不足以占满边框的时候默认或拉伸图片,因为默认此属性norepeat,如果设置成repeat则会在不足的时候重复元素
- border-image-souse
- box-shadow
为一个速写属性,第一个参数为水平偏移量,第二个为垂直偏移量,第三个为模糊半径,第四个为扩张半径(阴影向外扩张的距离),第五个为背景色,背景可以设置多个,以逗号隔开多个盒阴影,第一个参数也可以设置为盒边框位置,默认为外边框(向外)也可以设置为向内
背景
- background
- background-img
可同时设置多个背景图,他们是相互堆叠的 - background-repate
- 速写属性,可分为x和y
- round 背景图重复,并调整图片的大小让容器经可能多的容纳完整背景图
- space 尽可能多的放入完整的按照图片大小的图,会存在空隙
- background-position
- 水平垂直偏移量,写一个值另一个不写默认center
- 写百分比,代表的是甚于空间的百分比,比如一个父元素宽度400背景图200,写50%表示400-200的50%,也就是左边在距父元素左边框100的位置
- background-origin -背景图定位的参照物相对于盒模型,可以配合position使用
- background-size -设置元素的宽高(两个值)
- background-clip -规定了图片在哪个盒子内展示(值为盒子如padding)其一个属性为text用于给文本设置背景图,要给文本设置背景图需要文本的颜色为透明(可以设置动图)
- background-attachment -设置背景图相对于滚动条的位置情况,如使用fixed就像固定定位一样,滚动条滚但是图不动
- 可以用于实现特殊的背景图滑动效果
- background-img
css2d变换
- 一些空间变换会带动坐标轴一起变化,如旋转之后坐标系也会跟着旋转,原坐标系是x轴向右y轴向下,旋转90度后就变成了x轴向下y轴向左
- 由于轴的存在变换操作可以实现类似镜像内容的操作,如将一个元素的scaleX设置为-1就相当于将一个元素沿x轴镜像
css3d变换
- 什么是景深
在3d视角下,浏览器上会添加z轴,这个时候浏览器默认我们看到的始终是屏幕,当元素在z轴上进行移动的的时候会在屏幕上绘制一个从我们眼睛位置(perspective值)到物体边到屏幕的投影,我们看到的就是投影,那么当物体远离屏幕的时候,各边在眼睛和屏幕和物体上的投影就会变小(三角形),而物体靠近眼睛的时候投影就会变大
css过渡动画(transition)
css关键帧动画
- 利用动画实现语音输入的音条
- 实现碟片正向反向转动效果,用同一个关键帧动画
- 实现老师的点赞动画
flex
- display: inline-flex 直接设置flex不设置宽度默认占满包含块,而此属性则相当于行块盒不设置宽度则无宽度
- flex子项若不设置高度默认占满父元素高度,且给子项设置margin 0 auto也会自动分配父元素剩余空间
- align-items 交叉轴方向上所有元素的排列方式(或者说单行)他把所有子项看作一个整体
官方解释 CSS align-items 属性设置了所有直接子元素的 align-self 值作为一个组。在 Flexbox 中,它控制子元素在交叉轴上的对齐。 - align-content 设置交叉轴上元素每一行的排列方式(说白了就是切换了交叉轴的方向然后使用jc的效果)
items设置的是把交叉轴所有元素看作是一个整体,去调控其在价差轴上的对齐方式,而content则是在价差轴上的每个元素的对齐方式,相当于jc(不过此属性需要交叉轴上要有多行才能生效)
官方解释如下 CSS 的 align-content 属性设置了浏览器如何沿着弹性盒子布局的纵轴在内容项之间和周围分配空间。 - align-self 每个容器在交叉轴上的排列方式
- order 元素的排序方式,可以实现在元素顺序固定的情况下实现元素的排序
- flex-basis 设置元素的基础尺寸,当元素内部的内容大于基础尺寸会以内容尺寸为主,他会被内容撑开,如果同时设置宽度和该属性,则会基于一个公式max(min(width, content length), flex-basis)意思是,首先取宽度和内容宽度的最小值,当宽度小于内容宽度的时候取内容宽度,然后再和flex-basis值比较,如果内容宽度小于flex-basis则取flex-basis否则取内容宽度
- flex 即flex-basis,fg和fs的顺序简写,默认为0,1,auto
grid -网格布局
-
display
- grid
具有块级元素特点的网格,如果写入三个元素,元素默认会纵向排列,即一列三行 - inline-grid
具备行块盒特点的网格
- grid
-
grid-template-columns
设置每列宽度,写几个值就代表有多少列,多个列宽组成了一行的总宽度- fr
剩余空间等分单位,将父元素剩余空间等分,可写多个grid-template-columns: 50px 1fr 2fr
表示第一列宽度由50px,第二列和第三列占据所有剩余空间,第二列占三分之一,剩余第三列占有
2. min-content
表示内容区换行的最小宽度
3. max-content
表示内容区不还行的最大宽度
4. repeat()
有两个参数,第一个为重复次数,第二个由空格隔开,表示重复项
~~~ css
grid-template-columns: repeat(3, 10px 20px)
~~~
表示整个列分为六项,重复10px和20px
1. 参数一 auto-fit
表示自动划分网格,比如父元素500px,有5个子元素,设置repeat(auto-fit, 100px),会自动绘制五个列,有剩余宽度的话会将后续可填充的网格全部折叠在一起放在最后一条线上
2. auto-fit
功能类似,但是不会折叠,多余空间自动填充制定宽度的网格线
3. minmax(t1, t2)
t1表示最小值,t2表示最大值,这一列的宽度将会根据父元素宽度在这两个值中取值,可以结合fr实现三列布局
~~~ css
grid-template-columns: 100px minmax(100px, 1fr)
~~~
表示第一三列宽100,第二列如果宽度剩余空间大于100则全部占据,小于100则取100 - fr
-
grid-template-rows
设置每行的高度,设置几个值即有几行,多个行高组成了一列的总高度 -
gride-column
设置某个字元素从第几条边开始到第几条边结束gride-column: 1/3表示从第一条边开始,到第三条边结束
-
gride-row
同上,设置行开始与结束 -
grid-template-areas
用于给单元格命名,根据定义的行列数来进行操作grid-template-areas: "head head head head" "side body body body" "footer footer footer footer"上边的代码表示将定义的三行四列的网格的第一行命名为head,第二行为body,第三行为footer,光是命名是没有意义的,需要配合子元素属性进行操作
-
grid-area
表示此部分代码将应用到相应名字的模块,以下代码将应用于所有命名为head的模块.head { grid-area: head; background: red; } -
grid-template
以上的grid-template-areas和grid-template-columns和grid-template-rows可以使用此属性进行简写grid-template: "head heda head" 1fr "aside body body" 3fr "footer footer footer" 1fr / 1fr 1fr 1fr这段代码定义了一个三行三列的网格并定义了行高和模块名,斜杠前定义列数和列宽,后则表示行和行高
-
grid-auto-flow
设置元素的排列方向,默认是从左到右,从上到下,当设置为column时则排列方式修改为从上到下,相当于flex中的fd改变主轴方向- grid-auto-flow第二参数
当使用grid-column-start修改元素布局开始位置后,他的前边就会存在一个为排列元素的空余单元格,如果将grid-auto-flow的第二个参数设置为dens就会让后续可以放入此单元格的元素优先填充进此单元格,等宽的四行两列,将第一个元素放在第三条线开始排列,那么就空出了两个元素,如果设置了此属性则后续的第三第四个元素就会填充进第一第二个单元格
- grid-auto-flow第二参数
-
容器对齐方式(元素在单元格中的对齐方式,单元格宽元素窄的时候)
-
justify-items
水平方向的对齐方式,设置在grid容器元素上的属性,属性如jc,有一个stretch(默认)当元素在容器中不设置宽高则默认撑满单元格 -
align-items
垂直方向上的对齐方式,同样有stretch属性,撑满高度。默认值为normal -
place-items(以上两属性的简写属性,第一个为垂直方向齐方式,第二个为水平)
-
justify-content
整个网格元素在容器元素中的主轴排列方式,容器可能大于网格,也可以实现网格套网格,属性同flex的 -
align-content
整个网格元素在容器元素中的交叉轴排列方式 -
place-content(为上两属性的融合属性,第一个参数为列排列方式,第二个为行)
-
-
设置某元素占据的网格区域
当给某个元素设置了这四个属性后就规定了这个元素占据的 -
grid-column-start
-
grid-column-end
-
gird-row-start
-
grid-row-end
mask
此样式的各项属性类似于gackground,需要知道的是此属性设置的遮罩类似饺子皮模具,只有饺子皮模具框住的才展示,没框住的不会展示,不如底部有一个背景图宽500搞500,我设置的遮罩图宽50高50那么展示的就只有遮罩图的50*50
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.box {
width: 1134px;
height: 642px;
margin: 0 auto;
background-color: #000;
}
.mask {
--x: -150px;
--y: -150px;
mask-image: radial-gradient(
circle at var(--x) var(--y),
#fff 70px,
transparent 100px
);
}
</style>
</head>
<body>
<div class="box">
<img class="mask" src="../assets/kun.PNG" alt="" />
</div>
<script>
const box = document.querySelector(".box");
const mask = document.querySelector(".mask");
box.onmousemove = function (e) {
const { offsetX, offsetY } = e;
mask.style.setProperty("--x", `${offsetX}px`);
mask.style.setProperty("--y", `${offsetY}px`);
};
box.onmouseleave = function () {
mask.style.setProperty("--x", `-150px`);
mask.style.setProperty("--y", `-150px`);
};
</script>
</body>
</html>
clip-path


裁剪
裁剪一个三角形,之前还在利用border去模拟。
现在一行代码搞定
ele {
clip-path: polygon(50% 0, 0 100%, 100% 100%)
}
它可以按照 svg 路径、盒子模型、基本多边形路径等几种不同的方式来裁切
svg路径:
ele {
clip-path: url(#svg)
}
基本图形:
矩形:
clip-path: inset(top right bottom left)

圆形
clip-path: circle(半径 at x y);
椭圆
clip-path: ellipse(水平半径 垂直半径 at x y);
多边形ploygon
clip-path: ploygon(x1 y1, x2 y2, x3 y3, ...)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.box {
padding: 20px;
width: 400px;
text-align: center;
/* border: 4px solid #fac; */
margin: 100px;
position: relative;
}
.box::after {
content: "";
position: absolute;
left: -3px;
top: -3px;
right: -3px;
bottom: -3px;
border: 5px solid #cfa;
clip-path: inset(0 96% 0 0);
animation: clip-inset 2s linear infinite, hue-rotate 2s linear infinite;
}
@keyframes hue-rotate {
to {
filter: hue-rotate(360deg)
}
}
@keyframes clip-inset {
0%,
100% {
clip-path: inset(0 96% 0 0);
}
25% {
clip-path: inset(0 0 96% 0);
}
50% {
clip-path: inset(0 0 0 96%);
}
75% {
clip-path: inset(96% 0 0 0);
}
}
</style>
</head>
<body>
<div class="box">css 裁剪 clip-path</div>
</body>
</html>