CSS的厉害之处
CSS的厉害之处在于层叠样式表 ,其中包括
- 样式层叠:可以多次对同一选择器选择样式声明
- 选择器层叠:可以用不同选择器对同一个元素声明样式
- 文件层叠:可以用多个文件层叠
CSS的版本
CSS2是最广泛使用的版本,兼容一切IE, CSS3是现代使用的版本,之后就分模块升级
caniuse.com查询兼容性
可以在caniuse 上查询CSS样式的在不同浏览器的兼容性
CSS语法
语法一:
选择器 {
属性名:属性值;
/*注释*/
}
例子:
p {
color: red;
}
注意:
-
所有符号都是英语符号
-
区分大小写
-
任何地方写错了,浏览器不会报错,会直接忽略
-
需要写分号
语法二:@语法
@charset "UTF-8"; /*必须放在第一行, 而且要加分号*/
@import url(2.css);
@media (min-width: 100px) and (max-width: 200px) {
语法一
}
CSS的文档流
文档流
文档流是指HTML元素的流动方向
- inline 元素从左到右,到最右边会换行,如果最右边长度不够一个Inline元素,会自动切割为两半,一半在这一行,一半在下一行, 即会跨越两行
- Block元素的流动方向是从上到下,每一个都另起一行
- inline-block元素从左到右,但不会跨越两行
宽度
- inline元素的宽度是内部inline元素宽度的和,不能用width指定
- block元素默认自动计算宽度 (width: auto) ,即能占多宽就占多宽,可用width指定
-
- block元素的默认宽度不是100%,不是100%, 不是100%
- 永远不要对Block元素写 width: 100%;
-
inline-block默认宽度是内部inline元素宽度之和,可以用width指定宽度
inline元素是尽可能窄,block元素是尽可能宽
高度
-
inline元素的高度是由line-height间接 确定(大部分情况下,Inline元素和Line-height一样,但如果字体不一样,会有细微的区别,比如差1-2px),和height无关
-
block元素的高度是由内部文档流元素决定的,可以设Height
-
inline-block元素和Block元素一样
一个空的div的高度是0
一个空的span元素的高度不是0,因为span元素的高度是line-height决定的
问题是,如果我设置的高度小于内容元素的高度怎么办?
这就是溢出
溢出
overflow: hidden: 隐藏溢出内容
overflow: scroll: 显示滚动条,但问题是,如果内容宽度和高度没有溢出,也会有滚动条
Overflow: auto: 灵活地显示滚动条,只有在需要的时候才会出现滚动条
脱离文档流
回忆一下div的高度:
block元素的高度是由内部文档流元素决定的, 这就意味着,如果元素脱离了文档流,block元素就不会计算它的高度。
有两种方式可以脱离文档流:
- position: absolute
- float: left
两种盒模型
content-box内容盒: 宽度只是内容的宽度border-box边框盒: 宽度包括内容+padding+border的宽度
举例来说,如果写以下代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
.content-box {
margin:25px;
border: 5px solid red;
padding: 10px;
box-sizing: content-box;
width: 100px;
}
.border-box {
margin:25px;
border: 5px solid red;
padding: 10px;
box-sizing: border-box;
width:100px;
}
</style>
</head>
<body>
<div class="content-box">
内容盒
</div>
<div class="border-box">
边框盒
</div>
</body>
</html>
虽然都设置了相同的宽度为100Px,但可以看到两种盒模型的宽度是不同的
内容盒的盒模型:只有内容宽度是100px,
边框盒的盒模型:padding + border + content = 100px
border-box更好用
请简述 CSS 盒模型是什么
参考答案
CSS 盒模型有两种,一种是 content-box 一种是 border-box。
content-box 的宽度 width 表示内容区的宽度,不包含 padding 和 border;
border-box 的宽度 width 表示内容区 + padding + border 的总和。
一般优先使用后者。
Margin合并
兄弟合并
第一个div的Margin-bottom (下外边距)会和第二个div的margin-top(上外边距)合并
父子合并
parent的上边距会和第一个孩子的上边距重合,parent的下边距会和最后一个孩子的下边距重合
这种margin合并只存在与上下外边距,左右外边距不会合并
取消Margin 合并
对于兄弟合并:用display:inline-block
对于父子合并:
- 第一种方法是给parent加
Border - 第二种方法是给parent加
Padding
margin能合并就是因为父子的Margin之间没有其他的东西,如果加了border或者Padding就等于在父子的Margin中间加了东西,因此就无法合并margin了
- 第三种方式是给parent加
overflow:hidden
基本单位
- 长度单位
- px
- em 相对自身font-size的倍数
应用:画一个彩虹
yue2167.github.io/css-rainbow…
总结:
- 用
overflow:hidden解决margin合并 parent div表示parent下的所有divparent>divparent下的第一个div
float布局
步骤:
- 子元素上加
float:left, 和width - 父元素加上 .clearfix
-
- 父元素加上class: class="clearfix"
- .clearfix的写法:
.clearfix::after {
content:'';
display:block;
clear:both;
}
一些经验:
- 最后一个子元素不设置width, 或者设置
max-width - img 设置Max-width
- 如果图片下面有多余的空白,就在图片上写上
vertical-align: top或者middle - 如果border干扰了布局,可以用
outline: 1px solid red, outline不占用位置 - 固定元素的块级元素居中的方法:写上**
margin-left: auto; margin-right: auto; - 平均布局的关键点:负
Margin
flex布局
container属性
flex-direction
flex-direction: row(水平布局)/column(垂直布局)
flex-wrap
flex-wrap: wrap(自动换行)/nowrap
justify-content
space-between center
align-items
align-items: stretch; 即使内容高度不一样,也让item的高度一样
item属性
- order: 默认是0
-
- 按照order从小到大的顺序排
- 负数、0、正数
flex-grow控制如何长胖
-
- 使用技巧:三栏布局时,两边的不设置,中间的设置flex-grow:1.
flex-shrink控制如何变瘦
多余空间的分配
Grid布局
grid-template-columns: 40px 50px auto 50px 40px;
grid-template-rows: 60px 400px 200px;
表示5列3行
.container{
display: grid;
grid-template-columns: 40px 50px auto 50px 40px ;
grid-template-rows: 100px 300px 10px ;
}
.a,.b,.c{
border: 1px solid green;
}
.a{
grid-row-start: 1;
grid-row-end: 2;
grid-column-start: 1;
grid-column-end: 6;
}
.b{
grid-column-start: 1;
grid-column-end: 3;
}
.c{
grid-row-start: 2;
grid-row-end: 3;
grid-column-start: 3;
grid-column-end: 4;
}
fr的用法:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./reset.css">
<style>
.container{
display: grid;
border: 1px solid red;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
width: 800px;
grid-gap: 12px;
/*grid-gap可以设置每个空格之间间距,此时不需要负margin来调节 */
}
.container>div{
border: 1px solid black;
}
.image{
width: 191px;
height: 191px;
background-color: grey;
}
</style>
</head>
<body>
<div class="container">
<div class="image"></div>
<div class="image"></div>
<div class="image"></div>
<div class="image"></div>
<div class="image"></div>
<div class="image"></div>
</div>
</body>
</html>
效果预览:
grid用法总结:
- 用grid-template-areas 设计大致的布局
-
- 示例:
grid-template-areas:
"big mid1"
"big mid2"
"sm1 mid2"
"sm2 mid3"
"sm3 mid3"
- 用**
grid-template-rows和grid-template-columns**指定每一行每一列的高度和宽度
-
- 示例:
-
-
grid-template-rows:240px repeat(4, 120px);grid-template-columns: 250px 250px;
-
- 对于每一个小块,用
grid-area和grid-template-areas里布局的字符串对应
示例:
.demo > .image:first-child{
grid-area: big;
border: 1px solid red;
}
grid尤其适合用来做不规则布局
div的分层
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.demo{
background-color: rgb(120,184,211);
width: 200px;
height: 200px;
border: 15px solid rgba(255, 0, 0, .2);
padding: 10px;
}
.childDiv{
background-color: #fff;
height: 50px;
color:red;
margin-top: -10px;
}
.float{
float:left;
background-color:green;
height: 50px;
width: 50px;
color: red;
}
</style>
</head>
<body>
<div class="demo">
文字内容
<div class="float"></div>
<div class="childDiv"></div>
</div>
</body>
</html>
position
static 默认值,待在文档流里
relative 相对定位,升起来,但不脱离文档流
absolute 绝对定位,定位基准是祖先里的非 static fixed 固定定位,定位基准是 viewport (有诈) sticky 粘滞定位,不好描述直接举例
如果你写了 absolute ,一般都得补一个relative如果你写了 absolute 或 fixed ,一定要补 top 和left sticky 兼容性很差
文字不换行:white-space:no-wray;
层叠上下文
文档中的层叠上下文由满足以下任意一个条件的元素形成:
- 文档根元素();
- position 值为 absolute(绝对定位)或 relative(相对定位)且 z-index 值不为 auto 的元素;
- position 值为 fixed(固定定位)或 sticky(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持);
- flex (flex) 容器的子元素,且 z-index 值不为 auto;
- grid (grid) 容器的子元素,且 z-index 值不为 auto;
- opacity 属性值小于 1 的元素(参见 the specification for opacity);
- mix-blend-mode 属性值不为 normal 的元素;
- 以下任意属性值不为 none 的元素:
- isolation 属性值为 isolate 的元素;
- will-change 值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素(参考这篇文章);
- contain 属性值为 layout、paint 或包含它们其中之一的合成值(比如 contain: strict、contain: content)的元素。
在层叠上下文中,子元素同样也按照上面解释的规则进行层叠。重要的是,其子级层叠上下文的 z-index 值只在父级中才有意义。子级层叠上下文被自动视为父级层叠上下文的一个独立单元。
CSS动画渲染
浏览器渲染过程
- 浏览器渲染过程步骤根据 HTML 构建 HTML 树( DOM )
- 根据 CSS 构建 CSS 树( CSSOM )将两棵树合并成一颗渲染树( render tree )
- Layout 布局(文档流、盒模型、计算大小和位置)
- Paint 绘制(把边框颜色、文字颜色、阴影等画出来) composite 合成(根据层叠关系展示画面)
csstriggers.com/这个里面可以知道 每个属性触发哪些流程
transform
translate平移
利用translate设置绝对定位元素居中
scale 缩放
#demo:hover{
transform: scale(1.5);
transform: scaleX(1.5);
transform: scaleY(1.5);
transform: scaleZ(1.5);
}
rotate旋转
#demo:hover{
transform: rotate(45deg);
transform: rotateX(45deg);
transform: rotateY(45deg);
}
skew偏离
transform: skew(15deg);
transform: skewX(15deg);
transform: skewY(15deg);
transition 过渡
用transform做一个跳动的心
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{padding: 0;margin: 0;box-sizing: border-box;}
#heart{
margin: 220px;
position: relative;
display: inline-block;
transition: all .5;
}
#heart:hover{
transform: scale(1.5);
}
#heart>.bottom{
width: 50px;
height: 50px;
transform: rotate(45deg);
background-color: red;
}
#heart>.left{
width: 50px;
height: 50px;
background-color: red;
position: absolute;
bottom: 100%;
right: 100%;
border-radius: 50% 0 0 50%;
transform: rotate(45deg) translateX(31px);
}
#heart>.right{
width: 50px;
height: 50px;
background-color: red;
position: absolute;
bottom: 100%;
left: 100%;
border-radius:50% 50% 0 0;
transform: rotate(45deg) translateY(31px);
}
</style>
</head>
<body>
<div id="heart">
<div class="left"></div>
<div class="right"></div>
<div class="bottom"></div>
</div>
</body>
</html>
animation动画
缩写语法
animation:时长丨过渡方式延迟丨次数方向填充模式1是否暂停丨动画名;- 时长:1s或者1000ms过渡方式:跟 transition 取值一样,如 linear 次数:3或者2.4或者
infinite方向: reverse alternate alternate - reverse- 填充模式: none forwards backwards both
- 是否暂停: paused running
- 以上所有属性都有对应的单独属性
代码演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#demo{
width: 100px;
height: 100px;
border: 1px solid red;
margin: 50px;
}
#demo.start{
animation: xxx 1.5s ease infinite alternate forwards;
}
@keyframes xxx{
0%{
transform: none;
}
66%{
transform:translateX(200px);
}
100%{
transform: translateX(200px) translateY(200px);
}
}
</style>
</head>
<body>
<div class="wrapper">
<div id="demo"></div>
<button id="button">开始</button>
<button id="xxx">暂停</button>
<button id="yyy">恢复</button>
</div>
<script>
button.onclick=()=>{
demo.classList.add('start')
}
xxx.onclick=()=>{
demo.style.animationPlayState='paused'
}
yyy.onclick=()=>{
demo.style.animationPlayState='running'
}
</script>
</body>
</html>
用animation做一个跳动的心
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{padding: 0;margin: 0;box-sizing: border-box;}
#heart{
margin: 220px;
position: relative;
display: inline-block;
animation: heart 800ms infinite alternate linear;
}
@keyframes heart{
0%{
transform: scale(1.0);
}
100%{
transform: scale(1.2);
}
}
#heart>.bottom{
width: 50px;
height: 50px;
transform: rotate(45deg);
background-color: red;
}
#heart>.left{
width: 50px;
height: 50px;
background-color: red;
position: absolute;
bottom: 100%;
right: 100%;
border-radius: 50% 0 0 50%;
transform: rotate(45deg) translateX(31px);
}
#heart>.right{
width: 50px;
height: 50px;
background-color: red;
position: absolute;
bottom: 100%;
left: 100%;
border-radius:50% 50% 0 0;
transform: rotate(45deg) translateY(31px);
}
</style>
</head>
<body>
<div id="heart">
<div class="left"></div>
<div class="right"></div>
<div class="bottom"></div>
</div>
</body>
</html>