CSS 面试题整理

131 阅读21分钟

两种盒模型分别说一下

先说两种盒模型分别怎么写,具体到代码。然后说你平时喜欢用 border-box,因为更好用。

  • content-box(W3C标准盒模型) width 指 content 部分的宽度
  • border-box(IE盒模型) width 表示 content + padding + border 这三个部分的宽度
box-sizing: content-box
box-sizing: border-box

如何垂直居中?

摘要:

  • 使用 table,自带垂直居中
  • div 装成 table
  • 在目标元素前后(after before)加上100%高度的 inline-block 元素
  • 已知高度height时,absolute绝对定位 + top为50% + margin-top为负一半的高度
  • top为50% + translate为-50%
  • absolute + margin为auto + top/bottom/left/right为0
  • flex 布局
  • grid 布局

补充水平居中:

  • inline元素:text-align: center;
  • block元素:margin: auto;
  • absolute元素:left:50% + margin-left负值
  • flex 布局

如果 .parent 的 height 不写,你只需要 padding: 10px 0; 就能将 .child 垂直居中; 如果 .parent 的 height 写死了,就很难把 .child 居中,以下是垂直居中的方法。 忠告:能不写 height 就千万别写 height。

  • table 自带功能
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>table 自带功能</title>
        <style>
          .parent{
            border: 1px solid red;
            height: 600px;
          }
          .child{
            border: 1px solid green;
          }
        </style>
      </head>
      <body>
      <table class="parent">
          <tr>
            <td class="child">
              一串很长很长的文字
            </td>
          </tr>
        </table>
      </body>
    </html>
    
  • 在目标元素前后(after before)加上100%高度的 inline-block 元素
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>100%高度的 after before 加上 inline-block</title>
      <style>
        .parent{
          border: 3px solid red;
          height: 600px;
          text-align: center;
        }
        .child{
          border: 3px solid black;
          display: inline-block;
          vertical-align: middle;
        }
        .parent .before{
          display: inline-block;
          height: 100%;
          vertical-align: middle;
        }
        .parent .after{
          display: inline-block;
          height: 100%;
          vertical-align: middle;
        }
      </style>
    </head>
    <body>
      <div class="parent">
        <span class=before></span>
        <div class="child">  
          一串很长很长的文字
        </div>
        <span class=after></span>
      </div>
    </body>
    </html>
    
    优化版本:
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>100%高度的 after before 加上 inline-block(优化版)</title>
      <style>
        .parent{
          border: 3px solid red;
          height: 600px;
          text-align: center;
        }
        .child{
          border: 3px solid black;
          display: inline-block;
          width: 400px;
          vertical-align: middle;
        }
        .parent:before{
          content:'';
          outline: 3px solid red;
          display: inline-block;
          height: 100%;
          vertical-align: middle;
        }
        .parent:after{
          content:'';
          outline: 3px solid red;
          display: inline-block;
          height: 100%;
          vertical-align: middle;
        }
      </style>
    </head>
    <body>
      <div class="parent">
        <div class="child">
          一串很长很长的文字
        </div>
      </div>
    </body>
    </html>
    
  • div 装成 table
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>div 装成 table</title>
      <style>
        div.table{
          display: table;
          border: 1px solid red;
          height: 600px;
        }
        div.tr{
          display: table-row;
          border: 1px solid green;
        }
        div.td{
          display: table-cell;
          border: 1px solid blue;
          vertical-align: middle;
        }
        .child{
          border: 10px solid black;
        }
      </style>
    </head>
    <body>
      <div class="table">
        <div class="tr">
          <div class="td">
            <div class="child">
              一串很长很长的文字
            </div>
          </div>
        </div>
      </div>
    </body>
    </html>
    
  • 已知高度height时,absolute绝对定位 + top为50% + margin-top为负一半的高度
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>margin-top 设为 -50%</title>
      <style>
        .parent{
          height: 600px;
          border: 1px solid red;
          position: relative;
        }
        .child{
          border: 1px solid green;
          width: 300px;
          height: 100px;
          position: absolute;
          top: 50%;
          left: 50%;
          margin-left: -150px;
          margin-top: -50px;
        }
      </style>
    </head>
    <body>
      <div class="parent">
        <div class="child">
          一串很长很长的文字
        </div>
      </div>
    </body>
    </html>
    
  • top为50% + translate为-50%
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>translate 设为 -50%</title>
      <style>
        .parent{
          height: 600px;
          border: 1px solid red;
          position: relative;
        }
        .child{
          border: 1px solid green;
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translate(-50%,-50%);
        }
      </style>
    </head>
    <body>
      <div class="parent">
        <div class="child">
          一串很长很长的文字
        </div>
      </div>
    </body>
    </html>
    
  • absolute + margin为auto + top/bottom/left/right为0
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>absolute + margin:auto</title>
      <style>
        .parent{
          height: 600px;
          border: 1px solid red;
          position: relative;
        }
        .child{
          border: 1px solid green;
          position: absolute;
          width: 300px;
          height: 200px;
          margin: auto;
          top: 0;
          bottom: 0;
          left: 0;
          right: 0;
        }
      </style>
    </head>
    <body>
      <div class="parent">
        <div class="child">
          一串很长很长的文字
        </div>
      </div>
    </body>
    </html>
    
  • flex 布局
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>flex 布局</title>
      <style>
        .parent{
          height: 600px;
          border: 3px solid red;
          display: flex;
          justify-content: center;
          align-items: center;
        }
        .child{
          border: 3px solid green;
          width: 300px;
        }
      </style>
    </head>
    <body>
      <div class="parent">
        <div class="child">
          一串很长很长的文字
        </div>
      </div>
    </body>
    </html>
    

flex 怎么用?常用属性有哪些?

在父元素上声明 dispaly: flexdisplay: inline-flex 就可以激活弹性盒布局,父元素成为弹性容器,控制子元素(弹性元素)的布局。注:只有直接子元素使用弹性盒布局 常用属性:

  • 弹性容器:(第一个为默认值)
    • flex-direction: row | row-reverse | column | column-reverse 定义弹性容器主轴方向
    • flex-wrap: nowrap | wrap | wrap-reverse 是否允许弹性元素换行
    • justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly
      • center:所有弹性元素挤在一起,居中显示
      • space-between:第一个和最后一个弹性元素分别放在容器首尾处,然后在各弹性元素周围放置等量空白,直到占满一行
      • space-around:一行中的空白均匀分布在各弹性元素周围,就像每个元素都有不折叠的等量外边距
      • space-evenly:有n个弹性元素时有n+1个空隙(包含首尾),一行中的空白均匀分给n+1个空隙
    • align-items: flex-start | flex-end | center | baseline | stretch
      • baseline:基线对齐
      • stretch:当没有显式设置垂轴方向上的尺寸时,拉伸铺满弹性容器
    • align-self: flex-start | flex-end | center | baseline | stretch 在单个弹性元素上覆盖 align-items 的值
    • align-content: stretch | flex-start | flex-end | center | space-between | space-around | space-evenly 指定弹性容器中垂轴方向上的额外空间如何分配到弹性元素行之间和周围
  • 弹性元素
    • flex-grow: ,初始值:0,不支持负数 设定弹性增长因子,弹性容器中多余的空间将根据各弹性元素的非零增长因子按比例分配给各个弹性元素
    • flex-shrink: ,初始值:1,不支持负数 设定弹性缩减因子,将需要缩减的空间根据各弹性元素的非零缩减因子按比例分配给各个弹性元素进行缩减
    • flex-basis: content | | 定义弹性元素的初始尺寸
    • order: (整数)

display: none;visibility: hidden; 的区别?

  • 结构
    • display: none; 会让元素完全从渲染树中消失,渲染的时候不占据任何空间,不能点击。
    • visibility: hidden; 不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,不能点击。
  • 继承
    • display: none; 非继承属性,子孙节点消失由于元素从渲染树消失造成,通过修改子孙节点属性无法显示。
    • visibility: hidden; 继承属性,子孙节点消失由于继承了 hidden,通过设置 visibility: visible; 可以让子孙节点显式。
  • 性能
    • display: none; 修改元素会造成文档回流。读屏器不会读取其元素内容,性能消耗较大。
    • visibility: hidden; 修改元素只会造成本元素的重绘,性能消耗较少。读屏器会读取其元素内容。

有几种方式让元素在页面中消失?

  • display: none;:将元素的 display 属性设置为 none,元素将不会在页面中显示,并且不会占据页面空间。
  • visibility: hidden;:设置元素的 visibility 属性为 hidden,元素在页面上不可见,但仍然占据页面空间。
  • opacity: 0;:将元素的透明度设置为 0,元素将完全透明,看起来就像消失了,但仍然占据页面空间。
  • z-index:通过设置元素的z-index属性为一个较低的值或负值,可以让元素位于其他元素下方,从而在视觉上“消失”。
  • position: absolute;position: fixed;:将元素使用绝对定位或固定定位移动到屏幕外,例如将其放置在 left 或 top 为负值的位置。
  • height: 0; width: 0;:将元素的高度和宽度设置为 0,元素将不会显示,但这种方式会改变元素的尺寸而不是隐藏。
  • clip-pathclip:使用clip-pathclip属性将元素裁剪到一个看不见的区域。
  • transform: scale(0);:使用 transform 属性将元素缩放到 0,使其在页面上不可见,但仍然占据空间。

消失后能否还能获取到该元素: 如果只是通过 CSS 样式让元素在视觉上消失,通常可以在 JavaScript 中获取到这些元素。但如果是完全从 DOM 中移除元素(如使用某些特定的框架方法或removeChild()方法),则在移除后的状态下通过常规的 DOM 查询方法不能直接获取到该元素。例如在 Vue 中,当使用v-if将元素从 DOM 中完全移除时,在移除后的状态下通过常规的 DOM 查询方法不能直接获取到该元素。但是 Vue 的实例中可能仍然保留着对该元素相关数据的引用(如果有需要,可以通过 Vue 的内部机制进行访问,但这相对复杂)。

说一下清除浮动

.clearfix 加到容器上,里面子元素的浮动就被清除了

  .clearfix:after{
    content: '';
    display: block; /*或者 table*/
    clear: both;
  }
  .clearfix{
    zoom: 1; /* IE 兼容*/
  }

CSS3 新特性?

  • 新增选择器 p:nth-child(n){color: rgba(255, 0, 0, 0.75)}
  • 弹性盒模型 display: flex;
  • 媒体查询 @media (max-width: 480px) {.box: {column-count: 1;}}
  • 颜色透明度 color: rgba(255, 0, 0, 0.75);
  • 圆角 border-radius: 5px;
  • 渐变 background:linear-gradient(red, green, blue);
  • 阴影 box-shadow:3px 3px 3px rgba(0, 64, 128, 0.3);
  • 边框效果 border-image:url(bt_blue.png) 0 10;
  • 平滑过渡 transition: all .3s ease-in .1s;
    • all:受过渡影响的属性
    • .3s:过渡持续时间
    • ease-in:过渡的内部时序
      • ease:慢速开始,然后加速,再慢下来,结束时特别慢
      • linear:整个过渡过程保持相同的速度
      • ease-in:慢速开始,然后加速
      • ease-out:快速开始,然后减速
      • ease-in-out:与 ease 类似,中间较快,两端很慢,但不同速
    • .1s:延迟过渡的时间
  • 动画
    • 定义关键帧
        @keyframes nameOfAnimation {
          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: 100%; }
        }
      
    • 把动画应用到元素上 animation: nameOfAnimation 200ms ease-in 50ms 1 normal
      • 200ms:动画时长
      • 1:动画迭代次数
      • 50ms:动画延迟播放时间
      • normal:动画播放方向
  • 变形 transform
    • 旋转 transform: rotate(20deg);
    • 倾斜 transform: skew(150deg, -10deg);
    • 位移 transform: translate(20px, 20px);
    • 缩放 transform: scale(.5);

CSS 单位有哪些?

  • px:绝对单位
  • %:父元素宽度的比例
  • em:相对单位
    • 对于字体大小属性(font-size)来说,em 的计算方式是相对于父元素的字体大小。
    • border,width,height,padding,margin,line-height,在这些属性中,使用em单位的计算方式是参照该元素的 font-size,1em 等于该元素设置的字体大小。
  • rem:是相对于根元素 html 的 font-size 来计算的,所以其参照物是固定的。
  • vw,vh:相对单位,是基于视窗大小(浏览器用来显示内容的区域大小)来计算的;vmax 取前面两者中最大的长度,vmin 取前面两者中最小的长度。

如何实现响应式布局?

  1. 先使用媒体查询,根据不同的屏幕宽度设置根元素的 font-size
  2. 后续页面开发中使用基于根元素的 rem 相对长度单位

怎么理解回流跟重绘?什么场景下会触发?

  • 回流
    • 当我们对 DOM 的修改引发了 DOM 几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,浏览器需要重新计算元素的几何属性,然后再将计算的结果绘制出来
    • 触发时机:添加删除 DOM 节点,元素位置发生变化,元素尺寸发生变化,页面初始化渲染
  • 重绘
    • 当我们对 DOM 的修改导致了样式的变化(color 或 background-color),但是并未影响其几何属性时,浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式
    • 触发时机:颜色修改,文本方向修改,阴影修改
  • 如何减少重构:
    • 对于那些复杂的动画,对其设置position: fixed/absolute,尽可能地使元素脱离文档流,从而减少对其他元素的影响
    • 如果想设定元素的样式,通过改变元素的 class 类名(尽可能在 DOM 树的最里层)
    • 避免设置多项内联样式

回流有可能会导致重绘,但不是一定的。当发生回流时,由于布局发生了变化,很可能会影响到元素的外观表现,从而可能触发重绘。例如,改变元素的宽度会导致回流,而元素宽度的改变可能会使元素的背景颜色显示区域发生变化,进而触发重绘。

重绘不一定会导致回流。当发生重绘时,如果只是单纯地改变元素的外观属性,而没有涉及到元素的尺寸、位置等会影响布局的属性变化,那么就不会触发回流。例如,通过 JavaScript 改变元素的背景颜色,这只会触发重绘,因为它不影响元素的布局,所以不会导致回流。但是,如果在重绘的过程中,某些操作意外地影响了元素的布局,那么就有可能触发回流。这种情况比较少见,通常是由于代码中的错误或者不恰当的操作导致的。

伪元素和伪类的区别和作用?

  • 伪元素 在内容元素的前后插入额外的元素或样式,但是这些元素实际上并不在文档中生成。
  • 伪类 表示一种状态,将特殊的效果添加到特定选择器上。它是已有元素上添加类别的,不会产生新的元素。

position 有哪些值? relative 和 absolute 定位原点是?

  • relative:生成相对定位的元素,相对于其正常位置进行定位。
  • absolute:生成绝对定位的元素,相对于值不为 static 的第一个父元素进行定位。
  • fixed:生成绝对定位的元素,相对于浏览器窗口进行定位。
  • static:默认值。没有定位,元素出现在正常的流中。
  • inherit:规定从父元素继承 position 属性的值。

CSS 选择器优先级

  • 三句话
    • 越具体优先级越高
    • 同样优先级写在后面的覆盖写在前面的
    • !important 优先级最高,但是要少用
  • 大众答案
    • 选择符中的每个 id 属性值加 0,1,0,0
    • 选择符中的每个类属性值、属性选择或伪类加 0,0,1,0
    • 选择符中的每个元素和伪元素加 0,0,0,1
    • 连接符和通用选择符不增加特指度
  • 样式定义的优先级顺序 !important > 内联样式 > ID选择器 > 类选择器 > 类型选择器 > 元素选择器 > 浏览器默认样式

什么情况下z-index会失效?

  • 问题标签元素的z-index属性值低于父元素 ---> 提高父标签的z-index
  • 问题标签没有设置定位(position)属性 ---> 浮动元素添加 position 属性(如 relative,absolute 等)
  • 问题标签含有浮动(float)属性 ---> 除去浮动
  • 父标签 position 属性为 relative ---> 父标签改为 absolute

CSS 有哪些属性可以继承?

  • 字体系列属性:font、font-family、font-weight、font-size、font-style
  • 文本系列属性:内联元素(color、line-height、word-spacing、letter-spacing、 text-transform),块级元素(text-indent、text-align)
  • 元素可见性:visibility
  • 表格布局属性:caption-side、border-collapse、border-spacing、empty-cells、 table-layout
  • 列表布局属性:list-style
  • 光标属性:cursor

如何在移动端适配不同的机型?

  • 使用响应式布局
    • 弹性布局(Flex):可以轻松地实现元素在不同方向上的对齐和伸缩,适应不同屏幕尺寸。例如,设置容器为弹性布局,让子元素在水平和垂直方向上自动调整位置和大小。
      .container {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
      }
      
    • 网格布局(Grid):可以更精细地控制页面的布局,将页面划分为网格,方便地调整元素的位置和大小。
      .grid-container {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
        grid-gap: 10px;
      }
      
  • 使用相对单位
    • 百分比:设置元素的宽度、高度等属性为百分比,使其相对于父元素的大小进行调整。例如,设置一个元素的宽度为 50%,它将占据父元素宽度的一半。
    • rem:相对于根元素字体大小的单位。可以通过设置根元素的字体大小,然后在其他元素中使用 rem 单位来实现相对大小的调整。
  • 媒体查询 根据不同的屏幕尺寸设置不同的样式。可以针对特定的屏幕宽度范围、高度范围或设备类型(如手机、平板)进行样式调整。
    @media screen and (max-width: 480px) {
      /* 手机屏幕样式 */
    }
    @media screen and (min-width: 481px) and (max-width: 768px) {
      /* 平板屏幕样式 */
    }
    @media screen and (min-width: 769px) {
      /* PC 屏幕样式 */
    }
    

实现三栏布局,两边固定宽度,中间自适应

  • 圣杯布局(浮动+定位)
    <div class="container">
      <div class="middle">中间栏</div>
      <div class="left">左侧栏</div>
      <div class="right">右侧栏</div>
    </div>
    
    * {
      margin: 0;
      padding: 0;
    }
    .container {
      height: 100px;
      /* 给父容器添加 padding 腾开位置 */
      padding: 0 200px; 
    }
    .middle, .left, .right {
      height: 100%;
      /* 给三个子容器都设置 float 让它们都向左浮动,到同一行 */
      float: left;
    }
    .middle {
      /* 设置 width, 宽度继承了父容器的 100% */
      width: 100%;
    }
    .left {
      width: 200px;
      /* 给左右容器相对定位,让它们相对自己原本文档流的位置进行定位 */
      position: relative;
      /* 向左挪动父容器宽度的 100% */
      margin-left: -100%; 
      /* 再向左挪动自身的 200 宽度 */
      left: -200px; 
    }
    .right {
      width: 200px;
      /* 给左右容器相对定位,让它们相对自己原本文档流的位置进行定位 */
      position: relative;
      margin-right: -200px; 
    }
    
  • 双飞翼布局(浮动)
    <div class="container">
      <div class="middle">
        <div class="inner">中间栏</div>
      </div>
      <div class="left">左侧栏</div>
      <div class="right">右侧栏</div>
    </div>
    
    * {
      margin: 0;
      padding: 0;
    }
    .container {
      height: 100px;
    }
    .middle, .left, .right{
      float: left;
      height: 100%;
    }
    .middle{
      width: 100%;
    }
    .inner{
      height: 100%;
      /* 添加 padding 腾开位置 */
      padding: 0 200px;
    }
    .left{
      width: 200px;
      margin-left: -100%;
    }
    .right{
      width: 200px;
      margin-left: -200px;
    }
    
  • 弹性布局
    <div class="page">
      <div class="main">中间栏</div>
      <div class="left">左侧栏</div>
      <div class="right">右侧栏</div>
    </div>
    
    * {
      margin: 0;
      padding: 0;
    }
    .page {
      height: 200px;
      display: flex;
    }
    .main {
      flex: 1;
      order: 1;
    }
    .left {
      width: 200px;
      order: 0;
    }
    .right {
      width: 200px;
      order: 2;
    }
    
  • 表格布局
    <div class="page">
      <div class="left">左侧栏</div>
      <div class="main">中间栏</div>
      <div class="right">右侧栏</div>
    </div>
    
    * {
      margin: 0;
      padding: 0;
    }
    .page {
      width: 100vw;
      height: 200px;
      display: table;
      table-layout: fixed;
    }
    .main {
      width: 100%;
      height: 200px;
    }
    .left, .right {
      height: 200px;
      width: 200px;
    }
    
  • 网格布局
    <div class="page">
      <div class="left">左侧栏</div>
      <div class="main">中间栏</div>
      <div class="right">右侧栏</div>
    </div>
    
    * {
      margin: 0;
      padding: 0;
    }
    .page {
      width: 100vw;
      height: 200px;
      display: grid;
      grid-template-columns: 200px auto 200px;
    }
    .main {
      height: 200px;
    }
    .left,
    .right {
      height: 200px;
    }
    

CSS/SCSS 实现动态更换主题色

  • CSS 变量方法

    使用 CSS 变量来进行主题色的修改,替换主题色变量,然后用 setProperty 来进行动态修改,用法就是给变量加--前缀,涉及到主题色的都改成var(--themeColor)这种方式:

    body {
     --primaryColor: red;
    }
    .page {
      background: var(--primaryColor);
      color: var(--primaryColor);
    }
    

    要修改主题色时:document.body.style.setProperty('--primaryColor', 'blue');

  • SCSS

    • 给根节点定义一个类,切换主题色就是切换类名;或者设置一个属性,切换主题色就是修改这个属性的值
      // 改变主题色 
      changeTheme(theme) { 
        window.document.documentElement.setAttribute("class", theme)
      }
      
    • 创建主题 scss 文件,定义一个 map 类型的变量
      //themeVariable.scss
      $themes:(
        "green":(
          background:#ECECEC,
          font-basis-color:#585858,
          box-border:#D2D2D2
        ),
        "blue":(
          background:#022059,
          font-basis-color:#EFEFEF,
          box-border:#185F86
        )
      )
      
    • 创建混入 scss 文件,编写自定义 mixin
      //themeMixin.scss
      @import './themeVariable.scss'; //导入主题颜色变量
      @mixin themeMixin {
        // @each 遍历 $themes 的键值对
        @each $theme-name, $map in $themes {
          $theme-name: $theme-name !global; //全局变量供函数调用,如果无需全局调用,可不写!global
          $themeMapList: $map !global; //全局变量供函数调用
          //新定义一个类
          .theme-#{$theme-name} {
            @content; //插入位置
          }
        }
      }
      
      //从主题色map中取出对应颜色
      @function themeAttrVal($themeAttrKey) {
        @return map-get($themeMapList, $themeAttrKey);
      }
      
    • 在需要编写主题样式地方引入,在样式中使用@include引入 mixin
      @import './theme/themeMixin.scss';
      @include themeMixin {
        body {
          background: themeAttrVal('background');
          color: themeAttrVal('font-basis-color');
        }
      }
      

BFC 是什么?

BFC(Block formatting context):块级格式化上下文,是一个独立的布局环境,其中的元素布局是不受外界的影响。

  • 背 BFC 触发条件,MDN 写了。但是不用全部背下来,面试官只知道其中几个:
    • 浮动元素(元素的 float 不是 none)
    • 绝对定位元素(元素的 position 为 absolute 或 fixed)
    • 行内块元素
    • overflow 值不为 visible 的块元素
    • 弹性元素(display为 flex 或 inline-flex元素的直接子元素)
  • 补充
    • BFC 的规则:
      • BFC 就是一个块级元素,块级元素会在垂直方向一个接一个的排列
      • BFC 就是页面中的一个隔离的独立容器,容器里的标签不会影响到外部标签
      • 垂直方向的距离由margin决定, 属于同一个 BFC 的两个相邻的标签外边距会发生重叠
      • 计算 BFC 的高度时,浮动元素也参与计算
    • BFC 解决了什么问题:
      • 使用 float 脱离文档流,高度塌陷
      • margin 边距重叠
      • 两栏布局

外边距折叠(collapsing margins)?

相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。 折叠结果遵循下列计算规则:

  • 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值
  • 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值
  • 两个外边距一正一负时,折叠结果是两者的相加的和

link 与 @import 的区别

  • link 是 HTML 方式, @import 是 CSS 方式
  • link 最大限度支持并行下载,@import 过多嵌套导致串行下载,出现 FOUC
  • link 可以通过 el="alternate stylesheet" 指定候选样式
  • 浏览器对 link 支持早于 @import ,可以使用 @import 对老浏览器隐藏样式
  • @import 必须在样式规则之前,可以在 css 文件中引用其他文件
  • 总体来说:link 优于 @import

什么是 FOUC?如何来避免 FOUC?

FOUC(Flash of Unstyled Content):文档样式短暂失效

  • 产生原因:当样式表晚于结构性 html 加载时,加载到此样式表时,页面将停止之前的渲染。等待此样式表被下载和解析后,再重新渲染页面,期间导致短暂的花屏现象。
  • 解决方法:使用 link 标签将样式表放在文档 head

为什么要初始化 CSS 样式?

  • 不同浏览器对有些标签样式的默认值解析不同
  • 不初始化 CSS 会造成各现浏览器之间的页面显示差异
  • 可以使用 reset.css 或 Normalize.css 做 CSS 初始化

文本溢出显示为省略号?

  • 单行文本
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: no-wrap;
    
  • 多行文本
      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-line-clamp: 3;
      -webkit-box-orient: vertical;
    

CSS 优化、提高性能的方法有哪些?

  • 多个 css 合并,尽量减少 HTTP 请求
  • css 雪碧图
  • 抽象提取公共样式,减少代码量
  • 选择器优化嵌套,尽量避免层级过深 (用‘>’替换‘ ’)
  • 属性值为 0 时,不加单位
  • 压缩CSS代码
  • 避免使用 CSS 表达式

如何保留多个空格和换行?

使用white-space属性:white-space属性可以控制元素内空白的处理方式。要保留空格和换行,可以设置white-space属性的值为prepre-wrap

  • pre:保留空格和换行,并将元素内的内容按照文本编辑器中的方式显示。
  • pre-wrap:保留空格和换行,并且会根据元素的宽度自动换行。

有哪些设置透明度的方法?

  • opacity
    .element {
      opacity: 0.5; /* 设置 50% 的透明度 */
    }
    
  • filter
    .element {
      filter: opacity(50%); /* 设置 50% 的透明度 */
    }
    
  • RGBA 颜色值
    .element {
      background-color: rgba(0, 128, 0, 0.5); /* 绿色背景,透明度为 0.5 */
    }
    

opacity 的继承

  • 问题:有一个父元素它的透明度是opacity:0.5;,子元素给它设置为 1, 这个子元素的透明度是多少?
    • 在 CSS 中,当父元素设置了 opacity 属性时,子元素会继承父元素的透明度效果,即使子元素自身设置了 opacity 为 1。如果父元素的透明度是opacity: 0.5;,那么子元素实际显示的透明度也会受到父元素的影响而呈现出整体透明度为 0.5 的效果,尽管子元素自身设置了opacity 为 1。
  • 问题:如何设置子元素的透明度而不受到父元素的影响?
    • 使用 RGBA 颜色值
    • 使用 CSS3 的mix-blend-mode属性
      .parent {
        opacity: 0.5;
        background-color: gray;
      }
      
      .child {
        background-color: blue;
        mix-blend-mode: multiply; /* 根据具体需求选择合适的混合模式 */
      }
      
      通过设置mix-blend-mode属性可以让子元素与父元素以特定的混合模式显示,从而在视觉上达到一定的透明度效果,同时又不受父元素 opacity 的直接影响。
    • 使用position: relativeposition: absolute结合定位
      .parent {
        opacity: 0.5;
        position: relative;
      }
      
      .child {
        position: absolute;
        background-color: rgba(255, 0, 0, 0.5); /* 红色背景,透明度为 0.5 */
      }
      
      将子元素相对于父元素进行绝对定位,然后在子元素上设置背景色或其他需要透明度的属性时,就不会直接受到父元素 opacity 的影响。

一个高度自适应的 div,里面有两个 div,一个高度 100px,希望另一个填满剩下的高度

  • .sub { height: calc(100%-100px); }
  • .container { position:relative; } .sub { position: absolute; top: 100px; bottom: 0; }
  • .container { display:flex; flex-direction:column; } .sub { flex:1; }

抽离样式模块怎么写?

CSS 可以拆分成 2 部分:公共 CSS 和 业务 CSS。

  • 公共 CSS 网站的配色、字体、交互提取出为公共 CSS。这部分 CSS 命名不应涉及具体的业务
  • 业务 CSS 对于业务 CSS,需要有统一的命名,使用公用的前缀。

transform 的副作用

  • transform 改变 fixed 子元素的定位对象
  • transform 改变元素层叠顺序

font-style 属性 oblique 是什么意思?

font-style: oblique;:使没有 italic 属性的文字实现倾斜