进来工作代码不断增加发现对css的运用有了一定的偏差,所以在此对css的运用做总结学习
css选择器优先级
!important 1000 >
id 100 >
class 10 =
属性选择器 .a[ref="some"] 10
= 伪类选择器 a::nth-child(n) 10
> 标签选择器 1
= 伪元素选择器::before和::after其中after的z-index一定会盖住before的z-index
> 0(特殊选择器+,>,空格,*...)
css的可继承属性和不可继承属性
可继承属性
- 字体font
- 文本的缩紧、行高,水平对齐方式,字间距,字体大小,颜色等
- 可见度visibility opacity
- 列表布局 list-style
- 光标 cursor
不可继承属性
- display(block,inline,inline-block)
- 文本类的垂直对齐方式,装饰类,阴影空白符文本方向等
- 盒模型
- 背景
- 定位
- 内容类(伪类创造)
- 轮廓
- 页面样式
- 声音
隐藏一个元素的方式
- display:none 元素不在页面当中,会导致回流重绘,多次渲染尽量不要使用这个,仅作用当前元素,直接消失不利于子元素的更改
- visibility: hidden 元素存在界面之中,只会重绘性能较好,对事件等不影响所以要注意使用,被继承的可修改子元素再让子元素进行展示
- opacity:0 元素透明显示和上方一样
- 定位移出界面或z-index放到最下边给他遮住
- clip将元素裁剪出去
- transform:scale缩小元素
css文件引用时link引用和@import引用的区别
- link引用时XHTML的识别标签之一,不仅可用于引用css,还可以引用其他文件,而@import仅可用于引用css
- link由XHTML触发,会在页面加载过程中同步加载,而@import会在页面载入完成后异步加载
- link兼容无问题,而@import在低版本浏览器不支持,css支持在2.1版本之上
css动画的使用
- 单个动画使用:transition 仅2帧,多触发于某种特定情况
- 循环动画的使用:animation 可支持多帧动画(@keyframe),类似于flash动画,可自己控制执行时间动效等
visibility和display:none的区别伪
- 对比渲染层面,display:none会不在元素中渲染,但是回流重绘成本更高;visibility还会再元素中,只是透明了,多次hover的操作用这个可以减少渲染成本,不会回流
- 对比继承方面,display只作用于当前元素,但是visiblity是继承的,修改子元素样式可以让子元素在显示回来
伪元素和伪类
伪元素
伪元素::before和::after或其他伪元素再元素之前或之后所添加的额外的元素和样式,在代码中并不存在,而且::after的元素等级高于::before,多用于添加角标,清除浮动等
伪类
伪类一般只有一个冒号,目的是为了在元素在特定的环境或触发条件下下更快的添加想要有的对应的样式
回流与重绘
question one 是什么
回流是针对盒子的大小或位置改变而引起的页面重构.
重绘是盒子的颜色或大小或与位置无关的几何元素发生改变所引起的页面的重新绘制
question two 为什么会被触发
回流绘受display:none或直接add或remove元素导致的元素变化,通过触发特定环境更换元素位置,大小,内容等所被触发的,其中页面的首次渲染,浏览器的大小更改都会引起页面的回流.
重绘受回流影响必然重绘,或者更换颜色文本方向等会进行重绘.
此处注意:回流必然引起重绘而重绘不一定会引发回流
question three 如何减少回流重绘
- 尽量减少行内样式的更改样式,多使用类名更改样式
- 减少内联样式的更换
- 减少使用table布局(原因:table的子元素的更改会导致整个元素的重新计算)
- 使用动画时尽量使用定位使元素脱离文档流而影响其他元素
- 减少js中使用css,或者使用styled-component来使用cssInJs的思想减少影响
- 离线操作(即在js更改复杂样式前先使用display:none后更改元素样式,设置完以后在block设置回去减少重绘次数)
- 改变元素位置时可以使用translate(translate并不会触发回流重绘,而是会进行复合更改,若使用定位不仅会复合更改,还会引起重绘)
requestAnimationFrame动画帧
question one 是什么
是H5提供的一个请求动画的API,用于告知浏览器执行动画并在下次重绘前利用指定的回调进行更新,大致就是在js中书写动画,减少回流重绘时多余的动画计算,多用于canvas书写动画
question two 为什么
我们前边明明说为了减少回流重绘要少在js中写css,但是一些复杂动画需要我们使用js进行控制,所以不可避免的还是要在js中书写动画,但是页面根据各个电脑的不同刷新频率各不相同,若使用setTimeout等形式执行时间的不确定性会出现动画卡顿丢帧,暂停的时候也会有多余的执行影响性能,所以H5为我们提供这个方法会在屏幕刷新时调用(最快16ms,可能更快,但是也有慢的三十或者七十多毫秒),减少丢帧或重复的情况发生
question three 怎么做
使用windown.requestAnimationFrame(callback)执行动画;但是要注意浏览器兼容性
盒模型
盒模型的组成由content,padding,boder和margin索组成,但是在width和height的设置和获取上ie和其他浏览器有所不同,不过目前ie也不再更新了,可以忽略这部分的不同
标准盒模型的width只包含content
怪异盒模型的width包含了content,padding和border
若想更改这部分的影响可以对元素的box-sizing做出更改,针对标准盒模型给出content-box,针对怪异盒模型给出border-box
css3的常用特性(包含新增伪类和选择器和其他的样式方面)
- css选择器方面
- 元素:not(选择器) --表示所有这个元素中不是里边的那个条件的节点
- 元素[attribute]--所有带该属性的这个元素
- 元素[attribute=值]--所有属性为某个特定值的元素
- 元素[attribute~=值]--所有属性值包含特定值的元素,此处的特定值会被识别为单词
- 元素[attribute*=值]--所有属性值包含特定值的元素,此处的值会被识别为字符串
- 元素[attribute^=值]--所有属性值的开头为这个特定值的元素
- 元素[attribute$=值]--所有属性值的结尾为这个特定值的元素
- p > a 子元素选择器,选中在p的下一级的a元素
- p + a 相邻兄弟选择器,选中是p元素兄弟的a元素,a必须在p元素之后
- p ~ a 同级通用兄弟选择器,选中在p元素后的所有同级的a元素
- p,a 群组选择器,选中p和a元素同时被作用
- 伪类选择器(不存在于代码中仅交互体现)
- :link 未被选中的链接
- :visited 被访问过的链接
- :hover 鼠标滑过的链接
- :active 鼠标点击的链接
- :focus 聚焦后的效果(多用于输入框或选择器)
- :target 点击猫点链接时出现的目标元素,即跳转页面的某一个特定部位的那个目标元素
- :first-child/:last-child 第一个或最后一个孩子
- :nth-child(n) 第几个还是,当n为odd/even时可代表是单数还是双数
- :nth-last-child(n)倒数第几个孩子
- :nth-of-type(n) 指定类型的子元素
- :nth-last-of-type(n)倒数的指定类型的子元素
- :only-child 仅一个孩子的父元素
- :only-of-type 可以指定仅有一个孩儿类型的父元素
- :empty 没有子元素的元素
- :where(div1,div2) 可容错选择器列表,选择满足条件的元素,为类名时则是被这些元素所包裹的这个元素,也可以用于是否浏览器支持这些属性,不支持直接就不会被写入样式表中,用于选中或作用一些属性,但是:where的优先级为0,同类名下会被后面的元素属性覆盖
- :is(div1,div2) 和:where的作用相似,但是他的优先级为1会被累计
- 伪元素
- ::first-line 元素的第一行文本
- ::first-letter 元素的最后一行文本
- ::before 元素之前插入内容
- ::after 元素之后插入内容
- ::selection 选中的文本的样式
- 新增样式
- border-radius 圆角
- box-shadow 阴影(水平偏移,垂直偏移,模糊度,扩展度,颜色,是否为内阴影)
- background-image 渐变背景,也可直接设置为图片
- background-clip 背景剪裁
- background-origin 背景起始位置
- background-repeat 背景平铺
- background-size 背景大小
- margin-inline-start 渲染的方向距离左侧的位置,这个的使用可以代替margin,当渲染文本在其他方向时不是按照盒子的左侧而是文本渲染的左侧来定义margin的外侧距离值
- 渐变 linear-gradient垂直方向的颜色渐变,repeating-radial-gradient环形方向的颜色渐变
- 动画 transform transition animation @keyframes
图片的常用格式和使用场景
- BMP 无损的支持索引色和直接色的点阵图,很难压缩体积很大
- GIF 无损的采用索引色的点阵图,文件小,支持透明,可以动画,但是仅支持256色,常用于文件下且色彩少的文件
- jpeg 有损的采用直接色的点阵图,多用于存储照片,一般不直接拿来做展示,有损压缩会模糊图像,直接使用文件会大
- png-8 无损的索引色点阵图,文件小支持透明,就是不能做动画,压缩后效果还行
- png-24 无损的直接色点阵图,压缩后数据会更小,但是用的少因为就算压缩也还是会大
- svg 矢量图,直接绘制出的,不会失真,多用于logo和icon,大型文件代码多还是使用图片更好
- webp 谷歌的新提供的图片格式,文件下,好看,加载快,but兼容性很拉
精灵图
为减少图片加载数量和次数,提升性能,减少图片加载字节,提升浏览器加载速度,我们会将多张图片合为一张作为精灵图通过定位的方式使用,但是这个使用对图片的要求较高,后期更改时css修改成本也高,尽量一次完成
media query 媒体查询
媒体查询可以针对不同屏幕比或者其他如旋转屏,是否支持该样式等给出不同的样式,这里多用于多端开发或者适配等(适配也可考虑使用rem或者阿里的flexible结合postcss使用,这样还可以减少dpr影响,就是对移动端的定宽定高的样式设置要单独处理)
css的预处理器和后处理器
预处理器sass/less
会在浏览器加载之前进行编译,使用起来可以减少代码,增加代码复用性,可以简便的在css中使用js的方法,加快开发进度
后处理器postcss
会在编译完成后才加载,使样式更加有效无兼容问题,并且可以针对不同的浏览器内核做特殊处理
使用的优点
使用起来逻辑清晰便于查找;结构严谨减少无用嵌套;维护起来更佳
伪类选择器的:: 和: 的区别
- :是伪类,::是伪元素,二者虽然可以混合使用但是定义不同
- :是触发的规则,::是页面真实存在的内容
- 当然1中所说的混合使用是在css2.1时提出的伪元素选择器还是单冒号到css3的时候用到双冒号,只是为了兼容才可混合使用但是现在不建议混合还是按照规定使用防止那天就不允许了
getBoundingClientRect
返回元素本身及四周距离的大小,这里的距离是根据视窗而定,可以减少父元素的设定对这个距离的影响
z-index失效的特殊情况
- ::after的z-index会高于元素的z-index和before的z-index
- 元素不占位,父元素设置relative的定位时会失效,这里的z-index就要设置到父元素身上了,只有父元素高了子元素才可以设置到的高一些
- 元素浮动后会失效
常见的css单位
- px 像素比,无继承
- % 百分比,继承父元素
- em 字体大小继承最近的父元素的font-size
- rem html的font-size值为1rem
- vw/vh 视窗尺寸 1vw/vh=1/10视窗
移动端适配方式
- 媒体查询 虽然针对不同端要写很多不同的样式,但是会更加精准,就是代码量会增多
- rem 针对不同终端对html的font-size做特殊处理,然后根据视觉稿自己除出对应的rem值(计算起来有点累)
- postCss+dpr+rem 这里就使用先前提出的阿里的flexible+postcss做对应处理即可,这样的处理可以提高屏幕的清晰度,也可以在开发过程中减少rem计算,毕竟后处理器么,最后他会帮你算的,嘿嘿。
块级格式化上下文BFC和行内格式化上下文IFC
BFC
一个盒子下会有自己独立的作用域,样式会作用到他的下级,不会影响其他外部元素的样式,一般单独开发出来减少回流重绘的影响,做独立块使用,触发条件有很多,以下是常见的一些条件:
- 根元素body
- 设立float浮动
- 设立绝对定位或固定定位
- 设置display为inline-block或flex,table-cell
- overflow的设立
主要用于解决
- margin重叠问题,两个元素的margin重叠会去取最大的那个margin单独使用
- 实现河流图
- 解决高度塌陷
- 实现多栏布局
IFC
行内格式化上下文,不咋用,不多做说明
css实现一些特殊的形状
-------扇形------
div{
width:0;
height:0;
border:100px solid transarent;
vorder-radius:100px;
border-top-color:#f00;
}
-------三角形------
div{
width:0;
height:0;
border:100px solid transarent;
border-top-color:#f00;
}
-------椭圆-------
div{
width:100px;
height:50px;
border-radius:50%;
background:#ff0;
}
------0.5px的线------
div{
width:100%;
height:1px;
transform:scale(1,0.5)
}
of corus 你也可以设置信息元的viewport来书写,但是这里一旦使用你所写的所有样式都要两倍大,有点麻烦,现在高版本的很多浏览器也支持0.5px的线了,慢慢升级吧
<meta name="viewport" content="width=device-width, initial-scale=0.5, minimum-scale=0.5, maximum-scale=0.5"/>
常见的css对应的浏览器内核
- -moz 火狐(Gecko内核)
- -ms IE(Trident内核)
- -webkit 谷歌(现在更改为Blink内核是这个内核的精简版),苹果
- -o- Opera浏览器(Presto内核)
虚拟边框动画
依赖的不是border,是background,依赖渐变背景平铺,然后用animation书写会好看很多
div{
background://同时定义四个背景层,定义颜色和向那个方向平铺 linear-gradient(90deg ,#333 50%, transparent 0) repeat-x,
linear-gradient(90deg ,#333 50%,transparent 0) repeat-x,
linear-gradient(0deg, #333 50%,transparent 0) repeat-y,
linear-gradient(0deg, #333 50%,transparent 0) repeat-y;
background-size: 4px 1px, 4px 1px,1px 4px,1px 4px;//定义大小
background-position:0 0, 0 100%, 0 0,100% 0;//定义位置
&:hover{
animation: linearMove .3s infinite linear;
}
}
@keyframes linearMove{
100% {
background-position: 4px 0,-4px 100%, 0 -4px,100% 4px;//通过更改背景位置实现动画
}
}
cssHoudini 进阶
开发者可用此api来更改进行浏览器渲染引擎的更改,可以不用等待浏览器本地的css加载,提升渲染速度。
优势有:
比element-style加载更早,更快,不必等待浏览器对css的加载合成,直接在此之前进行更新更改
API有:
- Paint API
提供了一组与绘制(Paint)过程相关的API,我们可以通过它自定义的渲染规则,例如调整颜色(color)、边框(border)、背景(background)、形状等绘制规则。
- Animation API
提供了一组与合成(composite)渲染相关的API,我们可以通过它调整绘制层级和自定义动画。
- Layout API
提供了一组与布局(Layout)过程相关的API,我们可以通过它自定义的布局规则,类似于实现诸如flex、grid等布局,自定义元素或子元素的对齐(alignment)、位置(position)等布局规则。
- low-level APIs:低层次的API,这些API是high-level APIs的实现基础。
- Typed Object Model API
- CSS Properties & Values API
- Worklets
- Font Metrics API
- CSS Parser API
<script>
// 进行加载操作,将对应的js代码加载入内
CSS.paintWorklet.addModule('csscomponent.js');
//添加样式
CSS.registerProperty({
name: '--my-color',//名称
syntax: '<color>',//当作什么进行解析
inherits: false,//是否继承
initialValue: '#c0ffee',//内容
});
//加入默认的样式,使用函数的形式将背景设置为既定的背景样式
class CheckerboardPainter {
paint(ctx, geom, properties) {// 元素,原型,不知道
const colors = ['red', 'green', 'blue'];
const size = 32;
for(let y = 0; y < geom.height/size; y++) {
for(let x = 0; x < geom.width/size; x++) {
const color = colors[(x + y) % colors.length];
ctx.beginPath();
ctx.fillStyle = color;
ctx.rect(x * size, y * size, size, size);
ctx.fill();
}
}
}
}
// 注册checkerboard
registerPaint('checkerboard', CheckerboardPainter);
textarea {
background-image: paint(checkerboard); // 使用paint()方法调用checkboard绘制背景
}
</script>
//更多使用见这里https://zhuanlan.zhihu.com/p/538583864
进阶: 使用ScrollTimeLine类制作滚动动画
首先我们要知道animation的动画制作加载不是依赖于时间的,而是依赖他本身的加载,但是这个时间是固定的,当我们想要一个既定的动画实现滚动条联动动画加载时,我们就可以使用@scroll-timeline moveTime{}选择用滚动条的进度来加载动画
//内容
#g-content {
width: 300px;
height: 170vh;
background: #999;
}
//滚动的壳
#g-box {
font-size: 150px;
margin: 70vh auto 0;
//有关动画的设置
animation-name: rotate;
animation-duration: 3s;
animation-direction: alternate;
animation-easing-function: linear;
//一定要对应到动画的时间轴
animation-timeline: box-rotate;//动画的时间轴
}
@keyframes rotate {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
//这个对应动画的时间轴
@scroll-timeline box-rotate {
source: selector("#g-content");//选中对应的元素滚动内容
orientation: vertical://监听元素朝那个方向滚动
scroll-offsets: none;//滚动的什么阶段触发动画,这个值还挺复杂,不过依赖这个值可以做出更好看的动画效果,有需要的时候可以去查一查
}
scroll的一些设置
-
scroll-snap-type查询元素滚动方向并在规定的临时点内处理滚动结束的状态,作用于滚动的父元素
-
scroll-snap-align 停止后元素所在的位置,作用于滚动的子元素
-
scroll-margin 作用于滚动的子元素,指定最终的滚动结束时所在的位置
-
scroll-padding 作用于滚动的父元素作用于滚动父元素
@supports 可以检查浏览器是否有该样式有的情况下才做下述操作
eg。
@supports (animation-timeline:works){
@scroll-timeline list-item-1{
source:selector('#id');
start: selector(#list-item-1) end 0;
end: selector(#list-item-1) end 1;
scroll-offsets:
selector(#list-item-1) end 0,
selector(#list-item-1) end 1
;
time-range: 1s;
}
}
获取一个content的属性值 attr()
css表达式的attr()可以用来获取选择到元素的某一个html属性值并作用他的样式,还有内容,也可以使用伪元素
.text::before{
//这里可以有对应的内容和对应的样式
content:attr(.p)
}
根据饱和度计算颜色值计算函数hsl()
暂时没有使用过,仅看到过,以后可以研究一下调色板
css计算函数
css表达式hsl()函数用于根据饱和度计算颜色值的。
css表达式alpha() 函数是用来选择透明度的
css的filter将模糊或颜色偏移等图形效果应用于元素。滤镜通常用于调整图像、背景和边框的渲染,其中的url()函数是svg选择器,可以将对应的svg模版克隆填充,此svg可放至xml或者外层渲染中
css-in-js
我们在开发项目的过程中有时会多人开发或者通过微应用,iframe等形式做一些复用活着嵌套,这里多数可能会发生类名重复的情况,所以在2014年时在js中书写css样式通过hash来控制影响范围,常见的我们会使用cssmodule,但是不能用js写css,所以对于复杂的样式书写可以用style-components来实现
eg.使用时可穿惨
export const IconBookWrapper = styled.div<{ $top: number | undefined }>`
width: 100%;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
> img {
width: 140px;
}
${(props) =>
/* 如果传入top数值,转换为具体marginTop值 */
typeof props.$top === 'number'
? css`
margin-top: ${props.$top}px;
`
: css`
height: 100%;
justify-content: center;
`}
`;
export const TextWrapper = styled.div`
color: var(--icon-color);
font-size: 14px;
line-height: 20px;
text-align: center;
margin-top: 15px;
margin-bottom: 12px;
`;
如何在js中设置css的变量
dom.style.setProperty("--color","red")
env的使用,作用于安全边距
css的env主要针对于边界使用,主要是苹果的刘海屏等,一般safe-area-inset-top,safe-area-inset-right,safe-area-inset-bottom,safe-area-inset-left和这些一起使用来得到安全边距
calc的使用,作用于计算单位
css中的calc主要是为了进行样式计算的时候来使用,可以进行简易的加减乘除计算来达到样式的精准,支持不同单位的计算。