概念

Q1:怎么触发BFC?BFC有什么应用场景

难度:⭐⭐⭐

答案

BFC(块级格式化上下文)是一个独立的渲染区域,具有一定的规则和约束,它可以包含浮动元素、清除浮动、防止外边距重叠等特性。触发BFC的方法有多种,其中一些常见的方式包括:

  1. float 属性: 当一个元素设置了 float 属性值不为 none,会触发该元素生成 BFC。

    1
    2
    3
    cssCopy code.element {
    float: left; /* 触发BFC */
    }
  2. position 属性: 当一个元素的 position 属性值为 absolutefixed,也会触发该元素生成 BFC。

    1
    2
    3
    cssCopy code.element {
    position: absolute; /* 触发BFC */
    }
  3. display 属性: 当一个元素的 display 属性值为 inline-blocktable-celltable-captionflow-root(新的值,用于触发BFC)时,会触发该元素生成 BFC。

    1
    2
    3
    cssCopy code.element {
    display: inline-block; /* 触发BFC */
    }
  4. overflow 属性: 当一个元素的 overflow 属性值不为 visible,会触发该元素生成 BFC。

    1
    2
    3
    cssCopy code.element {
    overflow: auto; /* 触发BFC */
    }

应用场景:

  1. 清除浮动: BFC 可以包含浮动元素,这样可以解决浮动元素造成的父元素高度塌陷的问题。可以通过给父元素触发 BFC,如设置 overflow: hidden;display: flow-root;

    1
    2
    3
    4
    5
    cssCopy code.clearfix::after {
    content: "";
    display: table;
    clear: both;
    }
  2. 防止外边距重叠: BFC 可以防止相邻块级元素的外边距重叠问题。

  3. 自适应两栏布局: 利用 BFC 特性可以创建自适应两栏布局,其中一个栏固定宽度,另一个栏自适应剩余宽度。

  4. 包含浮动元素: BFC 可以包含浮动元素,防止浮动元素溢出父容器。


Q2:对CSS模块化的理解

难度:⭐⭐⭐⭐⭐

答案

CSS 模块化是一种组织和管理 CSS 代码的方法,旨在提高代码的可维护性、可读性和可重用性。主要目标是避免全局污染、减少样式冲突,同时使得样式表结构更清晰。

以下是一些与 CSS 模块化相关的核心概念和实践:

  1. 命名空间: 在 CSS 模块化中,使用命名空间是一种将样式限定在特定区域的方法,以防止样式冲突。可以使用 BEM(块、元素、修饰符)等命名约定,或者通过工程化工具(如 CSS Modules)自动生成唯一的类名。

    1
    2
    3
    4
    5
    6
    7
    8
    /* BEM 命名空间 */
    .block {}
    .block__element {}
    .block--modifier {}

    /* CSS Modules 自动生成的唯一类名 */
    .moduleBlock_foo {}
    .moduleBlock_bar {}
  2. 局部作用域: 使用工具或框架提供的局部作用域,确保样式只在特定模块或组件中生效。这可以通过 CSS-in-JS 库、CSS Modules、Scoped CSS 等实现。

    1
    2
    3
    4
    /* CSS Modules */
    .container {
    /* 局部作用域 */
    }
  3. 模块化工具: 使用模块化工具,例如 Sass、Less 或者 PostCSS,以便利用变量、嵌套、混合等功能,更好地组织样式代码。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /* Sass 示例 */
    $primary-color: #3498db;

    .button {
    background-color: $primary-color;
    &:hover {
    background-color: darken($primary-color, 10%);
    }
    }
  4. 组件化开发: 将页面划分为独立的组件,每个组件包含自己的 HTML 结构和样式,以实现更模块化、可重用的代码。

    1
    2
    3
    4
    5
    6
    7
    8
    <!-- 组件化开发 -->
    <div class="header">
    <!-- Header 组件 -->
    </div>

    <div class="footer">
    <!-- Footer 组件 -->
    </div>
  5. 工程化工具: 使用构建工具和任务运行器,如Webpack、Parcel 或者 Gulp,来优化、压缩和组织 CSS 代码,同时支持 CSS 模块化的开发流程。

CSS 模块化有助于团队协作,降低样式维护的复杂度,并提升项目的可维护性。选择适合项目需求的模块化方案,并在团队中建立一致的开发规范是保持代码质量的关键。


Q3:flexbox是什么?适用于什么场景

难度:⭐⭐

答案

Flexbox(Flexible Box)是一种用于布局设计的 CSS3 弹性盒子布局模型。它提供了一种更有效的方式来对容器内的子元素进行排列、对齐和分布,以适应各种屏幕尺寸和设备。Flexbox 的设计目标是在不同屏幕尺寸下,提供一种更加直观、灵活的布局方案。

Flexbox 的主要概念包括:

  1. 容器和项目: Flexbox 包含一个容器(display: flex;display: inline-flex;)和其内部的一组项目。

    1
    2
    3
    4
    5
    6
    7
    cssCopy code.container {
    display: flex;
    }

    .item {
    /* 子元素的样式 */
    }
  2. 主轴和交叉轴: Flexbox 中有主轴和交叉轴,主轴是 flex-direction 属性定义的方向,交叉轴则是与主轴垂直的轴。

    1
    2
    3
    4
    cssCopy code.container {
    flex-direction: row; /* 主轴方向为水平方向 */
    /* 或 flex-direction: column; 主轴方向为垂直方向 */
    }
  3. 弹性容器属性: Flexbox 提供了多个容器属性,例如 justify-content(主轴对齐方式)、align-items(交叉轴对齐方式)、flex-wrap(项目是否换行)等。

    1
    2
    3
    4
    cssCopy code.container {
    justify-content: space-between; /* 主轴上的项目分散对齐 */
    align-items: center; /* 交叉轴上的项目居中对齐 */
    }
  4. 弹性项目属性: Flexbox 提供了多个项目属性,例如 flex-grow(项目的放大比例)、flex-shrink(项目的缩小比例)、flex-basis(项目的初始大小)等。

    1
    2
    3
    cssCopy code.item {
    flex-grow: 1; /* 项目的放大比例为1,占据剩余空间 */
    }

Flexbox 适用于许多场景,特别是在以下情况下:

  • 均匀分布空间: 在容器中均匀分布项目,而不需要精确的尺寸或位置计算。
  • 动态尺寸: 适应不同屏幕尺寸,无论是横向还是纵向,都能够轻松调整布局。
  • 垂直居中: 在容器中垂直和水平居中项目。
  • 自适应空间分配: 在不同尺寸的屏幕上,自动适应空间分配,避免使用固定尺寸布局。


Q4:设备像素、css像素、设备独立像素、dpr、ppi之间有什么区别?

难度:⭐⭐⭐

答案
  1. 设备像素(Device Pixel):
    • 定义: 物理屏幕上的实际像素点。
    • 表示: 通常用于描述设备硬件的分辨率,例如 1920x1080 表示宽度为 1920 像素、高度为 1080 像素。
  2. CSS像素(CSS Pixel):
    • 定义: CSS 中使用的逻辑像素单位,用于衡量页面上的元素的尺寸。
    • 表示: 在不同设备上,CSS 像素的实际大小可以有所不同,取决于设备的像素密度(DPR)。
  3. 设备独立像素(Device-Independent Pixel):
    • 定义: 逻辑上的虚拟像素,是为了让开发者在不同设备上更一致地设置元素的尺寸而引入的概念。
    • 表示: 通常与 CSS 像素相等,但在高 DPI 屏幕上,一个设备独立像素可能对应多个物理设备像素。
  4. DPR(Device Pixel Ratio):
    • 定义: 设备像素和设备独立像素的比率,表示屏幕上每个 CSS 像素对应的设备像素数目。
    • 计算公式: DPR = 设备像素数 / 设备独立像素数。
  5. PPI(Pixels Per Inch):
    • 定义: 表示每英寸的物理屏幕上的像素数目,用于描述屏幕的像素密度。
    • 计算公式: PPI = √(设备像素宽^2 + 设备像素高^2) / 屏幕尺寸(以英寸为单位)。


Q5:对盒子模型的理解

难度:⭐

答案

盒子模型是CSS中用于描述网页元素尺寸和布局的概念。每个HTML元素都被视为一个矩形的”盒子”,这个盒子包含了内容、内边距、边框和外边距。这个模型定义了如何计算元素的总体尺寸,以及元素各个部分之间的关系。

盒子模型的主要组成部分包括:

  1. 内容区域(Content):
    • 定义: 包含元素的实际内容,比如文本、图像等。
    • 表示:widthheight属性决定。
  2. 内边距(Padding):
    • 定义: 包围在内容区域外部,与内容区域之间的空间。
    • 表示:padding属性决定,分为上、右、下、左四个方向。
  3. 边框(Border):
    • 定义: 包围在内边距外部,与内边距之间的空间,形成一个框。
    • 表示:border属性决定,包括宽度、样式和颜色。
  4. 外边距(Margin):
    • 定义: 包围在边框外部,与边框之间的空间,用于控制元素与其他元素之间的距离。
    • 表示:margin属性决定,分为上、右、下、左四个方向。

元素的总宽度和高度计算公式为:

总宽度=内容区域宽度+左右内边距+左右边框宽度+左右外边距

总高度=内容区域高度+上下内边距+上下边框宽度+上下外边距

在CSS中,有两种盒模型:标准盒模型和怪异盒模型。这两者的主要区别在于计算元素宽度和高度时是否包括内边距和边框。

  1. 标准盒模型(content-box):
    • 定义: 元素的宽度和高度仅包括内容区域,不包括内边距和边框。
    • 表示: widthheight属性仅表示内容区域的宽度和高度。
  2. 怪异盒模型(border-box):
    • 定义: 元素的宽度和高度包括内容区域、内边距和边框。
    • 表示: widthheight属性表示整个盒子(内容区域 + 内边距 + 边框)的宽度和高度。

在实际应用中,可以通过设置元素的 box-sizing 属性来指定使用哪种盒模型。例如,box-sizing: border-box; 表示使用怪异盒模型,而 box-sizing: content-box; 表示使用标准盒模型。默认情况下,大多数浏览器采用标准盒模型,但在一些旧版本的IE中,可能会采用怪异盒模型。选择适当的盒模型取决于设计的需求和布局的期望。


Q6:行内元素跟块级元素有什么区别

难度:⭐

答案

行内元素(Inline Elements):

  1. 默认布局: 行内元素不会独占一行,它们在同一行上显示,尽可能排满一行后换行。
  2. 宽度和高度: 行内元素的宽度和高度由其内容的大小决定。
  3. 不独占一行: 行内元素不会独占一行,相邻的行内元素会在同一行上显示,直到一行的空间不足,然后换行。
  4. 不能设置上下边距(margin): 行内元素上下的边距(margin)和内边距(padding)不会影响相邻元素,只有左右边距、内边距生效。

块级元素(Block Elements):

  1. 默认布局: 块级元素会独占一行,从新的一行开始,并且在前后都会产生换行。
  2. 宽度和高度: 块级元素的宽度默认为容器的100%,高度由内容决定。
  3. 独占一行: 块级元素会独占一行,相邻的块级元素会在不同行上显示。
  4. 可设置上下边距: 块级元素的上下边距(margin)和内边距(padding)会影响相邻元素的布局。

常见的行内元素:

  • <span>
  • <a>
  • <strong>
  • <em>
  • <img>
  • <br>

常见的块级元素:

  • <div>
  • <p>
  • <h1> - <h6>
  • <ul>, <ol>, <li>
  • <table>, <tr>, <td>
  • <form>


Q7:em\px\rem\vh\vw这些单位有什么区别

难度:⭐⭐

答案
  1. px(像素):
    • 像素是相对于显示器屏幕的最小单位,是一个固定的长度单位。
    • 在不同设备上,1px 的实际物理尺寸可能不同,因为设备的像素密度不同。
  2. em
    • 相对单位,是相对于父元素的字体大小(font-size)。
    • 如果应用在字体大小上,1em 等于当前元素的字体大小。
    • 如果应用在非字体大小的属性上,1em 等于父元素的字体大小。
  3. rem(根元素em):
    • 相对于根元素(html 元素)的字体大小。
    • 使用 rem 单位时,始终参照页面根元素的字体大小,不受嵌套影响。
  4. vh(视窗高度):
    • 相对于视窗(浏览器窗口)的高度的百分比。
    • 1vh 等于视窗高度的 1%。
  5. vw(视窗宽度):
    • 相对于视窗(浏览器窗口)的宽度的百分比。
    • 1vw 等于视窗宽度的 1%。

通常,相对单位(emrem)更适用于字体大小

绝对单位(px)和相对于视窗的单位(vhvw)更适用于布局和尺寸的定义


Q8:对CSS预编译语言的理解,以及他们之间的区别

难度:⭐⭐⭐

答案

CSS 预编译语言是一种在 CSS 基础上进行扩展的语言,它们允许开发者使用变量、嵌套、混入、函数等高级特性,以更模块化和可维护的方式组织样式代码。主要的 CSS 预编译语言包括 Sass、Less 和 Stylus。

Sass:

  1. 语法: Sass 有两种语法,一种是缩进式 Sass(.sass),另一种是 SCSS(Sassy CSS)(.scss),它与传统的 CSS 语法更为接近。

  2. 变量: 可以使用变量定义并引用。

    1
    2
    3
    4
    scssCopy code$primary-color: #3498db;
    body {
    background-color: $primary-color;
    }
  3. 嵌套: 允许嵌套规则,减少了重复的选择器。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    scssCopy codenav {
    ul {
    margin: 0;
    padding: 0;
    list-style: none;
    }
    li { display: inline-block; }
    a {
    text-decoration: none;
    padding: 6px 12px;
    }
    }
  4. 混入(Mixin): 允许定义可重用的样式块。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    scssCopy code@mixin border-radius($radius) {
    -webkit-border-radius: $radius;
    -moz-border-radius: $radius;
    border-radius: $radius;
    }

    button {
    @include border-radius(10px);
    }
  5. 函数: 提供内置函数和支持自定义函数。

    1
    2
    3
    4
    5
    6
    7
    scssCopy code@function px-to-em($px, $base-font-size: 16px) {
    @return ($px / $base-font-size) * 1em;
    }

    body {
    font-size: px-to-em(18px);
    }

Less:

  1. 语法: Less 采用与 CSS 更为相似的语法。

  2. 变量: 允许使用变量。

    1
    2
    3
    4
    lessCopy code@primary-color: #3498db;
    body {
    background-color: @primary-color;
    }
  3. 嵌套: 支持规则嵌套。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    lessCopy codenav {
    ul {
    margin: 0;
    padding: 0;
    list-style: none;
    }
    li { display: inline-block; }
    a {
    text-decoration: none;
    padding: 6px 12px;
    }
    }
  4. 混入(Mixin): 支持定义和使用混入。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    lessCopy code.border-radius(@radius) {
    -webkit-border-radius: @radius;
    -moz-border-radius: @radius;
    border-radius: @radius;
    }

    button {
    .border-radius(10px);
    }

Stylus:

  1. 语法: Stylus 采用非常简洁的语法,使用缩进而不是大括号。

  2. 变量: 可以使用变量。

    1
    2
    3
    stylCopy codeprimary-color = #3498db
    body
    background-color primary-color
  3. 嵌套: 支持规则嵌套。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    stylCopy codenav
    ul
    margin 0
    padding 0
    list-style none
    li
    display inline-block
    a
    text-decoration none
    padding 6px 12px
  4. 混入(Mixin): 支持定义和使用混入。

    1
    2
    3
    4
    5
    6
    7
    stylCopy codeborder-radius(radius)
    -webkit-border-radius radius
    -moz-border-radius radius
    border-radius radius

    button
    border-radius 10px

区别总结:

  1. 语法风格: Sass 和 Stylus 采用缩进式语法,而 Less 更接近传统 CSS 语法。
  2. 变量符号: Sass 使用 $,Less 使用 @,Stylus 不需要特定的符号。
  3. 嵌套规则: 所有三种预编译语言都支持规则嵌套,但在 Stylus 中,规则的嵌套是通过缩进实现的。
  4. 混入(Mixin): 三者都支持混入的概念,但在语法和使用上有一些差异。


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

难度:⭐⭐⭐

答案
  1. 回流(Reflow):
    • 回流是指浏览器为了重新渲染部分或全部文档而重新计算元素的位置和几何结构的过程。
    • 任何影响了元素几何属性(宽度、高度、位置等)的操作都会触发回流。
    • 回流的开销很大,因为它涉及到整个页面的布局重置,会导致渲染树的重新构建和页面的重新绘制。
  2. 重绘(Repaint):
    • 重绘是指浏览器根据元素的新样式重新绘制页面元素,但不会影响它们的布局。
    • 重绘的开销相对较小,因为它只涉及样式的改变和重新绘制。
  3. 触发回流和重绘的情况:
    • 回流的触发条件:
      • 添加或删除可见的 DOM 元素。
      • 元素的位置或尺寸发生变化。
      • 页面布局初始化。
      • 浏览器窗口大小发生变化。
    • 重绘的触发条件:
      • 修改元素的背景色、文字颜色等不影响布局的样式。
      • 修改元素的可见性、透明度等。
  4. 优化策略:
    • 使用 transformopacity 进行动画: 这两个属性的修改不会触发回流,只会引起重绘。
    • 避免直接操作样式: 尽量使用 CSS 类进行样式的切换,减少对元素样式的直接操作。
    • 批量修改 DOM: 对多个 DOM 元素进行修改时,最好将操作集中在一起,减少回流的次数。
    • 使用文档片段(DocumentFragment): 在内存中操作 DOM,然后一次性将变化的部分插入文档,减少回流和重绘。


Q10:说一说你对CSS工程化的理解

难度:⭐⭐⭐⭐

答案

为什么要工程化?

  1. 可维护性: 大型项目的样式表通常较为庞大,通过工程化可以模块化和组件化样式,提高代码的可维护性。
  2. 可拓展性: 工程化使得样式表能够轻松应对项目的扩展和变化,通过组件化和模块化的方式添加、修改或删除样式。
  3. 可复用性: 样式的组件化有助于提高样式的复用性,使得相似的样式能够在不同组件中共享,减少冗余代码。
  4. 协同开发: 团队协同开发中,工程化能够提供一致的代码规范和结构,降低团队成员之间的沟通成本。
  5. 性能优化: 自动化构建工具可以对样式进行压缩、合并、代码分割等优化,提高页面加载性能。

工程化实现方式及其解决的问题

  1. 模块化和组件化:
    • 实现方式: 使用 BEM(块、元素、修饰符)等命名规范,将样式表拆分为独立的模块或组件。
    • 解决问题: 提高代码的可读性和可维护性,降低样式冲突,使样式和组件之间的关系更加清晰。
  2. 预处理器:
    • 实现方式: 使用 Sass、Less 等预处理器引入变量、嵌套、混合等功能。
    • 解决问题: 提高样式的灵活性,减少代码量,使样式表更加易于维护。
  3. 自动化构建工具:
    • 实现方式: 使用 Webpack、Gulp 等构建工具对样式进行自动化处理。
    • 解决问题: 压缩、合并、前缀添加等,提高性能并确保兼容性。
  4. 代码规范检查:
    • 实现方式: 使用 Stylelint、ESLint 等工具进行代码规范检查。
    • 解决问题: 统一代码风格,提高代码质量。
  5. 版本控制:
    • 实现方式: 使用 Git 或其他版本控制系统对样式表进行版本管理。
    • 解决问题: 跟踪样式的变化,实现代码回滚和协同工作。
  6. 响应式设计:
    • 实现方式: 使用媒体查询等技术实现响应式设计。
    • 解决问题: 使样式适应不同设备和屏幕尺寸,提高用户体验。
  7. 文档:
    • 实现方式: 提供清晰的样式文档,描述每个模块和组件的样式规则。
    • 解决问题: 快速了解和使用样式,降低新成员的学习成本。


Q11:Sass、Less是什么?为什么要使用它们?

难度:⭐

解析

Sass:

  1. 特点:
    • 支持两种语法格式:Sass(缩进风格)和SCSS(类似于CSS的花括号风格)。
    • 引入了变量、嵌套规则、混合器、导入等功能。
    • 提供强大的控制结构,如条件语句和循环。
    • 有模块化的导入系统。
  2. 为什么使用Sass:
    • 更灵活的语法: Sass支持两种语法格式,可以选择更符合个人或团队的编码风格。
    • 丰富的功能: 提供了丰富的功能,如变量、混合器等,使得样式表更具表现力和可维护性。
    • 强大的控制结构: 支持条件语句和循环,增加了样式表的逻辑能力。
    • 社区支持: Sass有一个庞大的社区,提供了大量的资源和工具。

Less:

  1. 特点:
    • 类似CSS语法,较为轻量。
    • 支持变量、嵌套规则、混合器等基本功能。
    • 提供运算功能,可以进行数字计算。
    • 有模块化的导入系统。
  2. 为什么使用Less:
    • 低学习曲线: 由于Less语法较为接近原生CSS,对于初学者或迁移项目而言,学习曲线较低。
    • 轻量: 相对于Sass,Less的语法较为简单,适合一些对功能要求相对简单的项目。
    • 社区广泛: Less也有一个庞大的社区,提供了许多插件和工具。
答案

Sass(Syntactically Awesome Stylesheets)和Less都是CSS的预处理器,它们在CSS的基础上提供了一些额外的功能和语法糖,旨在提高CSS代码的可维护性、可读性和开发效率。以下是它们的一些特点和为什么要使用它们的原因:

为什么使用它们:

  1. 变量和可重用性: 可以使用变量定义颜色、字体等,提高代码的可维护性和可重用性。
  2. 嵌套规则: 嵌套规则可以更清晰地表示HTML结构,提高代码的可读性。
  3. 混合器: 可以定义和引用可重用的样式块,减少代码冗余。
  4. 导入机制: 可以将样式拆分为多个文件,通过导入的方式组织和管理样式。
  5. 更丰富的功能: 提供了条件语句、循环等功能,增加了样式表的逻辑能力。


Q12:硬件加速的原理是什么?

难度:⭐⭐

答案

硬件加速是指利用图形硬件(GPU)来加速页面渲染和动画效果的过程。硬件加速可以提高页面的性能和流畅度,特别是对于包含复杂图形和动画的应用。以下是Web前端硬件加速的原理:

  1. CSS 属性: 使用一些特定的CSS属性可以触发硬件加速。常见的属性包括 transformopacityfilter 等。这些属性可以将渲染任务交给GPU执行,提高性能。

    1
    2
    3
    4
    cssCopy code/* 例子:使用 transform 触发硬件加速 */
    .element {
    transform: translate3d(0, 0, 0);
    }
  2. 合成层: 浏览器会将某些元素单独创建为合成层(composite layer),这些层可以由GPU来处理。常见的触发合成层的方式包括使用3D变换、使用 will-change 属性等。

    1
    2
    3
    4
    cssCopy code/* 使用 will-change 属性触发合成层 */
    .element {
    will-change: transform;
    }
  3. 硬件加速 API: 浏览器提供了一些JavaScript API,允许开发者通过代码来触发硬件加速。例如,使用 requestAnimationFrame 函数可以让浏览器在下一次重绘时使用硬件加速。

    1
    2
    3
    4
    5
    6
    7
    javascriptCopy codefunction animate() {
    // 执行动画
    requestAnimationFrame(animate);
    }

    // 启动动画
    animate();
  4. 使用 Canvas 和 WebGL: Canvas 和 WebGL 是直接与GPU交互的技术,可以在Web页面上进行高性能的图形渲染。WebGL尤其适用于复杂的三维图形渲染。

硬件加速的原理是将某些渲染任务交给GPU处理,利用GPU的并行计算能力来加速图形渲染过程,从而提高页面的性能和响应速度。需要注意的是,滥用硬件加速可能导致性能问题,因此在使用硬件加速时要谨慎选择合适的场景和属性。


Q13:css动画跟js动画分别有什么优缺点?

难度:⭐⭐

答案
特性/优缺点CSS动画JavaScript动画
性能优化通常较好,可利用硬件加速可能存在性能开销,特别是在复杂动画或低性能设备上
简便易用对于基本动画效果,简单易用相对较灵活,编写复杂动画需要更多代码
灵活性有一定限制,难以实现复杂效果更灵活,能够实现复杂和定制化的动画效果
交互性较差,难以响应用户输入更好的交互性,可以根据用户输入调整动画状态
动态计算难以实现动态计算可以使用JavaScript进行动态计算
响应式可以响应页面样式变化需要手动处理样式变化的响应性
代码复杂性相对简单可能需要更多代码和调试

综合选择:

  1. 性能需求: 如果性能是首要考虑的因素,并且动画较简单,可以优先选择CSS动画。
  2. 复杂度要求: 对于复杂、高度定制的动画效果,尤其是需要用户交互的场景,JavaScript动画更为适用。
  3. 组合使用: 在一些场景中,CSS动画和JavaScript动画可以结合使用,发挥各自的优势,例如使用CSS实现基本动画,使用JavaScript进行交互和复杂计算。


Q14:前端实现动画有哪些方式?

难度:⭐⭐

答案
  1. CSS3 动画: 使用 CSS3 的 @keyframes 规则可以定义动画关键帧,然后通过将动画应用到元素上,实现基本的动画效果。
  2. CSS3 过渡(Transition): 利用 CSS3 过渡可以在元素的状态变化时实现平滑的过渡效果。通过设置过渡属性(如 transition-propertytransition-duration 等),在状态变化时自动产生动画效果。
  3. JavaScript 动画库: 使用 JavaScript 编写动画的库,如 GreenSock Animation Platform (GSAP)、anime.js 等。这些库提供了更高级的动画控制和更丰富的功能,适用于复杂的动画场景。
  4. Web Animation API: 是一组在 JavaScript 中控制动画的新 API,提供更多的灵活性和控制权,可以用于创建复杂的动画效果。
  5. Canvas 动画: 通过 HTML5 的 Canvas 元素,可以使用 JavaScript 绘制图形并实现动画效果。
  6. SVG 动画: 使用可缩放矢量图形(SVG)格式,结合 SMIL(Synchronized Multimedia Integration Language)或 JavaScript,实现矢量图形的动画效果。
  7. React Spring 等动画库: 针对 React 框架的动画库,可以方便地在 React 应用中实现动画。
  8. Three.js 等 3D 库: 用于创建基于 WebGL 的 3D 动画效果。


Q15:CSS为什么不支持父选择器?

难度:⭐⭐⭐

答案

CSS不直接支持父选择器的原因主要有两方面:

  1. 性能问题: 当浏览器解析 CSS 样式时,从右向左的匹配方式已经足够复杂,如果引入父选择器,会增加选择器的复杂性和计算成本。实现父选择器需要浏览器遍历整个文档树,找到每个元素的父元素,这样的计算对性能有较大影响。
  2. 样式层级问题: 父选择器可能导致样式层级的混乱。CSS 的层叠样式表(Cascading Style Sheets)的核心思想是层叠和继承,样式应该具有继承性,而引入父选择器可能导致样式的来源变得不清晰,使得样式层级难以理解和维护。

虽然 CSS 不直接支持父选择器,但通过其他手段,如使用 JavaScript 或一些预处理器(如 Sass 或 Less)可以达到一些类似的效果。未来可能会有一些新的 CSS 特性或选择器引入,但需要权衡性能和可维护性。


Q16:脱离文档流有哪些方法?

难度:⭐

答案

脱离文档流是指元素不再按照正常的文档流排列,而是脱离文档流独立定位。以下是一些脱离文档流的常见方法:

  1. position 属性:
    • position: absolute;:使元素脱离文档流,并相对于其最近的非 static 定位的祖先元素定位。
    • position: fixed;:使元素脱离文档流,并相对于浏览器窗口定位,不随页面滚动而变化。
    • position: relative;:使元素脱离文档流,但仍然占据原来的位置,相对于其正常位置进行定位。
  2. float 属性: 使用 float: left;float: right; 可以使元素脱离文档流并向左或向右浮动。不过,浮动元素仍然会影响文档流中的其他元素。
  3. display 属性:
    • display: none;:元素不可见,但不仅脱离文档流,还不占据空间。
    • display: inline-block;:使元素脱离文档流,并允许设置宽度和高度,但仍然保持行内元素的特性。
  4. flexbox 和 grid 布局:
    • 使用 display: flex;display: grid; 可以创建弹性盒子或网格布局,这些布局可以使元素脱离文档流,并按照不同的规则进行排列。
  5. position: absolute; 结合 transform: translate(-50%, -50%);:这种方式可以使元素相对于其父元素的中心定位,同时脱离文档流。


Q17:css的sprites是什么?怎么使用

难度:⭐

答案

CSS Sprites是一种将多个小图标或图片合并到一个单一图像文件中的技术。通过使用CSS的background-position属性,可以在页面上显示所需的图标或图片。这样做的主要目的是减少页面的HTTP请求数量,从而提高页面加载性能。

使用CSS Sprites的步骤如下:

  1. 准备图像: 将所有需要使用的小图标或图片合并成一个大图像。这个大图像通常称为雪碧图(Spritesheet)。

  2. 创建CSS样式: 使用CSS样式来定义每个小图标在雪碧图中的位置。通过设置background-position属性,指定每个小图标在雪碧图中的偏移位置。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    cssCopy code.icon1 {
    background-image: url('spritesheet.png');
    background-position: 0 0; /* 第一个图标的位置 */
    }

    .icon2 {
    background-image: url('spritesheet.png');
    background-position: -30px 0; /* 第二个图标的位置 */
    }

    /* 更多图标的样式 */
  3. 应用样式: 在HTML中使用相应的样式类来显示对应的图标。

    1
    2
    3
    htmlCopy code<div class="icon1"></div>
    <div class="icon2"></div>
    <!-- 其他图标的HTML -->

通过将多个图标合并成一个雪碧图,可以减少HTTP请求,提高页面加载速度。这对于移动端和需要快速加载的网页尤为重要。然而,使用CSS Sprites也需要考虑维护性和可扩展性,因为修改图标或添加新图标可能需要更新样式表。


Q18 :Atom Css是什么?

难度:⭐⭐⭐

答案

一种遵循原子设计原则的 CSS 模式,那么我们可以理解为这是一种采用原子化的 CSS 类,每个类都负责执行一个特定的样式任务,以便更好地组合和复用样式。

优点:

  1. 可维护性: 将样式拆分为原子类可以使代码更模块化和可维护。每个类都负责一个特定的样式,使得修改和扩展样式更加容易。
  2. 可重用性: 可以将原子类应用于多个元素,实现样式的可重用性。这有助于减少冗余的样式代码。
  3. 灵活性: 每个原子类都代表一个小的、独立的样式单元,可以在不影响其他部分的情况下进行修改。

缺点:

  1. 复杂性: 在一些情况下,使用过多的原子类可能导致样式表变得庞大且难以理解。过度的原子化可能会增加代码的复杂性。
  2. 学习曲线: 对于新来的开发者,理解和熟悉原子类的命名规范可能需要一些时间。
  3. 性能: 在某些情况下,使用过多的原子类可能导致页面加载时的样式表大小过大,从而影响性能。这可能需要通过一些工具进行优化。


Q19:CSS3新增了什么特性?

难度:⭐

答案
  1. 选择器
    • 更多的属性选择器,如 :nth-child:not 等。
    • 伪类选择器的增强,如 :hover:focus:active 等。
  2. 盒模型
    • 圆角边框(border-radius)。
    • 阴影效果(box-shadow)。
    • 盒阴影效果(text-shadow)。
  3. 背景和渐变
    • 线性渐变(linear-gradient)和径向渐变(radial-gradient)。
    • 多重背景图像(background-image)。
  4. 颜色和透明度
    • RGBA 和 HSLA 颜色表示法。
    • opacity 属性。
  5. 字体
    • Web 字体(@font-face)。
    • 字体阴影(text-shadow)。
  6. 文本效果
    • 文本渲染(text-rendering)。
    • 文本溢出处理(text-overflow)。
  7. 2D 转换和变形
    • transform 属性,包括平移、旋转、缩放等。
    • transition 属性,用于实现平滑过渡效果。
  8. 3D 转换
    • perspective 属性和 3D 变形。
  9. 动画
    • @keyframes 规则,用于定义动画序列。
    • animation 属性,用于应用动画。
  10. 多列布局
    • column-countcolumn-width 等属性,用于实现多列布局。
  11. Flexbox 弹性盒子布局
    • display: flex,用于创建弹性容器。
    • flex 属性,用于指定项目的放大比例。
  12. 网格布局
    • display: grid,用于创建网格容器。
    • grid-template-rowsgrid-template-columns 等属性。
  13. 过渡效果
    • transition 属性,用于在鼠标事件触发时实现平滑过渡。


属性

Q1:flex布局下怎么改变元素的顺序?

难度:⭐

答案

在Flex布局中,你可以使用order属性来改变元素的顺序。默认情况下,所有的元素的order值都是0,表示它们按照源代码的顺序排列。通过为元素设置不同的order值,你可以改变它们在Flex容器中的显示顺序。

order的取值可以是任意整数,负数也可以。order值越小,元素越靠前。

下面是一个简单的例子:

1
2
3
4
5
6
<div class="flex-container">
<div class="item">1</div>
<div class="item" style="order: 3;">3</div>
<div class="item" style="order: -1;">2</div>
<div class="item">4</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
.flex-container {
display: flex;
}

.item {
width: 50px;
height: 50px;
border: 1px solid #000;
margin: 5px;
display: flex;
align-items: center;
justify-content: center;
}

在这个例子中,元素2的order值为-1,所以它会在元素1的前面;元素3的order值为3,所以它会在元素4的后面。

请注意,order属性仅改变布局显示的顺序,而不改变文档流中的实际顺序。


Q2:flex: auto是什么意思?

难度:⭐

答案

在Flex布局中,flex: auto是一种设置flex属性的快捷方式,它表示元素应该根据其剩余空间来分配主轴空间。

具体来说,flex: auto将元素的flex-grow属性设置为1,表示该元素在主轴上会根据剩余空间进行拉伸,尽可能地占据可用空间。这通常用于使一些项目占据剩余空间,而其他项目则根据它们的内容或固定尺寸来分配空间。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.container {
display: flex;
}

.item1 {
flex: auto;
/* 或者使用 flex: 1; */
background-color: red;
}

.item2 {
/* 这个项目将根据内容占据空间,不会拉伸 */
background-color: blue;
}

在这个例子中,.item1将占据剩余空间,而.item2将根据其内容占据空间,而不会拉伸。使用flex: auto可以方便地实现这种效果,而无需手动设置flex-grow的值。


Q3:Object-fit的用法是什么

难度:⭐⭐

答案

object-fit是一个用于指定替换元素(例如<img><video>等)的内容如何适应其容器的 CSS 属性。它可以控制替换元素的尺寸、位置以及是否裁剪。

  1. object-fit: fill;

    • 使替换元素的内容完全填充容器,不保持宽高比例。内容可能会变形以适应容器。
    1
    2
    3
    img {
    object-fit: fill;
    }
  2. object-fit: contain;

    • 保持内容的宽高比例,确保整个内容都能完整显示在容器内,可能在容器内有留白。
    1
    2
    3
    img {
    object-fit: contain;
    }
  3. object-fit: cover;

    • 保持内容的宽高比例,使内容填充整个容器,可能会裁剪内容。
    1
    2
    3
    img {
    object-fit: cover;
    }
  4. object-fit: scale-down;

    • containcover的结合,选择更小的尺寸,以保持内容完整显示在容器内。
    1
    2
    3
    img {
    object-fit: scale-down;
    }
  5. inherit

    • 继承父元素的 object-fit 属性值。
    1
    2
    3
    img {
    object-fit: inherit;
    }
  6. initial

    • object-fit 属性重置为默认值,即 fill
    1
    2
    3
    img {
    object-fit: initial;
    }
  7. revert

    • 如果元素有继承的值,则等同于 inherit;否则等同于 initial
    1
    2
    3
    img {
    object-fit: revert;
    }
  8. revert-layer

    • revert 类似,但是更适用于多层嵌套的场景,用于在继承时恢复之前的层级关系。
    1
    2
    3
    img {
    object-fit: revert-layer;
    }
  9. unset

    • object-fit 属性重置为其父元素的属性值,如果没有继承值,则等同于 initial
    1
    2
    3
    img {
    object-fit: unset;
    }


Q4:transition和animation的属性分别有哪些?

难度:⭐⭐

答案

transitionanimation 是用于实现 CSS 动画效果的两个属性,它们有一些共同点,但也有一些不同之处。

transition 属性:

transition 属性是用于在元素状态改变时平滑过渡效果的 CSS 属性。它需要指定以下几个关键属性:

  • property 规定要过渡的 CSS 属性的名称。
  • duration 规定过渡效果的持续时间(以秒或毫秒为单位)。
  • timing-function 规定过渡效果的时间曲线。
  • delay 规定过渡效果何时开始。
1
2
3
4
cssCopy code/* 例子 */
.element {
transition: property duration timing-function delay;
}

animation 属性:

animation 属性允许你创建自定义的动画效果,它需要指定以下几个关键属性:

  • name 规定 @keyframes 动画的名称。
  • duration 规定动画的持续时间(以秒或毫秒为单位)。
  • timing-function 规定动画的时间曲线。
  • delay 规定动画何时开始。
  • iteration-count 规定动画播放的次数。
  • direction 规定是否轮流反向播放动画。
  • fill-mode 规定在动画之前和之后如何将样式应用于元素。
  • play-state 规定动画是运行还是暂停。
1
2
3
4
cssCopy code/* 例子 */
.element {
animation: name duration timing-function delay iteration-count direction fill-mode play-state;
}

这些属性的详细说明如下:

  • property (transition): 规定要过渡的 CSS 属性的名称,如 widthheight 等。
  • duration (transition/animation): 规定过渡或动画效果的持续时间。
  • timing-function (transition/animation): 规定过渡或动画效果的时间曲线,例如 easelinear 等。
  • delay (transition/animation): 规定过渡或动画效果何时开始。
  • name (animation): 规定 @keyframes 动画的名称。
  • iteration-count (animation): 规定动画播放的次数,可以使用 infinite 无限播放。
  • direction (animation): 规定是否轮流反向播放动画,可选值有 normalreversealternatealternate-reverse
  • fill-mode (animation): 规定在动画之前和之后如何将样式应用于元素,可选值有 noneforwardsbackwardsboth
  • play-state (animation): 规定动画是运行还是暂停,可选值有 runningpaused

区别点

特性transitionanimation
触发时机元素状态变化时触发,如悬停、获得焦点等任意时间点都可触发
适用性适用于简单的状态变化,如颜色、位置、大小等适用于复杂的、连续的动画效果
定义方式指定状态变化属性和过渡时间,不需要关键帧通过定义关键帧(keyframes)描述整个动画过程
循环播放默认执行一次,不支持循环可以通过设置animation-iteration-count属性实现循环
性能相对较轻量,适用于简单状态变化在复杂动画可能更耗费性能
控制可以通过JavaScript改变元素的类或样式触发通过JavaScript可以更精细地控制动画
示例transition: width 1s ease;animation: myAnimation 2s infinite;


Q5:::before跟::after这两个选择器有两个冒号跟一个冒号有什么区别跟作用?

难度:⭐

答案

::before::after 是 CSS 伪元素选择器,它们用于在元素的内容前面和后面生成虚拟的元素,并通过样式进行装饰或添加内容。

  1. 冒号数量:
    • :before:after 是 CSS2 中引入的伪元素选择器。
    • ::before::after 是 CSS3 中引入的双冒号语法,用于明确区分伪元素和伪类,增加语法的规范性。
  2. 区别:
    • 在实际使用中,单冒号和双冒号在大多数浏览器中可以互换使用,因为现代浏览器已经广泛支持双冒号语法。
    • 双冒号语法是为了与伪类区分,更明确表示它们是伪元素而不是伪类。
  3. 作用:
    • ::before 用于在元素内容前生成一个虚拟元素。
    • ::after 用于在元素内容后生成一个虚拟元素。

示例:

1
2
3
4
5
6
7
8
9
cssCopy code/* 使用单冒号语法 */
.element:before {
content: "Before";
}

/* 使用双冒号语法 */
.element::after {
content: "After";
}

在上述示例中,.element 元素的前面生成一个包含文本 “Before” 的虚拟元素,后面生成一个包含文本 “After” 的虚拟元素。使用单冒号或双冒号的效果是一样的,但为了符合最新的规范,推荐使用双冒号语法。


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

难度:⭐⭐⭐

答案

z-index 是用于控制元素的层叠顺序的 CSS 属性,但有一些情况下它可能表现得不如预期,失效的情况主要与文档流的特性和元素的定位方式有关:

  1. 未定位元素: z-index 只对定位元素(相对定位、绝对定位、固定定位)有效。如果一个元素没有被定位,设置 z-index 不会产生层叠效果。

    1
    2
    3
    .unpositioned {
    z-index: 999; /* 不会生效 */
    }
  2. 父元素 z-index 影响子元素: 如果子元素的 z-index 大于父元素的 z-index,在父元素的范围内仍然无法超越父元素的层叠顺序。

    1
    2
    3
    4
    5
    <div class="parent" style="z-index: 1;">
    <div class="child" style="z-index: 999;"> <!-- 不会超越父元素的层叠顺序 -->
    <!-- content -->
    </div>
    </div>
  3. 普通流中的元素: z-index 只对定位元素有效,对于普通流中的元素,即使设置了 z-index,也无法改变其默认的层叠顺序。

    1
    2
    3
    .normal-flow {
    z-index: 999; /* 不会生效 */
    }
  4. 定位方式为 static 如果元素的定位方式是 static(默认值),即使设置了 z-index 也不会生效。需要将元素的定位方式改为相对定位、绝对定位或固定定位。

    1
    2
    3
    .static-position {
    z-index: 999; /* 不会生效 */
    }


Q7:position:fixed一定是根据浏览器窗口去定位的吗?

难度:⭐⭐⭐

答案

position: fixed; 不一定是根据浏览器窗口去定位的,它是相对于最近的具有定位(非 static)属性的父元素进行定位的。如果没有符合条件的父元素,那么它将相对于初始包含块进行定位,而初始包含块通常是浏览器视口。

所以,position: fixed; 的定位参考点可能是:

  1. 最近的具有定位(非 static)属性的父元素:

    1
    2
    3
    4
    5
    <div style="position: relative;">
    <div style="position: fixed; top: 10px; left: 10px;">
    <!-- 内容 -->
    </div>
    </div>
  2. 如果没有符合条件的父元素,相对于初始包含块:

    1
    2
    3
    <div style="position: fixed; top: 10px; left: 10px;">
    <!-- 内容 -->
    </div>


Q8:css选择器有哪一些?它们的优先级顺序是什么?有什么属性是可以继承的?什么属性是不可以继承的?

难度:⭐⭐⭐

答案
  1. 元素选择器:

    1
    2
    3
    div {
    /* styles */
    }
  2. 类选择器:

    1
    2
    3
    .classname {
    /* styles */
    }
  3. ID 选择器:

    1
    2
    3
    #idname {
    /* styles */
    }
  4. 属性选择器:

    1
    2
    3
    [attribute="value"] {
    /* styles */
    }
  5. 伪类选择器:

    1
    2
    3
    :hover {
    /* styles */
    }
  6. 伪元素选择器:

    1
    2
    3
    ::before {
    /* styles */
    }
  7. 子元素选择器:

    1
    2
    3
    parent > child {
    /* styles */
    }
  8. 相邻兄弟选择器:

    1
    2
    3
    element + element {
    /* styles */
    }
  9. 通用选择器:

    1
    2
    3
    * {
    /* styles */
    }

CSS 选择器的优先级顺序如下:

  1. 内联样式(Inline styles): 优先级最高,直接在元素上使用 style 属性设置的样式。
  2. ID 选择器(#id): 优先级高于类选择器和元素选择器。
  3. 类选择器(.class)、属性选择器、伪类选择器: 优先级相同,按照出现的顺序计算。
  4. 元素选择器、伪元素选择器、子元素选择器、相邻兄弟选择器: 优先级相同,按照出现的顺序计算。
  5. 通用选择器(*)、继承: 优先级最低,只有在前面的规则没有设置样式时才会应用。

属性可继承的特性包括:

  • 字体系列(font-family)
  • 字体大小(font-size)
  • 字重(font-weight)
  • 行高(line-height)
  • 字体样式(font-style)
  • 颜色(color)
  • 文本缩进(text-indent)

属性不可继承的特性包括:

  • 边框(border)
  • 外边距(margin)
  • 内边距(padding)
  • 宽度(width)
  • 高度(height)
  • 背景(background)
  • 定位属性(position)
  • 浮动属性(float)
  • 清除浮动(clear)


Q9 :为什么有时候用translate来改变元素位置而不是position

难度:⭐⭐

答案

使用translate来改变元素位置相比于position属性具有一些优势,主要体现在性能和动画效果方面:

  1. 硬件加速: 使用translate可以触发硬件加速,这意味着浏览器会使用GPU来处理元素的变换,从而提高动画的性能。相比之下,使用position属性可能触发软件渲染,性能较差。
  2. 不影响文档流: translate对文档流没有影响,元素的位置变化不会引起文档重新布局(reflow),因此在动画过程中不会触发性能消耗较大的重排操作。
  3. 更平滑的动画效果: 由于translate是在合成阶段进行的,相对于使用position的动画效果更加平滑,没有闪烁或抖动。
  4. 更容易实现复杂动画: 使用translate可以方便地实现复杂的动画效果,例如平移、旋转、缩放等可以同时进行的变换,而不需要使用多个position属性来实现。
  5. 响应式设计: translate可以更方便地应用于响应式设计,因为它不依赖于具体的像素值,而是相对于元素自身或其父元素的尺寸。

尽管translate在某些情况下更有优势,但在一些需要精准控制布局的场景下,使用position可能更为合适


Q10:下面这段代码class为content的div高度是多少

难度:⭐

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<style>
.parent {
display: flex;
flex-direction: column;
height: 600px;
width: 300px;
background: yellow;
}
div {
width: 100%;
}
.header {
height: 200px;
background: red;
}
.content {
height: 100%;
background: blue;
}
.footer {
height: 200px;
background: black;
}
</style>

<body>
<div class="parent">
<div class="header"></div>
<div class="content"></div>
<div class="footer"></div>
</div>
</body>
解析

首先,content元素的 height 设置为 “100%”,在父级的高度为固定值时,直接继承该高度,也就是600px。

但父级设置了 display:flex ,在高度固定的前提下,子元素的高度会按比例进行缩放,所以content元素最后的高度应该是 600 * (600/(200+600+200)) = 360px

答案

600px


Q11:P标签的背景色是什么?

难度:⭐

1
2
3
4
5
6
7
8
9
10
<style type="text/css">
#parent p { background-color: red; }
div .a.b.c.d.e.f.g.h.i.j.k p{ background-color: green;
</style>
......
<div id="parent">
<div class="a b c d e f g h i j k">
<p>xxxx</p>
</div>
</div>
答案

权重是按优先级进行比较的,而不是相加规则。

red


Q12:下面的样式都作用域同一个span,哪个会生效?

难度:⭐

1
2
body#god div.dad span.son {width: 200px;}
body#god span#test {width: 250px;}
解析
  • 先比较高权重位,即第一个样式的高权重为 #god = 100
  • 第二个样式的高权重为 #god + #text = 200
  • 100 < 200
  • 所以最终计算结果是取 width: 250px;
  • 若两个样式的高权重数量一样的话,则需要比较下一较高权重!
答案

width: 250px;


Q13:第二个子元素高度是多少?

难度:⭐

1
2
3
4
5
6
7
8
9
10
11
12
<div class="container">
<div style="height: 100px"></div>
<div style="min-height: 10px"></div>
</div>
<style>
.container{
display: flex;
}
.container > div {
width: 100px;
}
</style>
解析

Flex 布局会默认:

  • 把所有子项变成水平排列。
  • 默认不自动换行。
  • 让子项与其内容等宽,并把所有子项的高度变为最高子项的高度。
答案

100px


Q14:如何从html元素继承box-sizing?

难度:⭐

答案

要从 HTML 元素继承 box-sizing 属性,可以使用全局选择器,将 box-sizing 应用到所有元素。以下是一个例子:

1
2
3
4
5
6
7
cssCopy codehtml {
box-sizing: border-box;
}

*, *::before, *::after {
box-sizing: inherit;
}

在这个例子中,首先将 html 元素的 box-sizing 设置为 border-box,表示所有元素的宽度和高度都包含内边距和边框。然后,通过 * 通用选择器,以及 ::before::after 伪元素选择器,将 box-sizing 继承设置为 inherit,确保所有元素及其伪元素都继承了相同的 box-sizing 值。

这样设置可以确保整个页面中的所有元素都采用相同的 box-sizing 规则,方便进行一致的布局计算。


Q15:position:absolute绝对定位是相对于谁的定位?

难度:⭐

答案

position: absolute; 绝对定位是相对于其最近的非 static 定位的祖先元素进行定位的。如果不存在这样的祖先元素,则相对于初始包含块(通常是视口)进行定位。

简而言之,绝对定位的元素会找到离它最近的具有定位属性(非 static)的祖先元素,然后相对于该祖先元素进行定位。如果没有找到这样的祖先元素,它将相对于初始包含块进行定位。


Q16:display有哪些取值?

难度:⭐

答案
  1. block(块级元素)

    • 元素生成一个块级框。
    • 块级元素会在新行上开始,并占据其父容器的整个宽度。
    1
    display: block;
  2. inline(行内元素)

    • 元素生成一个行内框。
    • 行内元素不会开始新行,仅占据其内容的宽度。
    1
    display: inline;
  3. inline-block(行内块级元素)

    • 元素生成一个行内块级框。
    • 行内块级元素可以设置宽度和高度,同时保持在同一行。
    1
    display: inline-block;
  4. flex(弹性容器)

    • 元素成为一个弹性容器。
    • 子元素成为弹性项目,可以通过flex属性进行布局。
    1
    display: flex;
  5. grid(网格容器)

    • 元素成为一个网格容器。
    • 子元素成为网格项,可以通过grid属性进行布局。
    1
    display: grid;
  6. inline-flex(行内弹性容器)

    • 元素成为一个行内弹性容器。
    1
    display: inline-flex;
  7. inline-grid(行内网格容器)

    • 元素成为一个行内网格容器。
    1
    display: inline-grid;
  8. none(隐藏元素)

    • 元素不会在页面中生成框,完全不可见。
    1
    display: none;


Q17:CSS中的flex:1是什么意思?

难度:⭐

答案

在CSS中,flex: 1是用于设置Flexbox布局中flex项的缩放比例的一种简写形式。具体来说,它是flex-grow, flex-shrink, 和 flex-basis这三个属性的缩写。

  • flex-grow: 决定了flex项在主轴上的扩展比例。如果所有的flex项都设置了flex-grow,它们的值将决定它们相对于其他项在可用空间中的分配比例。flex-grow默认值为0,表示不进行扩展。
  • flex-shrink: 决定了flex项在主轴上的收缩比例。如果所有的flex项都设置了flex-shrink,它们的值将决定它们相对于其他项在空间不足时的收缩比例。flex-shrink默认值为1,表示可以进行收缩。
  • flex-basis: 指定了flex项在主轴上的初始大小。它可以是一个长度值(如像素或百分比)或关键字autoflex-basis默认值为auto

因此,flex: 1等同于设置flex: 1 1 0,表示该flex项会根据可用空间进行扩展和收缩,初始大小为0。这通常用于让flex项平均分配可用空间。


Q18:CSS3新增的伪类有哪些?

难度:⭐

答案

CSS3新增的伪类有很多,以下是一些常用的CSS3新增伪类:

  1. :nth-child(n):选择父元素下的第n个子元素。
  2. :nth-last-child(n):选择父元素下的倒数第n个子元素。
  3. :nth-of-type(n):选择父元素下的特定类型的第n个子元素。
  4. :nth-last-of-type(n):选择父元素下的特定类型的倒数第n个子元素。
  5. :first-child:选择父元素下的第一个子元素。
  6. :last-child:选择父元素下的最后一个子元素。
  7. :first-of-type:选择父元素下的特定类型的第一个子元素。
  8. :last-of-type:选择父元素下的特定类型的最后一个子元素。
  9. :only-child:选择父元素下是唯一子元素的元素。
  10. :only-of-type:选择父元素下是唯一特定类型子元素的元素。
  11. :empty:选择没有子元素的元素。
  12. :not(selector):选择除了指定选择器匹配的元素之外的所有元素。
  13. :target:选择当前活动的目标元素。
  14. :checked:选择表单中被选中的radio或checkbox元素。
  15. :enabled:选择表单中可用的元素。
  16. :disabled:选择表单中不可用的元素。
  17. :required:选择表单中必填的元素。
  18. :optional:选择表单中非必填的元素。
  19. :hover:选择鼠标悬停的元素。
  20. :focus:选择获取焦点的元素。


功能实现

Q1:单行文本怎么实现两端对齐?

难度:⭐

答案
  1. 使用 text-align: justify;

    1
    2
    3
    4
    5
    6
    7
    .container {
    text-align: justify;
    text-align-last: justify;
    }
    .text {
    display: inline-block;
    }
  2. 使用伪元素 ::after

    1
    2
    3
    4
    5
    .container::after {
    content: '';
    display: inline-block;
    width: 100%;
    }
  3. 使用弹性盒子(Flexbox):

    1
    2
    3
    4
    .container {
    display: flex;
    justify-content: space-between;
    }
  4. 使用网格布局(Grid):

    1
    2
    3
    4
    .container {
    display: grid;
    grid-template-columns: 1fr auto;
    }


Q2:怎么让浏览器支持小于12px的字

难度:⭐⭐

答案
  1. 使用相对单位 remem

    1
    2
    3
    4
    5
    6
    7
    cssCopy codebody {
    font-size: 16px; /* 设置基本字体大小 */
    }

    .small-text {
    font-size: 0.75em; /* 相对于基本字体大小的相对单位 */
    }
  2. 使用 font-smooth CSS 属性:

    1
    2
    3
    4
    5
    cssCopy code.small-text {
    font-size: 11px;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    }
  3. 使用字体重置或规范化工具: 在 HTML 文件中引入 Normalize.css 或其他类似的工具,以确保浏览器默认样式更一致。

    1
    2
    htmlCopy code<!-- 引入 Normalize.css -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css" />
  4. 使用浏览器默认样式: 对于某些浏览器,默认字体大小可能已经支持小于 12px。在没有明显问题的情况下,可以尝试使用浏览器默认样式。

  5. 使用图标字体或 SVG: 对于小尺寸的图标或文本,考虑使用图标字体或 SVG 图片,而不是小字体。这有助于确保清晰度和可读性。


Q3:怎么实现两栏布局,右侧或者左侧自适应?三栏布局中间自适应?这两种布局分别由多少种不同的实现方法?

难度:⭐

答案

两栏布局(右侧或左侧自适应)

1
2
3
4
<div class="container">
<div class="sidebar">左侧栏</div>
<div class="main-content">主内容</div>
</div>
  1. 使用浮动布局

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    .container {
    width: 100%;
    }

    .sidebar {
    width: 200px;
    float: left;
    }

    .main-content {
    margin-left: 200px; /* 左侧栏宽度 */
    }
  2. 使用flex布局

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    .container {
    display: flex;
    }

    .sidebar {
    width: 200px;
    }

    .main-content {
    flex: 1; /* 自适应剩余空间 */
    }
  3. 使用grid布局

    1
    2
    3
    4
    .container {
    display: grid;
    grid-template-columns: 200px 1fr; /* 左侧栏宽度和剩余空间 */
    }

三栏布局(中间自适应)

1
2
3
4
5
<div class="container">
<div class="sidebar-left">左侧栏</div>
<div class="main-content">主内容</div>
<div class="sidebar-right">右侧栏</div>
</div>
  1. 使用浮动布局

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    .container {
    width: 100%;
    }

    .sidebar-left,
    .sidebar-right {
    width: 200px;
    float: left;
    }

    .main-content {
    margin-left: 200px; /* 左侧栏宽度 */
    margin-right: 200px; /* 右侧栏宽度 */
    }
  2. 使用flex布局

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    .container {
    display: flex;
    }

    .sidebar-left,
    .sidebar-right {
    width: 200px;
    }

    .main-content {
    flex: 1; /* 自适应剩余空间 */
    }
  3. 使用grid布局

    1
    2
    3
    4
    .container {
    display: grid;
    grid-template-columns: 200px 1fr 200px; /* 左侧栏宽度、剩余空间、右侧栏宽度 */
    }


Q4:怎么实现样式隔离?

难度:⭐⭐⭐

答案

样式隔离是指在Web开发中,确保一个组件的样式不会影响到其他组件,以避免全局污染和样式冲突的问题。以下是几种实现样式隔离的方法:

  1. 命名约定:
    • 原理: 通过为每个组件或模块定义独特的类名或ID,确保样式选择器的命名具有足够的唯一性。
    • 优点: 简单易行,不需要额外的工具或技术。
    • 缺点: 依赖于命名规范的严格性,容易出现冲突。
  2. BEM(Block Element Modifier):
    • 原理: 使用BEM命名约定,将组件分解为块(Block)、元素(Element)、修饰符(Modifier)三个部分,形成类名的层级结构,提高命名的唯一性。
    • 优点: 易于维护,提高了样式命名的可读性和可维护性。
    • 缺点: 类名相对较长,可能造成HTML文件的冗余。
  3. CSS Modules:
    • 原理: 使用CSS Modules工具,可以将CSS文件中的类名和选择器进行局部作用域的绑定,确保只在当前组件中生效。
    • 优点: 实现了真正的样式隔离,避免了全局命名冲突。
    • 缺点: 需要构建工具的支持,如Webpack。
  4. Scoped CSS:
    • 原理: 使用一些前端框架提供的scoped或module化的样式功能,例如Vue的<style scoped>或React的styled-components
    • 优点: 框架内置,使用方便,可以避免手动处理样式隔离。
    • 缺点: 依赖于具体的前端框架,可能不够灵活。
  5. Shadow DOM:
    • 原理: 使用Web标准中的Shadow DOM技术,创建一个封闭的、隔离的DOM子树,其中的样式只在Shadow DOM内部生效。
    • 优点: 提供了真正的DOM和样式隔离,适用于Web组件。
    • 缺点: 目前在所有浏览器中的兼容性还不完全,需要谨慎使用。


Q5:怎么实现单行/多行文本溢出的省略样式?

难度:⭐⭐

答案

单行文本溢出省略:

1
2
3
<div class="single-line">
This is a long single-line text that will be truncated with an ellipsis.
</div>
1
2
3
4
5
.single-line {
white-space: nowrap; /* 禁止换行 */
overflow: hidden; /* 溢出内容隐藏 */
text-overflow: ellipsis; /* 显示省略号 */
}

多行文本溢出省略:

1
2
3
<div class="multi-line">
<p>This is a long multi-line text that will be truncated with an ellipsis after three lines.</p>
</div>
1
2
3
4
5
6
7
.multi-line {
display: -webkit-box; /* 将元素作为弹性伸缩盒模型显示 */
-webkit-box-orient: vertical; /* 垂直方向排列 */
overflow: hidden; /* 溢出内容隐藏 */
text-overflow: ellipsis; /* 显示省略号 */
-webkit-line-clamp: 3; /* 限制行数 */
}

在多行文本溢出的情况下,使用 -webkit-line-clamp 可以指定最大行数,但该属性目前仅在 WebKit 内核的浏览器(如 Chrome 和 Safari)中支持。在其他浏览器中,你可能需要使用一些 JavaScript 或其他方法来实现多行文本的溢出省略效果。


Q6:css有什么方式可以隐藏页面元素?这几种方式都有什么区别?

难度:⭐

答案
  1. display: none;

    • 完全从布局中移除元素,不占据任何空间。
    • 元素及其子元素都不可见,不会渲染。
    • 通过修改display属性可以重新显示元素。
    1
    2
    3
    cssCopy code.hidden-element {
    display: none;
    }
  2. visibility: hidden;

    • 元素仍占据布局空间,但变为不可见。
    • 元素及其子元素在页面中仍有位置,但内容不可见。
    • 通过修改visibility属性可以重新显示元素。
    1
    2
    3
    cssCopy code.hidden-element {
    visibility: hidden;
    }
  3. opacity: 0;

    • 元素保留其位置和布局,但变为完全透明。
    • 元素及其子元素在页面中仍占据空间,但内容不可见。
    • 通过修改opacity属性可以重新显示元素。
    1
    2
    3
    cssCopy code.hidden-element {
    opacity: 0;
    }
  4. position: absolute; + left: -9999px;

    • 将元素移动到视口之外,但仍保留其布局。
    • 元素及其子元素在页面中仍占据空间,但位置在视口之外。
    • 通过修改left属性可以重新显示元素。
    1
    2
    3
    4
    cssCopy code.hidden-element {
    position: absolute;
    left: -9999px;
    }
  5. clip-path: polygon(0 0, 0 0, 0 0, 0 0);

    • 使用裁剪路径将元素剪裁为一个不可见的区域。
    • 元素及其子元素在页面中仍占据空间,但被裁剪为不可见形状。
    • 通过修改clip-path属性可以重新显示元素。
    1
    2
    3
    cssCopy code.hidden-element {
    clip-path: polygon(0 0, 0 0, 0 0, 0 0);
    }

选择隐藏方式取决于具体的需求。如果要完全从布局中移除元素,可以使用 display: none;。如果需要保留布局但使元素不可见,可以使用 visibility: hidden;opacity: 0;

方式布局可见性重新显示
display: none;完全移除不可见修改 display 属性
visibility: hidden;保留布局空间不可见修改 visibility 属性
opacity: 0;保留布局位置不可见修改 opacity 属性
position: absolute;
left: -9999px;
移动到视口外保留布局空间修改 left 属性
clip-path: polygon(0 0, 0 0, 0 0, 0 0);保留布局空间部分可见,被裁剪修改 clip-path 属性


Q7:使用css实现一个无限循环动画

难度:⭐

答案

要创建一个无限循环的 CSS 动画,你可以使用 @keyframes 规则和 animation 属性。以下是一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
cssCopy code@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

.infinite-rotation {
animation: rotate 5s infinite linear;
}

在这个例子中,我们定义了一个名为 rotate 的关键帧动画,使元素在 0% 处和 100% 处的状态下旋转 360 度。然后,我们将这个动画应用于类名为 infinite-rotation 的元素,使其在5秒内以线性的方式无限循环旋转。


Q8:怎么实现一个宽高自适应的正方形

难度:⭐⭐

答案

方法一:使用相对单位和 padding 百分比

1
2
3
4
5
.square-1 {
width: 50vmin; /* 或其他百分比值,相对于视口宽度或高度中较小的那个 */
padding-top: 50vmin; /* 50% 相对于视口宽度或高度中较小的那个 */
background-color: red; /* 为了演示效果,可以添加背景色 */
}

方法二:使用百分比设置宽高和 padding 百分比

1
2
3
4
5
.square-2 {
width: 50%;
padding-top: 50%;
background-color: blue; /* 为了演示效果,可以添加背景色 */
}

方法三:使用 ::before 伪元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.square-3 {
position: relative;
width: 50%;
}

.square-3::before {
content: '';
display: block;
padding-top: 100%;
}

.square-3-content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: green; /* 为了演示效果,可以添加背景色 */
}

这三种方法都利用了百分比或相对单位以及 padding 百分比的特性,确保宽度和高度保持一致,从而实现宽高自适应的正方形。


Q9 :怎么做移动端的样式适配?

难度:⭐⭐⭐⭐

解析

在移动端,由于不同手机屏幕尺寸、分辨率、横竖屏等因素的影响,需要考虑到不同情况下的展示效果,因此需要进行移动端适配。以下是一些基本知识点:

  1. 像素单位:
    • 设备像素(device pixels)是显示器上的真实像素。
    • 设备分辨率描述的是显示器的宽和高分别是多少个设备像素。
    • 设备独立像素(device independent pixels)是操作系统定义的一种像素单位,用于在应用程序和设备像素之间建立关系,以适应不同屏幕参数。
    • CSS像素用于在CSS中表示长度,如width: 128px
  2. Viewport:
    • 布局视口(layout viewport)是网页布局的区域,用于展示整个页面,使用CSS像素衡量尺寸。
    • 视觉视口(visual viewport)是实际可见的网页区域,随着缩放和窗口调整而改变,但不影响布局视口。
    • 理想视口(ideal viewport)是移动设备的最适合的视口,宽度等于设备的屏幕宽度。
  3. Viewport控制:
    • 使用<meta>标签控制viewport,常见设置为<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    • width=device-width设置layout viewport的宽度等于设备的宽度。
    • initial-scale设置页面的初始缩放值。
    • user-scalable控制是否允许用户手动缩放。

适配方案的核心是理解不同像素单位之间的关系,以及通过设置viewport来实现适配不同屏幕的效果。这对于确保在移动设备上呈现出良好的用户体验至关重要。

答案

1. 使用CSS的媒体查询@media

基于CSS的媒体查询属性@media可以为不同屏幕尺寸的移动设备编写不同尺寸的CSS属性。然而,这种方法存在一些问题:

  • 所有元素都需要在不同的@media中定义不同的尺寸,代价较高。
  • 随着屏幕尺寸的增加,需要添加更多的@media查询块。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@media only screen and (min-width: 375px) {
.logo {
width: 62.5px;
}
}

@media only screen and (min-width: 360px) {
.logo {
width: 60px;
}
}

@media only screen and (min-width: 320px) {
.logo {
width: 53.3333px;
}
}

2. 使用rem单位

rem(根元素字体大小的单位)是相对于根元素的字体大小的单位。虽然可以使用rem解决移动设备适配问题,但需要借助@media属性为不同大小的设备设置不同的font-size,存在一些繁琐的计算。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@media only screen and (min-width: 375px) {
html {
font-size: 375px;
}
}

@media only screen and (min-width: 360px) {
html {
font-size: 360px;
}
}

@media only screen and (min-width: 320px) {
html {
font-size: 320px;
}
}

.logo {
width: calc(180rem);
}

3. Flexible适配方案

Flexible方案对rem进行改进,通过JS动态设置根字体大小。它可以模拟vw特性适配多种屏幕尺寸,但存在一些缺陷:

  • 对于视频播放器的样式在不同dpr的设备上可能存在差异。
  • 不再兼容@media的响应式布局。
  • 在某些时期可能存在兼容性不友好。

4. Viewport适配方案

基于viewport的适配方案被广泛采用。使用vw作为布局单位,解决了不同尺寸屏幕的适配问题。可以使用postcss-px-to-viewport插件将px自动转换为vw

4.1 设置meta标签

在HTML头部设置meta标签,使当前viewport的宽度等于设备的宽度,同时不允许用户手动缩放。

1
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">

4.2 px自动转换为vw

使用postcss-px-to-viewport插件将px自动转换为vw,配置相关参数。

4.3 标注不需要转换的属性

如果某些场景不需要自适配,可以使用插件的Ignoring特性标注不需要转换的CSS属性。

4.4 Retina屏预留坑位

考虑Retina屏场景,可以通过判断dpr并设置data-dpr,在CSS中根据不同的dpr写不同的样式类。

引申
  1. 行内样式的场景:
    • postcss-px-to-viewport 插件无法处理行内样式中的px单位转换。
    • 最佳实践是通过添加、修改、删除 className 处理,不直接操作行内样式,符合js和css隔离的实践。
  2. 1px问题解决方案:
    • Retina屏下1px问题常见,需特殊处理。
    • 常用方法:
      • transform: scale(0.5):通过缩放解决1px线条问题,但边框处理较复杂。
      • transform: scale(0.5) + :before/:after:结合伪元素解决1px问题,通用性好。
      • box-shadow:利用阴影模拟边框,存在阴影问题。
  3. 其他1px问题处理方法(不推荐):
    • 缩小页面viewport。
    • 使用border-image切图模拟。
    • 使用background-image切图模拟。
    • 使用linear-gradient通过渐变实现。
    • 使用SVG矢量图形。
  4. 图片高清问题:
    • 针对Retina屏预留dpr方案,根据不同dpr使用对应图片。
  5. iPhone X适配方案:
    • 了解新知识:
      • 安全区域:确保页面可视、可操作区域在安全区域内,不受设备特性影响。
      • viewport-fit:新增属性,设置网页在可视窗口的布局方式。
      • env()和constant():CSS函数,设定安全区域与边界距离。
    • 适配步骤:
      • 设置viewport-fit=cover。
      • 处理fixed元素的底部适配,考虑安全区域。


Q10:css垂直居中有几种方式?

难度:⭐⭐⭐

答案

垂直居中是在网页布局中常见的需求,有多种方式可以实现。以下是几种常见的CSS垂直居中方式:

  1. 使用Flexbox(弹性盒子布局): 使用Flexbox是一种简单而强大的方式,特别适用于垂直和水平居中。

    1
    2
    3
    4
    5
    .container {
    display: flex;
    align-items: center; /* 垂直居中 */
    justify-content: center; /* 水平居中 */
    }
  2. 使用Grid(网格布局): Grid布局同样提供了简单的居中方式。

    1
    2
    3
    4
    .container {
    display: grid;
    place-items: center; /* 垂直和水平居中 */
    }
  3. 使用position和transform: 利用绝对定位和transform属性可以实现垂直居中。

    1
    2
    3
    4
    5
    6
    .child {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    }
  4. 使用line-height: 对于单行文本,可以使用line-height属性。

    1
    2
    3
    .container {
    line-height: 200px; /* 与容器高度相同 */
    }
  5. 使用表格布局: 利用表格布局可以实现垂直和水平居中。

    1
    2
    3
    4
    5
    .container {
    display: table-cell;
    vertical-align: middle;
    text-align: center; /* 水平居中 */
    }
  6. 使用伪元素和absolute定位: 利用伪元素进行占位,然后绝对定位可以实现居中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    .container {
    position: relative;
    }
    .child {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    }


Q11:怎么让flex布局最后一行列表左对齐?

难度:⭐⭐⭐

1
2
3
4
5
6
7
8
9
<div class="container">
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
</div>
1
2
3
4
5
6
7
8
9
10
.container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.list {
width: 24%; height: 100px;
background-color: skyblue;
margin-top: 15px;
}

image-20240118162615644

答案

方法一:模拟space-between和间隙

CSS代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
cssCopy code.container {
display: flex;
flex-wrap: wrap;
}
.list {
width: 24%;
height: 100px;
background-color: skyblue;
margin-top: 15px;
}
.list:not(:nth-child(4n)) {
margin-right: calc(4% / 3);
}

实现原理:

  • 使用Flex布局设置flex-wrap: wrap,使子项可以换行。
  • 通过:not(:nth-child(4n))选择器排除每行的第4、8、12…个元素,然后给它们添加右侧的margin,模拟space-between效果。

方法二:根据个数最后一个元素动态margin

CSS代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cssCopy code.container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.list {
width: 24%;
height: 100px;
background-color: skyblue;
margin-top: 15px;
}
.list:last-child:nth-child(4n - 1) {
margin-right: calc(24% + 4% / 3);
}
.list:last-child:nth-child(4n - 2) {
margin-right: calc(48% + 8% / 3);
}

实现原理:

  • 使用Flex布局设置justify-content: space-between,实现两端对齐。
  • 通过:last-child:nth-child(4n - 1):last-child:nth-child(4n - 2)选择器选择最后一行的第3和第2个元素,分别添加动态的右侧margin。

方法三:最后一项margin-right:auto

CSS代码:

1
2
3
4
5
6
7
8
9
10
11
12
cssCopy code.container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.list {
background-color: skyblue;
margin: 10px;
}
.list:last-child {
margin-right: auto;
}

实现原理:

  • 使用Flex布局设置justify-content: space-between,实现两端对齐。
  • 给最后一个子项使用margin-right: auto,使其占据剩余空间,实现左对齐效果。

方法四:创建伪元素并设置flex:auto或flex:1

CSS代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
cssCopy code.container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.list {
background-color: skyblue;
margin: 10px;
}
.container::after {
content: '';
flex: auto; /* 或者flex: 1 */
}

实现原理:

  • 使用Flex布局设置justify-content: space-between,实现两端对齐。
  • 创建伪元素::after,设置flex:autoflex:1,使其占据剩余空间,实现左对齐效果。

方法五:Grid布局

CSS代码:

1
2
3
4
5
6
7
8
9
10
11
12
cssCopy code.container {
display: grid;
justify-content: space-between;
grid-template-columns: repeat(auto-fill, 100px);
grid-gap: 10px;
}
.list {
width: 100px;
height: 100px;
background-color: skyblue;
margin-top: 5px;
}

实现原理:

  • 使用Grid布局设置justify-content: space-between,实现两端对齐。
  • 使用grid-template-columns: repeat(auto-fill, 100px)定义自动填充的列,实现左对齐效果。

方法六:使用足够的空白标签进行填充占位

CSS代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cssCopy code.container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
margin-right: -10px;
}
.list {
width: 100px;
height:100px;
background-color: skyblue;
margin: 15px 10px 0 0;
}
.container > i {
width: 100px;
margin-right: 10px;
}

实现原理:

  • 使用Flex布局设置justify-content: space-between,实现两端对齐。
  • 使用伪元素<i>进行占位,通过margin调整宽度和右侧间隙,实现左对齐效果。


Q12:相邻的两个inline-block节点为什么会出现间隔?怎么解决?

难度:⭐⭐

答案

在处理相邻的inline-block节点之间的间隔时,有一些常见的方法,包括一些特殊的CSS技巧。以下是一些常见的解决方法,总共有9种:

  1. 删除HTML代码中的空白字符:

    1
    <div class="inline-block-element"></div><div class="inline-block-element"></div>
  2. 使用注释清除空白:

    1
    2
    <div class="inline-block-element"></div><!--
    --><div class="inline-block-element"></div>
  3. 设置父容器字体大小为0:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    .parent-container {
    font-size: 0;
    }
    .inline-block-element {
    display: inline-block;
    width: 50px;
    height: 50px;
    background-color: blue;
    }
  4. 使用letter-spacing

    1
    2
    3
    .parent-container {
    letter-spacing: -0.31em;
    }
  5. 使用word-spacing

    1
    2
    3
    .parent-container {
    word-spacing: -1em;
    }
  6. 设置负margin

    1
    2
    3
    .inline-block-element + .inline-block-element {
    margin-left: -4px; /* 负margin值等于两个元素间隔的宽度 */
    }
  7. 使用Flex布局:

    1
    2
    3
    .parent-container {
    display: flex;
    }
  8. 使用Flexbox的gap属性:

    1
    2
    3
    4
    .parent-container {
    gap: 0;
    display: flex;
    }
  9. 使用Grid布局:

    1
    2
    3
    4
    .parent-container {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(0, 1fr));
    }


Q13:css怎么实现移动端禁用页面左右滑动手势

难度:⭐

答案
  1. 使用 touch-action 属性:

    1
    2
    3
    html {
    touch-action: none;
    }

    或者通过指定元素的宽度和 overflow 来实现:

    1
    2
    3
    4
    html {
    width: 100vw;
    overflow-x: hidden;
    }
  2. 使用 overscroll-behavior 属性:

    1
    2
    3
    body {
    overscroll-behavior: none;
    }
  3. 使用 position: fixed 固定定位:

    1
    2
    3
    4
    body {
    position: fixed;
    width: 100%;
    }


Q14:怎么检测浏览器支持的最小字体大小?

难度:⭐

答案

要检测浏览器支持的最小字体大小,你可以使用 JavaScript 来获取浏览器的最小字体大小设置。下面是一个简单的方法:

1
2
3
4
5
6
7
8
9
10
const div = document.createElement('div');
div.style.fontSize = '1px'; // 设置一个很小的字体大小
div.style.visibility = 'hidden';
document.body.appendChild(div);

const computedFontSize = window.getComputedStyle(div).fontSize;

document.body.removeChild(div);

console.log('浏览器支持的最小字体大小:', computedFontSize);

此代码创建一个隐藏的 div 元素,将其字体大小设置为1px,然后通过 getComputedStyle 获取计算后的样式,包括最小字体大小。最后,移除该 div 元素。

请注意,这只是获取当前样式表中设置的最小字体大小,并不一定代表浏览器的默认最小字体大小。某些浏览器可能对最小字体大小有硬性限制,无法通过 CSS 直接设置。此方法适用于获取当前页面样式表中的最小字体大小设置。


Q15:iconfont的实现原理是什么

难度:⭐⭐

答案

Iconfont(字体图标)的实现原理主要基于字体文件(通常是.ttf或.woff格式)。以下是实现原理的主要步骤:

  1. 图标设计: 首先,需要设计所需的图标,这些图标通常以矢量图形的形式存在。设计师可以使用矢量图形工具(如Illustrator、Sketch等)创建这些图标。
  2. 字体制作: 将设计好的图标通过专门的工具(如阿里巴巴矢量图标库的在线制作工具)转换为字体文件。这个字体文件包含了每个图标对应的字符编码,每个字符对应一个图标。
  3. 引入字体文件: 将生成的字体文件引入到项目中。通常,开发者可以通过CSS的@font-face规则将字体文件嵌入到网页中。
1
2
3
4
5
cssCopy code@font-face {
font-family: 'iconfont';
src: url('iconfont.woff2') format('woff2'),
url('iconfont.woff') format('woff');
}
  1. 使用字体图标: 在HTML或CSS中使用字体图标,通过指定相应的字符编码即可显示对应的图标。
1
2
htmlCopy code
<i class="iconfont">&#xe001;</i>

上述代码中, 是字体文件中某个图标对应的字符编码,浏览器会根据这个编码找到对应的图标进行显示。

  1. 样式调整: 可以通过CSS来调整字体图标的样式,比如颜色、大小等。

字体图标的优势在于它是矢量的,可以无损放大缩小而不失真,并且只需要加载一份字体文件即可使用多个图标,减小了网络请求的数量。


Q16:css种的1像素问题是什么?要怎么解决?

难度:⭐⭐⭐⭐

答案

在移动端开发中,1像素问题是指在高像素密度的设备上(如Retina屏幕),使用1像素的边框或线条在显示时会过于粗细,影响视觉效果。这是因为在Retina屏幕上,一个CSS像素对应多个物理像素,导致1像素的边框在物理像素上被拉伸,显得较粗。

解决1像素问题的常见方法包括:

  1. 使用viewport单位: 使用vw(视窗宽度单位)或vh(视窗高度单位)来设置边框或线条的宽度,以相对于视窗大小的方式进行定义,而不是使用固定的像素值。例如,border: 0.01vw solid #000;

  2. 使用媒体查询: 利用媒体查询检测设备的像素比(device pixel ratio,通常为2或3),然后根据像素比调整边框或线条的样式。例如:

    1
    2
    3
    4
    5
    6
    cssCopy code@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (min-resolution: 2dppx) {
    /* 高像素密度设备的样式 */
    .element {
    border: 0.5px solid #000;
    }
    }
  3. 使用伪元素和transform: 通过使用伪元素和transform: scaleY(0.5);来实现边框的缩放,使得1像素边框在Retina屏幕上看起来更细。

    1
    2
    3
    4
    5
    6
    7
    cssCopy code.element::after {
    content: "";
    display: block;
    height: 1px;
    background-color: #000;
    transform: scaleY(0.5);
    }
  4. 使用box-shadow: 利用box-shadow属性模拟边框效果,可以在不同的方向上添加阴影来实现1像素线条。例如:

    1
    2
    3
    cssCopy code.element {
    box-shadow: 0 1px 0 0 #000;
    }


Q17:CSS优化跟提高性能的方法有哪些?

难度:⭐⭐

答案

优化CSS以提高性能是一个重要的前端任务,以下是一些常见的CSS优化和性能提高的方法:

  1. 减少HTTP请求:
    • 将多个CSS文件合并成一个文件,减少HTTP请求次数。
    • 使用CSS Sprites将多个小图标合并成一张大图,减少图片的HTTP请求。
  2. 精简和压缩CSS:
    • 移除不必要的空格、注释和换行。
    • 使用CSS压缩工具,如UglifyCSS、cssnano等。
  3. 使用字体图标:
    • 替代使用图片的小图标,使用字体图标(如Font Awesome、Material Icons)减少图片请求。
  4. 避免使用@import:
    • 使用标签引入CSS文件,而不是使用@import,因为@import会增加页面加载时间。
  5. 减少选择器的嵌套和复杂性:
    • 避免过度嵌套选择器,以减小CSS文件的大小。
    • 简化选择器,避免使用过于复杂的选择器,提高匹配速度。
  6. 使用缓存:
    • 使用适当的缓存策略,确保浏览器可以缓存CSS文件,减少重复加载。
  7. 使用合适的单位:
    • 使用相对单位(如em、rem)而不是绝对单位(如px),以便更好地适应不同屏幕大小和分辨率。
  8. 避免使用昂贵的属性和选择器:
    • 尽量避免使用性能较差的属性和选择器,如使用position: fixedbox-shadow等。
  9. 懒加载CSS:
    • 根据页面的需要,延迟加载不是首要渲染的CSS文件,以提高首次加载性能。
  10. 使用GPU加速:
    • 使用可以利用GPU加速的CSS属性,如transform和opacity,以提高动画性能。
  11. 使用媒体查询:
    • 使用媒体查询在不同的屏幕尺寸和设备上提供不同的样式表,以优化移动端和桌面端的显示。
  12. 避免使用!important:
    • 尽量避免使用!important,因为它会增加样式的优先级,使得后续的修改更加困难。


Q18:为什么会出现浮动?什么时候要清除浮动?有什么清除方式?

难度:⭐

答案

浮动(float)是一种常见的CSS布局技术,用于控制元素在父元素内的位置。浮动的元素会从文档流中脱离,并向左或向右移动,直到它的边缘碰到包含元素或另一个浮动元素的边缘。

浮动元素引起的主要问题是可能导致父元素的高度塌陷(高度塌陷指父元素无法包含浮动元素而导致高度为零的情况)。在这种情况下,需要清除浮动。

何时需要清除浮动:

  1. 父元素包含浮动子元素: 如果一个元素的子元素都是浮动的,而这个父元素没有设置高度,就会导致高度塌陷,这时需要清除浮动。
  2. 在两个块级元素之间浮动: 当两个块级元素之间有浮动元素时,后续的块级元素可能会受到浮动元素的影响而位置错乱。

清除浮动的方式:

  1. 使用空元素清除浮动:

    1
    2
    3
    4
    5
    cssCopy code.clearfix::after {
    content: "";
    display: table;
    clear: both;
    }

    在需要清除浮动的父元素上添加一个空的块级元素,并应用clearfix类。这个方法适用于大多数浏览器。

  2. 使用overflow属性:

    1
    2
    3
    cssCopy code.clearfix {
    overflow: auto;
    }

    给父元素设置 overflow: auto; 或 overflow: hidden;,这样也可以清除浮动,但可能影响盒模型。

  3. 使用伪元素清除浮动:

    1
    2
    3
    4
    5
    cssCopy code.clearfix::after {
    content: "";
    display: table;
    clear: both;
    }

    使用伪元素方式,类似于空元素清除浮动,但不需要在HTML中添加额外的元素。

  4. 使用BFC(块级格式上下文): 父元素设置 overflow: hidden;display: flow-root; 可以创建BFC,从而清除浮动。


Q19 :如何使用css完成视觉差滚动效果?

难度:⭐⭐⭐

答案

1. background-attachment: fixed;

1
2
3
4
5
6
.parallax-container {
background-image: url('background.jpg');
background-size: cover;
background-attachment: fixed;
height: 100vh;
}

通过设置 background-attachment: fixed;,可以让背景图保持固定,当页面滚动时,背景图不会随之滚动,从而产生视觉差效果。这是一种简单直观的实现方式。

2. transform: translate3D;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.parallax-layer {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
}

.layer1 {
background-image: url('layer1.jpg');
background-size: cover;
height: 120%;
transform: translate3D(0, -20%, 0);
}

.layer2 {
background-image: url('layer2.jpg');
background-size: cover;
height: 150%;
transform: translate3D(0, -25%, 0);
}

通过利用 transform: translate3D; 属性,将图层在垂直方向上进行位移,产生不同层之间的滚动速度差异,从而实现视觉差效果。需要注意调整图层的高度和位移的百分比,以获得理想的效果。


Q20:如何用css画一个三角形?

难度:⭐

答案

方法一:利用边框

1
2
3
4
5
6
7
.triangle {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 87px solid #3498db; /* 可自定义颜色 */
}

这里通过设置 border-leftborder-rightborder-bottom 的值,可以绘制一个等边三角形。需要注意的是,三角形的高度可以根据勾股定理计算,这里设定 border-bottom 为 87px 是一个常见的值。

方法二:利用伪元素

1
2
3
4
5
6
7
.triangle {
width: 0;
height: 0;
border-style: solid;
border-width: 0 50px 87px 50px;
border-color: transparent transparent #3498db transparent; /* 可自定义颜色 */
}

这里同样通过设置 border-widthborder-color 来实现,利用 transparent 使得三角形的一边是透明的。