面试必看:css 的那些事(下)

195 阅读7分钟

接上文

面试必看:css 的那些事(上)

6. 元素水平垂直居中的方法有哪些?

来举一个例子:父容器 1px 的黑色边框,子容器红色背景色

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .parent {
      width: 400px;
      height: 400px;
      border: 1px solid #000;
    }
    .child {
      width: 100px;
      height: 100px;
      background-color: red;
    }
  </style>
</head>

<body>
  <div class="parent">
    <div class="child"></div>
  </div>
</body>

</html>

如图

image.png

以下所有示例代码的结果都是这一张图片

image.png

1. Flex 布局(推荐🌟)

代码示例

.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

优势:一行代码实现,无需子元素宽高,天然响应式

2. Grid 布局

.parent {
  display: grid;
  place-items: center;
}

优势:代码简洁,现代浏览器支持度高。

3. Table 布局(传统方案)

.parent {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}
.child { display: inline-block; }

适用场景:兼容老旧项目,但语义化较差。

4. 定位 + Transform

.parent {
  position: relative;
}
.child {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

适用场景:子元素宽高未知,兼容性较好(需考虑 IE9+)。

5. 定位 + Margin 负值

.parent {
  position: relative;
}
.child {
  position: absolute;
  left: 50%;
  top: 50%;
  margin-left: -50px; /* 子元素宽的一半 */
  margin-top: -50px;  /* 子元素高的一半 */
}

限制:需明确子元素宽高,响应式场景不友好(要固定子元素宽高)。

6. 定位 + Margin: Auto

.parent {
  position: relative;
}
.child {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
}

关键点:需子元素定义宽高,常用于弹窗居中。


7. 说说你对 CSS 动画的理解

动画类型

1. 渐变动画(Transition):通过属性变化触发过渡效果,如颜色、尺寸变化。

2. 转变动画(Transform):实现旋转、缩放、位移等几何变换。

3. 自定义动画(Keyframes):通过 @keyframes 定义复杂动画序列。

实现方式

1. 渐变动画(Transition)

.box {
  transition: all 0.3s ease-in-out;
  /* all 表示所有可动画的属性都将应用过渡效果。*/
  /* 0.3s 是过渡的持续时间,表示过渡效果将持续0.3秒。*/
  /*  ease-in-out 是过渡的时间函数,表示过渡效果将以缓慢开始,然后加速,最后再缓慢结束。 */
}
.box:hover {
  width: 500px;
  height: 500px;
}

动画.gif

2. 转变动画(Transform)

.box {
  transition: all 0.3s ease-in-out;
  /* all 表示所有可动画的属性都将应用过渡效果。*/
  /* 0.3s 是过渡的持续时间,表示过渡效果将持续0.3秒。*/
  /*  ease-in-out 是过渡的时间函数,表示过渡效果将以缓慢开始,然后加速,最后再缓慢结束。 */
}
.box {
  transform: scale(1.2);
  /*缩放*/
  
  /* transform: translateX(50px); */
  /*平移*/
  
  /* transform: rotate(45deg); */
  /*旋转*/
}

动画.gif

3. 自定义动画(Keyframes)

@keyframes rotate {
  0% { transform: rotate(0); }
  100% { transform: rotate(360deg); }
}
.box { animation: rotate 2s infinite; }

动画.gif


8. 响应式布局的实现方式

核心原理:根据视窗宽度动态调整布局。

例如,这里又有一个 300*300 的 div 容器,背景色是红色:

image.png

常用技术:

1. 媒体查询

@media (max-width: 500px) {
  .div { background-color: blue; }
}

动画.gif

痛点:需手动编写多套样式,代码冗余

2. 百分比布局

.div { width: 50%; } /* 相对于父容器,width 为父容器的一半 */

动画.gif

限制:嵌套场景计算复杂。

3. rem/vw/vw 方案

html { font-size: 16px; }
.box { width: 10rem; } /* 160px */

image.png

html中的<meta name="viewport" content="width=device-width, initial-scale=1.0">是实现响应式布局的关键,如果删掉了响应式布局就不能做了。


9. CSS 性能优化

1. 首页内联关键 CSS

  <div class="div" style="background-color: red;"></div>

原理:减少 HTTP 请求,加速渲染。

2. 异步加载非关键 CSS

  <link rel="stylesheet" href="style.css" media="noexist">

css 是会阻塞 html 的,通过 media="noexist" 延迟 css 加载

3. 压缩与合并
使用工具如 Webpack 或 PostCSS 自动优化。

4. 选择器优化

最好在三层之内

/* 避免嵌套过深 */
#app .content h3 { } /* 会先找全文的 h3 标签,然后再去找包含 h3 的 content 容器... */

10. 文本单行溢出省略号

.text {
  /* 文本溢出时显示省略号 */
  text-overflow: ellipsis;
  
  /* 限制文本显示行数为2行(WebKit内核特有属性) */
  -webkit-line-clamp: 2;
  
  /* 必须配合display: -webkit-box使用 */
  display: -webkit-box;
  
  /* 规定盒子显示模式为垂直排列 */
  -webkit-box-orient: vertical;
  
  overflow: hidden; /* 隐藏溢出内容 */
  width: 100%; /* 容器需有固定宽度 */
}

image.png


11. CSS 画三角形

1. 利用裁剪函数 clip-path

.box {
  width: 300px;
  height: 300px;
  background-color: red;
  clip-path: polygon(0 0, 100% 0, 0 100%); /* 定义三个顶点坐标 */
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}

动画.gif

2. 利用边框 border

image.png

image.png

所以当内容的 height 和 width 为0时,边框是这样子的,只需要让下边框和右边框消失就好了

image.png

代码如下:

.box {
  border: 100px solid #000;
  width: 0px;
  height: 0px;
  /* 哪条边框消失 */
  border-right-color: transparent;
  border-bottom-color: transparent;
  /*border-left-color: transparent;*/
}

动画.gif


12. 展示 12px 以下字体(拓展)

以前的浏览器版本不能展示 12px 以下的字体,现在支持了。所以这个知识点可以看作一个拓展:

  1. zoom
  2. transform
p {
  font-size: 16px;
  zoom: 0.5;
  /* transform: scale(0.5); */
  /* color: var(--simplecolor) */
}

动画.gif


13. CSS 预处理器

是什么

  1. 一种 css 语言
  2. 可以使用变量、函数、继承、混入、运算等功能
  3. 可以编译成 css 文件

主流方案

  1. Less:浏览器端可直接运行,语法贴近原生 CSS。
  2. Sass:功能最全,支持条件语句和循环。
  3. Stylus:语法最灵活,省略括号和分号。

代码对比

// Less
@red: #f00;
.box { color: @red; }
// Sass
$red: #f00;
.box { color: $red; }
// Stylus
red = #f00
.box
    color: red

14. 多栏布局

传统方案:Float

.column { float: left; width: 33.33%; }

缺点:需手动清除浮动。

现代方案:Grid

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

黑科技:Columns

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS Columns布局示例</title>
  <style>
    .container {
      /* 自动填充列,每列至少300px */
      columns: 3 300px;
      /* 旧版浏览器兼容 */
      -webkit-columns: 3 300px;
      
      /* 列间距 */
      column-gap: 20px;
      /* 列边框 */
      column-rule: 1px solid #ff0000;
      
      /* 容器样式 */
      padding: 20px;
      min-height: 600px;
    }

    .item {
      /* 防止元素跨列显示 */
      break-inside: avoid;
      
      /* 卡片样式 */
      background: #f2b8ea;
      padding: 20px;
      margin-bottom: 20px;
      border-radius: 8px;
      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="item">内容块1</div>
    <div class="item">内容块2</div>
    <div class="item">内容块3</div>
    <div class="item">内容块4</div>
    <div class="item">内容块5</div>
    <div class="item">内容块6</div>
    <div class="item">内容块7</div>
    <div class="item">内容块8</div>
    <div class="item">内容块9</div>
    <div class="item">内容块10</div>
  </div>
</body>
</html>

动画.gif

优势:类似 Pinterest 瀑布流,无缝响应式


15. Flex 布局详解

1. 弹性容器会让子容器默认继承交叉轴上的 100%

例如这个代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    *{
      margin: 0;
      padding: 0;
    }
    li{
      list-style: none;
    }
    .parent {
      width: 300px;
      height: 100px;
      border: 1px solid #000;
      display: flex;
      flex-wrap: wrap;
    }
    .child{
    /* 没有给子容器高度 */
    }
  </style>
</head>
<body>
  <ul class="parent">
    <li class="child" style="background-color: red;"></li>
    <li class="child" style="background-color: rgb(0, 255, 0);"></li>
    <li class="child" style="background-color: rgb(217, 48, 180);"></li>
  </ul>
</body>
</html>

image.png

2. 默认情况下,子容器在主轴上是不放大,会缩小

子容器在主轴方向:默认值:flex: 0 1 auto

  • 不主动放大(flex-grow: 0
  • 允许缩小(flex-shrink: 1
  • 基础宽度由内容决定(flex-basis: auto
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    li {
      list-style: none;
    }

    .parent {
      width: 300px;
      height: 100px;
      border: 1px solid #000;
      display: flex;
      flex-wrap: wrap;
    }

    .child {
      /* 默认值:flex: 0 1 auto */

      flex: 0 0 100px;
      /* height: 100px; */
      /* 显式设置为不放大、不缩小,基础宽度100px */
    }
  </style>
</head>

<body>
  <ul class="parent">
    <li class="child" style="background-color: red;"></li>
    <li class="child" style="background-color: rgb(0, 255, 0);"></li>
    <li class="child" style="background-color: rgb(217, 48, 180);"></li>
  </ul>
</body>

</html>

flex: 0 0 100px; ,则三个子容器都是 100*100

flex: 0 0 150px; ,则父容器高度 100px 被平分给两行,导致每行高度 50px,,150*50

flex: 0 0 120px; height: 100px;flex-shrink: 0 禁止缩小,导致溢出

动画.gif

3. 默认情况下,所有子元素的 order 值都为 0,它们按照在 HTML 文档中出现的顺序排列。

当给子元素设置不同的 order 值时,元素会按照 order 值从小到大的顺序进行排列。

.child:nth-child(2){
  order: -1; 
}

动画.gif

应用场景:等宽卡片列表,右侧边栏固定等。