# CSS 基础

# 盒子模型

  • 用 box-sizing 设置盒子模型

    • 标准盒子模型:box-sizing: content-box

    • 怪异盒子模型:box-sizing: border-box

  • 标准盒子模型

    • 如果没有特别说明元素默认为标准盒子模型
    • 标准盒子模型的宽高为 content-height / width + 2 _ padding-height / width + 2 _ border-height / width
  • 怪异盒子模型

    • 怪异盒子模型的宽高为 content-height / width
    • 如果给定的设计稿严格要求了元素的宽高的时候用怪异盒子模型布局时设置 padding 和 border 会比较方便

# 元素的隐藏

  1. display: none
    • 将元素设置为不可见且该元素不会占位但在 dom 树中依然是存在的
    • 在 vue 中的 v-show 控制显示隐藏就是采用的这种形式
      • 补充说明 vue 中 v-if 的显示隐藏并不是从 css 层面去实现的,而是直接对 dom 树的节点进行增删来操作的,所以在 vue 中 v-if 的使用性能消耗会比 v-show 大很多(这里的二者都会触发元素的重排但是对于 vue 来说 dom 的销毁和创建会涉及一次内容的重新编译和生成,所以在性能的消耗上要比 v-show 大)
  2. visibility :hidden
    • 同样也是设置元素不可见但元素仍旧会以原本的宽高占据位置
    • 该属性可继承。即当父元素的 visibility 设置为 hidden 时,你仍可以设置子元素的 visibility 为 visible 使其可见,这是其他两种隐藏方式所做不到的
  3. opacity:0
    • 设置元素的透明度为 0,意为元素为全透明同样也会占据原本的宽高

# flex 布局

# flex: 1 的含义

  • flex: 1 包含三个属性,分别是 flex-grow、flex-shrink、flex-basis
flex 取值 flex-grow flex-shrink flex-basis
none 0 0 auto
auto 1 1 auto
1 1 1 0%
大于 0 的数字 n n 1 0%
  • 所以一般我们使用 flex: n 的时候都是指对 flex-grow 的设置

# flex-grow

  • flex-grow 表示的是子元素分配父元素的剩余空间

    <div class="father">
      <div class="children" />
      <div class="children" />
      <div class="children" />
    </div>
    
    .father: { display:flex; width:300px; } .children: { flex: 1 }
    

    1)计算要分配的剩余空间

    要分配的剩余空间(因为子元素没有宽度所以父元素的宽度就是全部的剩余空间)
     = 剩余空间 * ( 所有项目的flex-grow之和 >= 1 ? 1 : 所有项目的flex-grow之和 )
     = 300px * (3 >= 1 ? 1 : 3)
     = 300px * 1
     = 300px
    

    2)计算每个子元素分配到的剩余空间

    每个子元素分配的剩余空间
     = 要分配的剩余空间 * ( 单个项目flex-grow / 所有子元素的flex-grow之和 )
     = 300px * ( 1 / 3)
     = 100px
    
  • 以上的计算公式不需要太过记住,平时调试只需要知道 flex-grow: n 是对父元素剩余空间的索取,当 n 的值越大时索取的就越多但总量不会超过父元素的全部剩余空间,一般我们用的最多的也是这一条

# flex-shrink

  • 该属性用来设置,当父元素的宽度小于所有子元素的宽度的和时(即子元素会超出父元素),子元素如何缩小自己的宽度的。 flex-shrink 的默认值为 1,当父元素的宽度小于所有子元素的宽度的和时,子元素的宽度会减小。值越大,减小的越厉害。如果值为 0,表示不减小。

  • 设置这个属性可以在 flex 布局的时候防止溢出

    <div class="father">
      <div class="children1" />
      <div class="children2" />
      <div class="children3" />
    </div>
    
    .father: { display:flex; width:300px; } .children1: { width:200px;
    height:200px; flex-shrink:2 } .children2: { width:200px; height:200px;
    flex-shrink:1 } .children1: { width:200px; height:200px; flex-shrink:3 }
    
  • 根据上述例子套入 flex-shrink 计算公式中 当 flex-shrink 为 n 时

    缩小之后的宽度(children1)
    = 溢出父元素总宽度 * (元素本身宽度 * n / (子元素宽度 * 自身的n)的和
    = (200 * 3 - 300 ) * ((200 * 2) / (200 * 2 + 200 * 1 + 200 * 3) )
    = 300 * (400 / 1200)
    = 100
    所以 children1 缩放之后是100px
    同理可得出 children2 为 50px
    		 children3 为 150px
    
  • 该属性值对于统一设置该属性的元素而言只能起到防止溢出并缩小的作用

# flex-basis

  • 意思是指元素的主题部分

  • 该属性可以用来设置元素的宽度,可以使用 px 等作为单位进行设置

  • 当该属性与 width 同时存在时以该属性优先(即 flex-basis 会覆盖 width)

  • 可以将其理解为就是元素的宽(在与 flex-grow 合用时剩余空间会减去这一部分)

    <div class="father">
      <div class="children" />
      <div class="children" />
      <div class="children" />
    </div>
    
    .father: { display:flex; } .children: { width:200px; flex-basis:300px;
    height:200px; flex-shrink:2 } 此时children的宽应为300px
    

# flex 布局的坑

# 主轴布局和交叉轴布局 justify-content / align-items

<div class="outside">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>
<style>
     * {
  	box-sizing:border-box;
  }
     .outside {
         display:flex;
         justify-content:center;
         align-items:center;
         width:500px;
         height:400px;
         padding:10px;
         overflow:auto;
         background:red;
     }
     .item{
         width:200px;
         height:200px;
         margin:10px;
         background:green;
     }
</style>
  • 如上代码所示,当子级元素的宽度之和大于父级元素的时候,此时子级元素的 flex-shrink 如果没有设置的话默认就会为 1,那么在此情况下我们所见到的子元素就会被缩放。

image-20220727153727527

  • 但如果我们的子元素是某系图片的时候我们希望保证原有的尺寸不进行缩放,此时我们可以把子元素的 flex-shrink 设为 0,那么子元素的确不会被缩小而是保持原有的大小

image-20220727154540071

  • 然后我们会发现新的问题,即我们设置了水平居中所以元素在父级中的起始是从所有子元素的中间开始的,即使此时父元素设置了 overflow: auto,当我们拖动滚动条的时候也只能看见后面的元素,即前面一半的元素被遮挡了。所以当子元素的总宽度之和超出父元素而此时又不想让子元素缩小的话,就不要设置 justify-content:center,因为在这种状态下的居中不仅没有意义还会丢失部分元素。

    比较容易出现这个问题的是当我们想让元素居中且设置元素是纵向排列的时候(flex-direction:column),如果此时设置的是 justify-content:center 那就会导致前半部分元素的丢失,正确的居中应该是只设置 align-items: center(因为 justify-content 设置的是主轴的元素排列方式,而 flex-direction:column 是把主轴给变成了纵向所以这里的排列不需要设置主轴对齐方式为居中否则会丢失元素)

  • 同样的 bug 在交叉轴设置的时候同样也会产生,比如

    <div class="outside">
      <div class="inside">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div></div>
        <style>
             * {
          	box-sizing:border-box;
          }
             .outside {
                 display:flex;
                 justify-content:center;
                 align-items:center;
                 width:500px;
                 height:400px;
                 padding:10px;
                 overflow:auto;
                 background:red;
             }
             .inside {
                 width 100%
                 overflow auto
             }
             .item{
                 width:200px;
                 height:200px;
                 margin:10px;
                 background:green;
             }
        </style>
      </div>
    </div>
    
    • 如上代码中当我们对最外层设置了 align-items: center 时,此时如果我们不设置第二层的高度而是希望用 inside 的子元素将它的高度撑开那么就会出现子元素(item)的排列从中间开始只能看见半部分而上半部分丢失的情况。此时设置 inside 的 margin: auto 可以解决
  • 在画页面的时候我们很容易将一个最外层的元素使用 flex 布局去使其子元素居中,但是当我们需要不同的子元素之间切换的时候很容易因为滥用这两项居中而出现一些元素的丢失,所以一定要慎用。

# 过渡动画 transition

  • transition 是 css 中最简单的动画
  • transition 有四个属性值,分别是 transition-property、transition-duration、transition-timing-function、transition-delay

# transition-property

  • 设置需要执行过渡的属性

  • 多个属性之间用“,”隔开

  • 大部分属性都支持过渡效果,但是过渡生效的前提必须是从一个有效值向另一个有效值转变

  • 此项可以设置为 all,表示所有有效属性都会执行过渡效果(前提是都有有效值的转变否则不执行)

    .transition {
            margin-top 10px
            height 300px
            width 200px
            background red
            transition all 1s ease-in
        }
    .transition:hover {
            width 500px
        }
    // 当将鼠标放在transition元素上时,它的宽度就会在1s内以ease-in的方式产生变化,这里虽然设置了all,但是过渡后的有效属性仅有宽度,所以就只会有宽度发生变化。
    // 当然这里也可以用js的方式通过改变类名或添加属性的方式来用更多的交互去产生过渡动画
    

# transition-duration

  • 指定过渡效果的持续时间(单位是 s 和 ms)

# transition-timing-function

  • 指定过渡的执行方式(不同的过渡动画)

  • 可选值:

    ease 默认值,慢速开始,先加速,再减速

    linear 匀速运动

    ease-in 加速运动

    ease-out 减速运动

    ease-in-out 先加速 后减速

    cubic-bezier() 来制定时序函数(贝塞尔曲线)

    steps() 分步执行过渡效果

    • 第一个参数表示分几步

    • 第二个参数:

      start 在时间开始时就执行过渡

      end 在时间结束时执行过渡(默认值)

# transition-delay

  • 过渡效果的延迟,等待一段时间后再产生过渡效果(单位是 s 和 ms)

# 变幻 transform

  • transform 支持一些 css 中的变幻(旋转、位移、缩放等)

  • 不同于 transition,transform 是本身的变化而不是两个有效状态之间的过渡

  • 当一个元素被设置了 transform 之后,它的层级会被提升。比如我们在 css 中的 position:fixed; 原本是依照浏览器来进行定位的,当它的祖级元素中有某一个元素被设置了 transform 之后,那么其定位也会被依照被设置了 transform 的那一级元素来进行定位

  • scale(x,y) 定义 2D 缩放,传参表示的是缩放的倍数,1 表示不变,大于 1 是放大,小于 1 是缩小;如果只传一个参数表示 x,y 为同一个值,

# transform-origin

  • 这个属性表示 css3 动画在执行的过程中是围绕着某一个点进行的(例如位移、旋转等)。

  • 属性值可以是百分比、em、px 等具体的值,也可以是 top、right、bottom、left 和 center 这样的关键词

    transform-origin: x-axis y-axis z-axis;
    /*它们的默认值分别是 50% 50% 0*/
    
  • 所以当我们不设置该项属性的时候默认是依照元素的中心点进行变幻的

# filter

# filter: blur(px)

  • 给图像设置高斯模糊。"radius"一值设定高斯函数的标准差,或者是屏幕上以多少像素融在一起, 所以值越大越模糊,如果没有设定值,则默认是 0;这个参数可设置 css 长度值,但不接受百分比值。