1.关于CSS
CSS是李爵士(Tim Berners-Lee)的挪威同事赖先生(Hakon Wium Lie)首先提出的。
CSS全称为Cascading Style Sheets,中文名叫层叠样式表。它是一种用来为结构化文档(如HTML文档或XML应用)添加样式(字体、间距和颜色等)的计算机语言,由W3C定义和维护。
层叠的三种结构:
- 样式层叠:可以多次对同一选择进行样式说明;
- 选择器层叠: 可以用不同选择器对同一个元素进行样式说明;
- 文件层叠: 可以用多个文件进行层叠。
历史版本:
- CSS1 1996年发明
- CSS2 1998年发明
- CSS2.1 2004年~2011年(使用最广泛的版本 IE支持)
- CSS3 1999年开始起草 现代版本,分模块(IE8部分支持)
通过caniuse网站可以得知哪些浏览器支持CSS哪些特性
2.关于文档流(Normal Flow)
元素流动方向:
- inline元素(内联元素):从左到右,到最右边才会换行;
<span> - block元素(块级元素):从上到下,每一个都会起另起一行;
<div> - inline-block元素也是从左到右。
宽度(width)
- inline元素宽度为内部inline元素的和 不能用
width指定宽度 - block元素默认自动计算宽度,可用
width指定(默认auto,不是100%,最好不设100%); - inline-block结合前两者特点,可用
width指定。
高度(height)
- inline元素高度由
line-height(行高,也就是实际高度)间接决定(跟字体相关),跟height无关; - block高度由内部文档流元素决定,可以设
height; - inline-block跟block类似,可以设
height。
内容溢出(overflow)
当内容宽度或高度大于容器的宽或高,会溢出
overflow属性
overflow: auto灵活设置(常用)overflow: scroll永远显示滚动条overflow: hidden隐藏溢出部分overflow: visible可看见- 可分为overflow-x, overflow-y(x横y竖)
脱离文档流
float、position:absolute、position:fixed可使元素脱离(跳出)文档流
3.关于盒模型(Box-Sizing)
盒模型类型:
content-box内容盒-内容就是盒子的边界border-box边框盒-边框就是盒子的边界
公式:
content-box width=内容宽度border-box width=内容宽度+padding+border
margin合并
margin合并是指块级元素的上外边距与下外边距有时会合并为单个外边距。两种情况:父子合并;兄弟合并。
如何阻止合并
父子合并:
- 给父容器添加
padding/border - 给父容器加
overflow:hidden(溢出的元素就会被浏览器隐藏); - 给父容器加
display: flex
兄弟合并(符合预期)
- 给两个
div设置display:inline-blcok,并添加 ️width:100%。
基本单位
长度单位
- px(像素)
- em(相对于自身font-size的倍数)
- 百分数
- 整数
- rem
- vw、vh
颜色
- 十六进制 例如
#FF6600/#F60 - RGBA颜色 例如
rgb(0,0,0)或rhba(0,0,0,1) - hsl颜色 例如
hsl(360,100%,100%)
4.CSS布局(Display/Layout)
分类
- 固定宽度布局 一般为960/1000/1024px (pc端)
- 不固定宽度布局 主要靠文档流原理布局 (手机端)
- 响应式布局 pc上固定 手机上不固定
布局思路
- 从大到小,先定下大局,然后完善每个部分的小布局
- 从小到大,先完成小布局,然后组成大布局。
如何决定使用何种布局
再决定用何种布局时要根据两点 1.是否兼容IE9 和 2.是否兼容最新浏览器 下面给出图
-
float布局:当需要兼容IE浏览器时使用
-
flex布局:可以简便、完整、响应式地实现各种页面布局
-
grid布局:最强大的布局
必要时可以使用负margin来布局,这里做个提醒
float布局(IE)
重要步骤:
- 子元素上加
float:left和width - 父元素上加
.clearfix
.clearfix:after{
content:'';
display:block;
clear:both;
}
tips
- 最后一个标签不设
width,可以加max-width: 100%; - 不用做响应式
- IE6/7存在双倍margin bug 解决办法:加
display:inline-block - 若发现图片下面有多余的背景色,加
vertical-align:top或vertical-align:middle - 让元素居中:加
margin-left:auto和margin-right:auto这样不会占用其他margin - 若要做平均图层,在父级元素加上X(加.clearfix),再用负margin,例如
margin-right= -5px
flex布局
采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器";它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。
容器(container)属性
flex-directionflex-wrapflex-flowjustify-contentalign-itemsalign-content
让一个元素变成容器
.container{
display: flex;
}
或
.container{
display: inline-flex;
}
flex-direction:属性决定主轴的方向(即项目的排列方向)。
.container{
flex-direction: row | row-reverse | column | column-reverse;
}
flex-wrap:默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。
.container{
flex-wrap: nowrap | wrap | wrap-reverse;
}
flex-flow:flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
.container {
flex-flow: <flex-direction> || <flex-wrap>;
}
justify-content:属性定义了项目在主轴上的对齐方式。
.container{
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
}
align-items:属性定义项目在交叉轴上如何对齐。
.container{
align-items: stretch | flex-start | flex-end | center | baseline;
}
align-content:属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
.container{
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
项目(item)属性
orderflex-growflex-shrinkflex-basisflexalign-self
order:属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
.item {
order: <integer>;
}
flex-grow:属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
.item {
flex-grow: <number>; /* default 0 */
}
flex-shrink:属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
.item {
flex-shrink: <number>; /* default 1 */
}
flex-basis:属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
.item {
flex-basis: <length> | auto; /* default auto */
}
flex:flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
align-self:align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
重点记住
display: flexflex-direction:row | columnflex-wrap:wrapjustify-content:center | space-betweenalign-items: center
tips
- 永远不要把
height和width写死,除非特殊说明; - 尽量用
min-width|max-width|min-width|max-height - flex布局基本可以满足所有需求
- flex布局与
margin-xxx:auto配合有意外效果
Grid布局
网格布局(Grid)是最强大的 CSS 布局方案。
容器和项目
采用网格布局的区域,称为"容器"(container)。容器内部采用网格定位的子元素,称为"项目"(item)。
行和列
容器里面的水平区域称为"行"(row),垂直区域称为"列"(column)。
上图中,水平的深色区域就是"行",垂直的深色区域就是"列"。
单元格
行和列的交叉区域,称为"单元格"(cell)。
正常情况下,n行和m列会产生n 乘以 m个单元格。比如,3行3列会产生9个单元格。
网格线
划分网格的线,称为"网格线"(grid line)。水平网格线划分出行,垂直网格线划分出列。
正常情况下,n行有n + 1根水平网格线,m列有m + 1根垂直网格线,比如三行就有四根水平网格线。
容器(container)属性
displaygrid-template-columns|grid-template-rowsgrid-row-gap|grid-column-gap|grid-gapgrid-template-areas- ...
display: display: grid指定一个容器采用网格布局。
div {
display: grid;
}
grid-template-columns | grid-template-rows容器指定了网格布局以后,接着就要划分行和列。grid-template-columns属性定义每一列的列宽,grid-template-rows属性定义每一行的行高。
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
}
为了方便表示比例关系,网格布局提供了fr关键字(fraction 的缩写,意为"片段")。如果两列的宽度分别为1fr和2fr,就表示后者是前者的两倍。
.container {
display: grid;
grid-template-columns: 1fr 1fr;
}
fr可以与绝对长度的单位结合使用,这时会非常方便。
.container {
display: grid;
grid-template-columns: 150px 1fr 2fr;
}
grid-row-gap | grid-column-gap | grid-gap:grid-row-gap属性设置行与行的间隔(行间距),grid-column-gap属性设置列与列的间隔(列间距)。grid-gap属性是grid-column-gap和grid-row-gap的合并简写形式。
.container {
grid-row-gap: 20px;
grid-column-gap: 20px;
}
等于
.container {
grid-gap: 20px 20px;
}
grid-template-areas:网格布局允许指定"区域"(area),一个区域由单个或多个单元格组成。grid-template-areas属性用于定义区域。示例:
.item-a{
grid-area:header;
}
.item-b{
grid-area:main;
}
.item-c{
grid-area:sidebar;
}
.item-d{
grid-area:footer;
}
.container{
display:grid;
grid-template-columns:50px 50px 50px 50px;
grid-template-rows:auto;
grid-template-areas:"header header header header"
"main main . sidebar"
"footer footer footer footer"
}
便会造出如下图所示的布局
grid属性更多资料来源于CSS Grid 网格布局教程-作者阮一峰
5.CSS定位(Position)
布局是屏幕平面上的 定位是垂直于屏幕的
盒模型定位
背景范围是border外边沿围成的区域
一个div的分层
position的属性
static默认值,待在文档流里relative相对定位,元素会升起来,但不脱离文档流absolute绝对定位,定位基准是祖先里的非static元素fixed固定定位,定位基准是viewport(浏览器窗口)sticky粘滞定位
tips
- 如果写了
absolute,一般都要补一个relatvie(有绝对就有相对) - 如果写了
absolute或fixed,一定要补top和left sticky兼容性很差,很少用position:relative可配合z-index使用,很少用
关于z-index
z-index 属性设定了一个定位元素及其后代元素或 flex 项目的 z-order。 当元素之间重叠的时候, z-index 较大的元素会覆盖较小的元素在上层进行显示。取值为整数。
z-index:auto不会创建新的层叠上下文
作用:
- 用于做位移(少用)
- 用于给absolute做父元素
position: static
static是position属性的默认值。如果省略position属性,浏览器就认为该元素是static定位。
这时,浏览器会按照源码的顺序,决定每个元素的位置,这称为"正常的页面流"(normal flow)。每个块级元素占据自己的区块(block),元素与元素之间不产生重叠,这个位置就是元素的默认位置。
position: relative
relative相对定位表示,相对于默认位置(即static时的位置)进行偏移,即定位基点是元素的默认位置。
它必须搭配top、bottom、left、right这四个属性一起使用,用来指定偏移的方向和距离。
div {
position: relative;
top: 20px;
}
上面代码中,div元素从默认位置向下偏移20px(即距离顶部20px)。
position: absolute
absolute绝对定位表示,相对于上级元素(一般是父元素)进行偏移,即定位基点是父元素。
它有一个重要的限制条件:定位基点(一般是父元素)不能是static定位,否则定位基点就会变成整个网页的根元素html。另外,absolute定位也必须搭配top、bottom、left、right这四个属性一起使用。
使用场景:脱离原来位置,另起一层(比如对话框的关闭按钮或者是鼠标提示)
配合z-index使用
/*
HTML 代码如下
<div id="father">
<div id="son"></div>
</div>
*/
#father {
positon: relative;
}
#son {
position: absolute;
top: 20px;
}
上面代码中,父元素是relative定位,子元素是absolute定位,所以子元素的定位基点是父元素,相对于父元素的顶部向下偏移20px。如果父元素是static定位,上例的子元素就是距离网页的顶部向下偏移20px。
tips
- 某些浏览器上如果不写
top/left会位置错乱 - 善用
left: 100%以及left:50%加负margin absolute是相对于祖先元素中最近的一个定位元素
position: fixed
fixed固定定位表示,相对于视口(viewport,浏览器窗口)进行偏移,即定位基点是浏览器窗口。这会导致元素的位置不随页面滚动而变化,好像固定在网页上一样。
它如果搭配top、bottom、left、right这四个属性一起使用,表示元素的初始位置是基于视口计算的,否则初始位置就是元素的默认位置。
使用场景:烦人的广告/回到顶部的按钮,配合z-index使用
div {
position: fixed;
top: 0;
}
上面代码中,div元素始终在视口顶部,不随网页滚动而变化。
tips:手机上尽量不用,坑很多
position: sticky
sticky粘滞定位跟前面四个属性值都不一样,它会产生动态效果,很像relative和fixed的结合:一些时候是relative定位(定位基点是自身默认位置),另一些时候自动变成fixed定位(定位基点是视口)。
因此,它能够形成"动态固定"的效果。比如,网页的搜索工具栏,初始加载时在自己的默认位置(relative定位)。
层叠上下文(堆叠上下文)
- 使用了
position属性以后,会超越内联子元素,成为定位元素。 - 每个层叠上下文就是一个新的小世界(作用域)
- 这个小世界里面的
z-index跟外界无关,处在同一个小世界的z-index才能比较 background只影响背景色,opacity影响所有元素的透明度(包括文字等)- 不正交属性可创建层叠上下文:
z-index|flex|opacity|transform - 负index逃不出小世界
6.CSS动画(Animation)
动画是由许多静止的画面(也称“帧”)以一定的速度(如每秒30张)连续播放时肉眼因视觉残象产生错觉而误以为是活动的画面。
在CSS中,最简单的例子是div从左往右移动
- 原理:每过一段时间用计时器(js中的
setInterval)将div移动,直到移到目标地点。 - 老手用
transform:translateX()以及transition过渡,比上面的好。
浏览器渲染原理
参考文章
浏览器渲染过程
- 根据HTML构建HTML树(DOM)
- 根据CSS构建CSS树(CSSOM)
- 将两棵树合并成一棵渲染树(render tree)
- Layout布局(文档流、盒模型、计算大小和位置)
- Paint绘制(把边框颜色、文字颜色、阴影等画出来)
- Compose合成(根据层叠关系展示画面)
具体过程如图所示
浏览器如何更新样式
一般用js来更新样式
- JS/CSS>样式>布局>绘制>合成
- JS/CSS>样式>绘制>合成(改变背景颜色,直接repaint和composite)
- JS/CSS>样式>合成(改变transform,只需composite) 注意必须全屏查看效果,在开发者工具里的iframe查看问题(报错)
CSS动画优化
- JS优化:使用
requestAnimationFrame代替setTimeout或setInterval - CSS优化:使用
will-change或translate
transform属性
translate位移scale缩放rotate旋转skew倾斜
tips
- 一般都需要配合transition过渡
- inline元素不支持transform,需要先变成block元素
translate位移
常用写法:
transform: translateX(<length | percentage>)transform: translateY(<length | percentage>)transform: translate(<length | percentage>,<length | percentage>)transform: translate(<length>)且父容器perspectivetransform: trabslate3d(x,y,z)
tips
- 要学会看懂MDN语法示例
translate(-50%,-50%)可做绝对定位元素的居中
scale缩放
常用写法
transform: scaleX(<number>)transform: scaleY(<number>)transform: scale(<number>,<number>)tips- 用得比较少,会使内容变模糊
rotate 旋转
常用写法
transform: rotate([<angle> | <zero>])transform: rotateZ([<angle> | <zero>])transform: rotateX([<angle> | <zero>])transform: rotateY([<angle> | <zero>])tips- 一般用于360度旋转制作loading
skew倾斜
常用写法
transform: skewX([<angle> | <zero>])transform: skewY([<angle> | <zero>])transform: skew([<angle> | <zero>],[<angle> | <zero>])tips- 用得少,用得到的时候查阅MDN文档
多重效果(组合使用)
例如transform: scale(0.5) translate(-100%, -100%);或transform:none
tips
- CSS需要有想象力,而不是逻辑
- CSS给出的属性很简单,但可以组合得很复杂
transition过渡
作用:补充中间帧
语法:
transition:属性名,时长,过渡方式,延迟transition:all
过渡方式:linear|ease|ease-in|ease-out|ease-in-out|cubic-beizer|step-start|step-end|steps
tips:
- 并不是所有属性都能过渡
display: none变成display: block或反过来不能过渡- 若要有淡入或淡出的过渡效果一般写
visibility:hidden与visibility:visible - background颜色可以过渡
- opacity透明度可以过渡
- 过渡必须要有起始,若有中间变化,可以使用两种方法
- 使用两次transform
.a===transform===>.b
.b===transform===>.c
然后用setTimeout或者监听transitionend事件
- 使用animation
需要声明关键帧(keyframes),添加动画;若需要动画停在最后一帧,在后面加
forwards
@keyframes完整语法
一种是frmo...to...(从...到...) 另一种是百分数
@keyframes slidein {
from {
transform: translateX(0%);
}
to {
transform: translateX(100%);
}
}
或
@keyframes identifier{
0%{top:0; left:0;}
30%{top:50px};
68%,72%{left:50px;}
100%{top:100px;left:100px;}
}
animation缩写语法
animation: 时长|过渡方式|延迟|次数|方向|填充模式|是否暂停|动画名
- 时长:1s或者1000ms
- 过渡方式:跟transition取值一样,如linear
- 次数:正整数或infinite(无限)
- 方向:reverse|alternate|alternate-reverse
- 填充模式:none|forwards|backwards|both
- 是否暂停:pasued|running 以上属性都有对应的单独属性
小白学习经验分享,若有错误或缺漏,请私信指正,不胜感激