CSS总结

124 阅读8分钟

CSS的厉害之处

CSS的厉害之处在于层叠样式表 ,其中包括

  • 样式层叠:可以多次对同一选择器选择样式声明
  • 选择器层叠:可以用不同选择器对同一个元素声明样式
  • 文件层叠:可以用多个文件层叠

CSS的版本

CSS2是最广泛使用的版本,兼容一切IE, CSS3是现代使用的版本,之后就分模块升级

caniuse.com查询兼容性

可以在caniuse 上查询CSS样式的在不同浏览器的兼容性

CSS语法

语法一:

选择器 {

属性名:属性值;

/*注释*/

}

例子:

p {
 color: red;
}

注意:

  1. 所有符号都是英语符号

  2. 区分大小写

  3. 任何地方写错了,浏览器不会报错,会直接忽略

  4. 需要写分号

语法二:@语法

@charset "UTF-8";  /*必须放在第一行, 而且要加分号*/
@import url(2.css);
@media (min-width: 100px) and (max-width: 200px) {
	语法一
}

CSS的文档流

文档流

文档流是指HTML元素的流动方向

  • inline 元素从左到右,到最右边会换行,如果最右边长度不够一个Inline元素,会自动切割为两半,一半在这一行,一半在下一行, 即会跨越两行
  • Block元素的流动方向是从上到下,每一个都另起一行
  • inline-block元素从左到右,但不会跨越两行

宽度

  1. inline元素的宽度是内部inline元素宽度的和,不能用width指定
  2. block元素默认自动计算宽度 (width: auto) ,即能占多宽就占多宽,可用width指定
    1. block元素的默认宽度不是100%,不是100%, 不是100%
    2. 永远不要对Block元素写 width: 100%;
  1. inline-block默认宽度是内部inline元素宽度之和,可以用width指定宽度

inline元素是尽可能窄,block元素是尽可能宽

高度

  1. inline元素的高度是由line-height间接 确定(大部分情况下,Inline元素和Line-height一样,但如果字体不一样,会有细微的区别,比如差1-2px),和height无关

  2. block元素的高度是由内部文档流元素决定的,可以设Height

  3. inline-block元素和Block元素一样

一个空的div的高度是0

一个空的span元素的高度不是0,因为span元素的高度是line-height决定的

问题是,如果我设置的高度小于内容元素的高度怎么办?

这就是溢出

溢出

overflow: hidden: 隐藏溢出内容

overflow: scroll: 显示滚动条,但问题是,如果内容宽度和高度没有溢出,也会有滚动条

Overflow: auto: 灵活地显示滚动条,只有在需要的时候才会出现滚动条

脱离文档流

回忆一下div的高度:

block元素的高度是由内部文档流元素决定的, 这就意味着,如果元素脱离了文档流,block元素就不会计算它的高度。

有两种方式可以脱离文档流:

  • position: absolute
  • float: left

两种盒模型

  1. content-box 内容盒: 宽度只是内容的宽度
  2. 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…

总结:

  1. overflow:hidden解决margin合并
  2. parent div 表示parent下的所有div
  3. parent>div parent下的第一个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用法总结:

  1. 用grid-template-areas 设计大致的布局
    1. 示例:
 grid-template-areas:
    "big mid1"
    "big mid2"
    "sm1 mid2"
    "sm2 mid3"
    "sm3 mid3"
  1. 用**grid-template-rowsgrid-template-columns**指定每一行每一列的高度和宽度
    1. 示例:
      1. grid-template-rows: 240px repeat(4, 120px);
      2. grid-template-columns: 250px 250px;
  1. 对于每一个小块,用grid-areagrid-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如果你写了 absolutefixed ,一定要补 topleft 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动画渲染

浏览器渲染过程

  1. 浏览器渲染过程步骤根据 HTML 构建 HTML 树( DOM )
  2. 根据 CSS 构建 CSS 树( CSSOM )将两棵树合并成一颗渲染树( render tree )
  3. Layout 布局(文档流、盒模型、计算大小和位置)
  4. 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>