CSS

布局

文档流

  • 文档流(normal flow)
    • 网页是一个多层结构,最底层就是文档流
    • 页面中的元素具有两种状态:在文档流中,脱离文档流
  • 元素在文档流中的特点
    • 块元素:独占一行(垂直排列)、默认宽度为是父元素的全部、默认高度被内容(子元素)撑开。
    • 行内元素:只占自身大小(水平排列)、宽度和高度都被内容撑开。

盒子模型

  • CSS 将页面的所有元素都设置为一个矩形的盒子
  • 每个盒子包括以下部分:
    • 内容区(content)
    • 内边距(padding)
    • 边框(border)
    • 外边距(margin)
  • 元素在水平方向的布局
    • 子元素在水平方向的位置由以下属性共同决定
    • margin-left``border-left``padding-left``width``padding-right``border-right``margin-right
    • 上述所有属性值相加必须 = 父元素的 width
  • 元素在垂直方向的布局

    • 默认情况,父元素的高度被内容撑开
    • 若子元素的高度大于父元素的高度,子元素会溢出
    • 在父元素中设置 overflow处理溢出的元素


      垂直外边距的折叠问题

  • 父子元素之间的外边距,其子元素的上外边距会传递给父元素,会影响页面布局

  • 清除外边距折叠的方法
    • 在子元素中设置 display:inline-block;行内块元素
    • 在子元素中设置 float:left;开启浮动
    • 在子元素中设置 position:absolute;在父元素中设置 position:relative;开启定位


浮动

  • 浮动用于完成水平方先的布局
  • 设置 float ,可以使一个元素向其父元素的左侧或右侧移动
  • 浮动的特点
    • 浮动元素会脱离文档流,不占据文档流中位置。
    • 浮动元素不会移出父元素。
    • 元素脱离文档流后,不在区块元素、行内元素

高度塌陷问题

  • 描述:在浮动布局中,父元素的高度默认被子元素撑开,子元素浮动后,脱离文档流,导致父元素高度丢失
  • 解决方案:
  • 1、开启 BFC(块级格式化环境)

    • 设置元素的浮动(宽度也被内容撑开,未开启浮动的元素会上移。不推荐)
    • 将元素设为行内块元素 display:inline-block(宽度也被内容撑开,不适合做外部布局容器)
    • 将元素的 overflow 设置为一个非 visible 的值(推荐,auto或hidden)
      1. .outer{
      2. border: 5px solid red;
      3. float: left; /* 开启浮动 */
      4. display: inline-block; /* 设置为行内块元素 */
      5. overflow: hidden; /* 设置溢出 overflow */
      6. }
  • 2、设置 clear 属性(清除浮动)

    • 原理:浏览器会自动为元素添加一个 margin-top 来使其不受影响
      1. .box3{
      2. width: 300px;
      3. height: 300px;
      4. background-color: orange;
      5. clear: both; /* 清除其他浮动元素的影响 可选值 left、right、both */
      6. }
  • 3、使用html结构解决样式问题

    • 添加一个空标签,放在最后,并设置 clear
      1. <!DOCTYPE html>
      2. <html lang="en">
      3. <head>
      4. <style>
      5. .box1{
      6. border: 10px solid red;
      7. }
      8. .box2{
      9. width: 100px;
      10. height: 100px;
      11. background-color: #bfa;
      12. float: left;
      13. }
      14. /* 清除浮动 */
      15. .helper{
      16. clear: both;
      17. }
      18. </style>
      19. </head>
      20. <body>
      21. <div class="box1">
      22. <div class="box2"></div>
      23. <!-- 增加一个空标签 -->
      24. <div class="helper"></div>
      25. </div>
      26. </body>
      27. </html>
  • 4、使用伪类元素 ::after

    • 内容 content 为空,设 dispaly 为块元素,并设置 clear
      1. <!DOCTYPE html>
      2. <html lang="en">
      3. <head>
      4. <style>
      5. .box1{
      6. border: 10px solid red;
      7. }
      8. .box2{
      9. width: 100px;
      10. height: 100px;
      11. background-color: #bfa;
      12. float: left;
      13. }
      14. /* 清除浮动 */
      15. .box1::after{
      16. content: "";
      17. display: block;
      18. clear: both;
      19. }
      20. </style>
      21. </head>
      22. <body>
      23. <div class="box1">
      24. <div class="box2"></div>
      25. </div>
      26. </body>
      27. </html>
  • 5、最终解决方案 clearfix

    • 手写一个样式 .clearfix,使其同时解决外边距折叠和高度塌陷问题
    • 借助伪类元素 ::before、::after、clear、display
      1. <!DOCTYPE html>
      2. <html lang="en">
      3. <head>
      4. <style>
      5. .box1{
      6. border: 10px solid red;
      7. }
      8. .box2{
      9. width: 100px;
      10. height: 100px;
      11. background-color: #bfa;
      12. float: left;
      13. }
      14. /* 清除浮动 */
      15. .clearfix::before,
      16. .clearfix::after{
      17. content: '';
      18. display: table;
      19. clear: both;
      20. }
      21. </style>
      22. </head>
      23. <body>
      24. <!-- 导入样式即可 -->
      25. <div class="box1 clearfix">
      26. <div class="box2"></div>
      27. </div>
      28. </body>
      29. </html>
  • 上述方案都只针对,由浮动引起的高度塌陷。而由绝对定位引起的高度塌陷,无法解决。需设置父元素高度。


定位

  • 定位是一种更加高级的布局方式,通过定位可以将元素摆放在任意位置。
  • 四种定位方式:
    • **relative**:相对定位
    • **absolute**:绝对定位
    • fixed:固定定位
    • sticky:粘滞定位
  • 相对定位,不会脱离文档流,参照元素在文档流中的位置进行定位。
  • 绝对定位,脱离文档流,相对包含块进行定位
  • 固定定位,参照浏览器的视口进行定位,不随滚动条滚动
  • 粘滞定位,当翻滚条滚动到一定位置,元素固定

绝对定位元素的布局

  • 需求:块元素在父元素中水平垂直居中 ```javascript <!DOCTYPE html>

  1. - 水平居中:`left: 0;``right: 0;``margin-left: auto;``margin-right: auto;`
  2. - 垂直居中:`top: 0;``bottom: 0;``margin-top: auto;``margin-bottom: auto;`
  3. <a name="REOTZ"></a>
  4. ### 元素的层级
  5. - 开启了定位的元素,可以通过 `z-index`属性来制定元素层级
  6. - 值越大,层级越高,即越优先展示
  7. <a name="DGRN5"></a>
  8. ## 动画
  9. <a name="tAFve"></a>
  10. ### 过渡
  11. - `trainsition`,设置指定属性变化时,切换的方式
  12. - `transition-property: ` 指定变化的属性
  13. - `transition-timing-function:` 指定过渡的时序函数
  14. - `transition-duration: ` 指定过渡效果的持续时间
  15. - `transition-delay` :指定过渡效果延迟多少秒后执行
  16. ```javascript
  17. transition-property: margin-left;
  18. transition-timing-function: steps(5);
  19. transition-duration: 2s;
  20. transition-delay: 1s;
  21. // 相当于
  22. transition: margin-left steps(5) 2s 1s

动画``

  • 动画和过渡都可以实现动态效果。
    • 区别在于:过渡需要某个属性发生变化时触发,而动画可以自动触发效果
  • 设置动画需要定义一个关键帧 @keyframes
  • animation,定义动画
    • animation-name:设置关键帧
    • animation-duration:一次动画的持续时间
    • animation-delay:动画的延时
    • animation-timing-function:设置动画的时序函数
    • animation-iteration-count:动画的执行次数
    • animation-direction:动画的执行方向,和关键帧中 from 和 to 有关
    • animation-fill-mode:设置执行一次动画后,元素位于哪个位置 ```javascript animation-name: test; animation-duration: 2s; animation-delay: 1s; animation-timing-function: steps(4); animation-iteration-count: infinite; animation-direction: normal; animation-fill-mode: forwards;

// 相当于 animation: test 2s 1s steps(4) infinite normal forwards

// 关键帧 @keyframes test { / from 设置动画的开始位置, 也可以使用 0% / from { margin-bottom: 0; } / to 设置动画的结束位置, 也可以使用 100% / to { margin-left: 700px; } }


<a name="borKc"></a>
### 变形

- `transform`:通过css 改变元素的形状和位置。**不会影响页面的布局**

<br />
<a name="qJKVv"></a>
#### 平移

- `translateX``translateY``translateZ`
- 分别为沿着 X 、Y、Z 轴平移
- 需求:元素水平垂直居中
```javascript
.box3{
  background-color: blue;
  position: absolute;
  /* 将元素整体移动 包含块 的 50% 此时偏移多了 */
  left: 50%;
  top: 50%;
  /* 再回移自身大小的 50% 可以达到居中效果 */
  transform: translateX(-50%) translateY(-50%);
}
  • Z 轴平移较特殊、
    • 需要设置窗口视距
  • 需求:鼠标移入时,元素 “变近” 200 像素
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <style>
      body div{
        /* 设置窗口的视距 */
        transform: perspective(500px);
      }
      .box1{
        width: 200px;
        height: 200px;
        background-color: #bfa;
        margin: 200px auto;
        position: relative;
        transition:2s;
      }
      .box1:hover{
        /* 设置 Z 轴平移,默认网页不支持透视,想看到效果,必须设置网页的视距 */
        transform:  translateZ(200px)
      }
    </style>
    </head>
    <body>
      <div class="box1"></div>
    </body>
    </html>
    

旋转

  • rotateX``rotateY``rotateZ
  • 设置旋转,可以使元素 沿着(当前)x y z 轴 旋转指定角度
  • 单位:deg 多少度、trun多少圈

缩放

  • scaleX``scaleY``scaleZ
  • scaleZ比较特殊,需要先设置 transform-style: preserve-3d;设为3d
  • 需求:实现鼠标移入,图片放大效果
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <style>
      .img-wrapper{
        width: 240px;
        height: 158px;
        /* border: 1px solid red; */
        outline: 1px solid red;
        overflow: hidden;
      }
      img{
        transition: 0.5s; /* 过渡耗时 */
        vertical-align: bottom;
      }
      .img-wrapper:hover img{
        transform: scale(1.2); /* 图片变大 */
      }
    </style>
    </head>
    <body>
      <div class="img-wrapper">
          <img src="../execrise/img/for10/1.jpg" alt="">
      </div>
    </body>
    </html>
    

弹性盒

  • flex,弹性盒,是CSS 中一种布局手段,用来代替浮动
  • 使元素具有弹性,让元素可以随着页面大小的改变而改变

分类

  • 弹性容器,一般为父元素。使用 display:flex
  • 弹性元素(弹性项):弹性容器中的直接子元素为弹性元素
  • 一个元素既可以是弹性容器也可以是弹性项


样式

  • 写在弹性容器中的属性
    • flex-flow,其中包括 flex-direction``flex-wrap
    • flex-direction指定弹性元素的排列方式
    • flex-wrap指定元素溢出时,如何换行。
    • justify-content如何分配主轴上的空白。一般来说 justify-xxx表示主轴上的。。。
    • align-items``align-content分别为指定元素在辅轴上如何分布、分配辅轴上的空白。类似, align-xxx表示辅轴上的。。。
  • 写在弹性元素中的属性
    • flex,其中包括 flex-grow``flex-shrink``flex-basis
    • flex-grow指定增长系数,当父元素中有多余空间,子元素如何伸展
    • flex-shrink指定收缩系数,当父元素空间不足以容纳所有子元素时,子元素如何收缩
    • flex-basis基础长度
    • flex的可选值
      flex: 2 2 200px
      initial ==> "flex: 0 1 auto"
      auto ==> "flex: 1 1 auto"
      none ==> "flex: 0 0 auto"
      

常用布局

两栏布局

浮动实现

  • left块开启浮动。right块使用 margin-left 撑出内容块 ```html

左边
右边
其他


<a name="uLN4V"></a>
### 弹性盒

- 父容器设置为弹性盒子。`right` 块的 `flex-grow` 设置为 1
```html
<style>
  .box {
    /* 设置弹性盒容器 */
    display: flex;
    /* 设置弹性元素在辅轴如何排列  默认stretch(同行元素等高)*/
    /* align-items: flex-start; */
  }
  .left {
    width: 250px;
    height: 400px;
    background-color: #bfa;
  }
  .right {
    /* 设置 flex-grow 为 1,占满右测 */
    flex: 1;
    height: 200px;
    background-color: pink;
  }
  .box2 {
    height: 100px;
    background-color: red;
  }
  /* 设置弹性盒容器,右侧 flow-grow 为 1 */
</style>


<body>
  <div class="box">
    <div class="left">左边</div>
    <div class="right">右边</div>
  </div>
  <div class="box2">其他</div>
</body>

三栏布局

浮动实现

  • center 块需要放在最后
  • left块左浮动、right块右浮动、center块的 width 设置 100%

    <style>
    .box {
      overflow: hidden;
      height: 400px;
    }
    .left {
      float: left;
      width: 250px;
      height: 100%;
      background-color: rgb(129, 129, 129);
    }
    .right {
      float: right;
      width: 200px;
      height: 100%;
      background-color: pink;
    }
    .main {
      height: 100%;
      width: 100%;
      background-color: yellow;
    }
    .box2 {
      height: 100px;
      background-color: blue;
    }
    </style>
    
    <body>
      <div class="box">
        <div class="left">左边</div>
        <div class="right">右边</div>
        <div class="main">主体</div>
      </div>
      <div class="box2">其他</div>
    </body>
    

定位实现

  • 三者都开启绝对定位

    <style>
    .box {
      height: 400px;
      position: relative;
    }
    .box > div {
      position: absolute;
    }
    .left {
      width: 250px;
      height: 100%;
      background-color: #bfa;
      left: 0;
    }
    .right {
      width: 200px;
      height: 100%;
      background-color: pink;
      right: 0;
    }
    .main {
      height: 100%;
      background-color: yellow;
      left: 250px;
      right: 200px;
    }
    /* 都开启绝对定位 */
    
    <body>
      <div class="box">
        <div class="left">左边</div>
        <div class="main">主体</div>
        <div class="right">右边</div>
      </div>
    </body>
    

圣杯布局

  • center块放在最前面(保证 center最先渲染)
  • 父容器设置左右padding,为 left块和 right块位置,三者都开启浮动。
  • centerwidth设为 100%、为保证 leftright同行,其 margin-left 均为负值
  • 然后开启 leftright块的相对定位。调整位置,占据预留的 padding区 ```html

中间
左边
右边


<a name="vNCry"></a>
### 双飞翼布局

- 在圣杯布局的基础上优化
- 父容器无需设置 padding
- 在 `center` 块中再添加一个 `inner` 块,使用 `margin-left` 和 `margin-right` 预留位置
- left、right 块就无需开启相对定位调正位置。
```html
<style>
  /* 最外层开启 BFC 设置高度 */
  .box {
    overflow: hidden;
    height: 400px;
  }
  /* 中、坐、右 都开启浮动 */
  .center,
  .left,
  .right {
    float: left;
    height: 100%;
  }
  /* 中的宽度 100% 自适应 */
  .center {
    width: 100%;
    background-color: yellow;
  }
  /* 内部节点 使用margin-left、margin-right 给left和right 预留位置 */
  .inner {
    margin-left: 200px;
    margin-right: 250px;
  }
  /* 相比于圣杯布局,无需使用相对定位 */
  .left {
    width: 200px;
    background-color: #bfa;
    margin-left: -100%;
  }
  /* 相比于圣杯布局,无需使用相对定位 */
  .right {
    width: 250px;
    background-color: pink;
    margin-left: -250px;
  }
</style>


<body>
  <div class="box">
    <div class="center">
      <!-- center 内部添加 inner 块 -->
      <div class="inner">主体</div>
    </div>
    <div class="left">左边</div>
    <div class="right">右边</div>
  </div>
</body>

弹性盒

  • 设置父容器为弹性盒
  • leftright块固定宽度,centerflow-grow 设为 1 ```html

左边
中间
右边


<a name="tTAaJ"></a>
### 网格布局

- `display:grid` 开启网格布局
- 设置左右固定宽度,中间为 auto:`grid-template-columns: 200px auto 250px;`
```html
<style>
  .box {
    display: grid;
    /* 核心代码:左右两栏固定宽度,中间自适应宽度 */
    grid-template-columns: 200px auto 250px;
    height: 400px;
  }
  .left {
    background-color: #bfa;
    height: 100%;
  }
  .center {
    background-color: yellow;
    height: 100%;
  }
  .right {
    background-color: pink;
    height: 100%;
  }
</style>


<body>
  <div class="box">
    <div class="left">左边</div>
    <div class="center">主体</div>
    <div class="right">右边</div>
  </div>
</body>