Skip to content
On this page

CSS面试题汇总

1、🔥px、rem、em、vw的区别?

  • px是相对于显示器屏幕分辨率而言的,固定的一种单位

  • em是相对于自身元素的字体大小而言的,譬如自身元素字体大小为16px,那么1em=16px,2em=32px

    html
    <style>
      .list {
        font-size: 18px;
      }
      .item {
        font-size: 14px;
        width: 2em;
        height: 2em;
        background: #ccc;
      }
    </style>
    <div class="list">
      <!-- width: 28px;height: 28px; -->
      <div class="item">aaa</div>
    </div>
    
  • rem是相对于根元素(html)字体大小而言的,浏览器默认的字体大小都是16px,那么1rem=16px,2rem=32px,可以根据设备的宽度,结合媒体查询(@media)来进行自适应的布局。

  • vw是窗口的实际宽度,1vw=1%窗口的实际宽度。

  • 对于只需要适配少部分手机设备,且分辨率对页面影响不大的,使用px即可 。

  • 对于需要适配各种移动设备,使用rem,例如只需要适配iPhone和iPad等分辨率差别比较挺大的设备。

2、🔥vw、vh是什么?

vwvh是 CSS3 新单位,即 view width 可视窗口宽度 和 view height 可视窗口高度。1vw 就等于可视窗口宽度的百分之一,1vh 就等于可视窗口高度的百分之一。

3、🔥介绍下BFC及其应用

BFC,全称为Block Formatting Context,即块级格式化上下文,是CSS布局中的一个重要概念。它可以被视为页面上的一个独立的渲染区域或容器,其中的元素不会影响到外部的元素,同时外部的元素也不会影响到它

注意: 一个BFC区域,只包含其所有子元素,不包含子元素的子元素。

触发BFC的条件: 满足下面任意一个条件,这个元素都会被当做一个BFC

  • body根元素
  • 设置浮动float,不包括none
  • 设置定位,position的值不为relativestatic
  • 设置overflow,即hidden,auto,scroll
  • display的值为inline-blocktable-celltable-captionflexgrid

利用BFC解决问题

BFC有一个特点: 每一个BFC区域都是相互独立,互不影响的。

  • 1、解决外边距的塌陷问题(垂直塌陷)

    开发中,前端的布局手段,离不开外边距margin,那么,也会遇到一些问题,例如外边距的垂直塌陷问题。 202303161021217.png 通过上面的例子,我们会发现,我们分别为两个HM都设置了四个方向的margin,按照正常情况来看,本应该两个HM垂直方向的间距是100px + 100px = 200px,但是现在确是100px,出现了margin的塌陷即,两段margin重叠了。 利用BFC解决塌陷问题:可以将这两个盒子,放到两个BFC区域中,即可解决这个问题。 202303161024381.png

  • 2、解决包含塌陷

    当父子关系的盒子,给子元素添加margin-top,有可能会把父元素一起带跑 202303161025495.png 理想状态下,应该是son元素在father元素的顶部间距是50px,而此时是fater距离body的顶部间距是50px。 利用BFC解决塌陷问题: 将父盒子变成一个独立的区域 202303161029416.png

  • 3、当浮动产生影响的时候,可以利用BFC来清除浮动的影响 202303161032186.png 上面例子中,一个没有设置高度的父盒子,包含了几个子元素,此时父元素的高度会被子元素撑开。如果为子元素都设置浮动的话效果会怎样呢 2023031610341810.png 从上面效果就能看出,当为子元素设置了浮动后,父盒子失去了原有的高度了。

    利用BFC解决高度丢失问题: 将父盒子变成一个独立的区域 202303161036308.png

  • 4、BFC可以阻止标准流元素被浮动元素覆盖 202303161038348.png 上面例子中,红色盒子设置了浮动,灰色盒子是标准流,默认情况下,浮动盒子覆盖了标准流盒子。

    利用BFC解决覆盖问题: 将灰色盒子的BFC触发 202303161041181.png

4、🔥介绍下 BFC、IFC、GFC 和 FFC

BFC、IFC、GFC 和 FFC 是 CSS 盒模型中的四种容器,用于控制盒子之间的排布和尺寸。

BFC(块级格式化上下文)

**BFC(块级格式化上下文)**是一种独立的渲染区域,其中的元素按照特定规则进行排布。BFC 中的元素不会与外部元素重叠,而是在垂直方向上一个接一个地排列。

  • 使用场景:
    • 清除浮动:当父元素包含浮动元素时,BFC可以防止父元素高度塌陷。
    • 防止margin合并:当相邻两个元素都设置了外边距时,BFC可以防止这些边距发生合并,从而避免产生意料之外的空白或布局问题。
    • 垂直居中:当一个元素垂直居中对其另一个元素时,可以使用BFC来实现。
  • 使用案例:

    在一个包含浮动元素的父元素中,添加一个overflow:hidden属性,就可以创建一个新的BFC,并防止父元素高度塌陷。

    css
    .parent {
      overflow: hidden;
    }
    

IFC(内联格式化上下文)

IFC(内联格式化上下文)(Inline Formatting Context)是一行内元素的渲染区域,内部元素的布局受到相邻元素的影响。在IFC中,盒子按照从左到右的顺序排列,可以通过vertical-align属性来垂直对齐。

  • 使用场景:
    • 实现文字和图标的对齐:通过使用 IFC 中的vertical-align属性,可以让行内元素垂直方向上对齐,从而实现图标和文字的对齐。
    • 创建水平菜单:通过设置列表项为行内元素,并设置其间距和边框,即可创建水平菜单。
  • 使用案例:

    实现文字和图标的对齐:可以通过设置行内元素的vertical-align属性,将它们在垂直方向上对齐,从而实现图标和文字的对齐。

    html
    <div class="parent">
      <span class="icon"></span>
      <span class="text">Some text.</span>
    </div>
    <style>
      .icon {
        display: inline-block;
        width: 20px;
        height: 20px;
        background-image: url(icon.png);
        background-size: cover;
        vertical-align: middle; /* 对齐方式 */
      }
      .text {
        display: inline-block;
        vertical-align: middle; /* 对齐方式 */
      }
    </style>
    

GFC(网格格式化上下文)

GFC(网格格式化上下文)(Grids Formatting Context)是CSS Grid Layout中的一个概念,规定了内部网格元素的布局方式,且与外部毫不相干。

  • 使用场景:
    • 创建复杂的网格布局:通过使用网格布局,可以将页面分割成网格,然后在这些网格中排列内容,从而实现复杂的布局结构。
    • 实现自适应布局:通过使用响应式的网格布局,可以让页面在不同的屏幕尺寸下自适应地调整布局。
  • 使用案例:

    创建复杂的网格布局:可以使用网格布局,将页面分割成网格,并在这些网格中排列内容,从而实现复杂的布局结构。

    html
    <div class="grid-container">
      <div class="item item-1"></div>
      <div class="item item-2"></div>
      <div class="item item-3"></div>
      <div class="item item-4"></div>
    </div>
    <style>
      .grid-container {
        display: grid; /* 触发 GFC */
        grid-template-columns: repeat(2, 1fr); /* 定义两列等宽 */
        grid-gap: 20px; /* 设置网格之间的间隙 */
      }
      .item {
        background-color: #ccc;
        padding: 20px;
      }
      .item-1 {
        grid-row: 1 / 3; /* 占用两行 */
      }
      .item-2 {
        grid-column: 2 / 3; /* 占用一列 */
      }
      .item-3 {
        grid-row: 2 / 4; /* 占用两行 */
      }
      .item-4 {
        grid-column: 1 / 2; /* 占用一列 */
      }
    </style>
    

FFC(弹性盒格式化上下文)

FFC(弹性盒格式化上下文)(Flexible Formatting Context)是CSS3引入的一种新的布局模型——flex布局。它提供了一种更加有效的方式来对容器内的项目进行布局,以适应各种类型的显示设备和各种尺寸的屏幕。

  • 使用场景:
    • 实现弹性布局:通过使用 flexbox 布局,可以让元素在容器内自适应调整大小和位置,从而实现弹性布局。
    • 创建响应式设计:通过使用 FFC,可以让元素在容器内自动根据容器大小进行调整,从而实现响应式设计。
  • 使用案例:

    实现弹性布局:可以通过使用flexbox布局,让元素在容器内自适应调整大小和位置,从而实现弹性布局。

    html
    <div class="container">
      <div class="item item-1"></div>
      <div class="item item-2"></div>
      <div class="item item-3"></div>
    </div>
    <style>
      .container {
        display: flex; /* 触发 FFC */
        justify-content: space-between; /* 沿主轴方向平均分布元素 */
      }
      .item {
        background-color: #ccc;
        padding: 20px;
      }
      .item-1 {
        flex-basis: 30%; /* 设置元素基础尺寸为30% */
      }
      .item-2 {
        flex-grow: 1; /* 自动扩展,占据剩余空间 */
      }
      .item-3 {
        flex-basis: 200px; /* 固定宽度为200px */
      }
    </style>
    

5、🔥flex布局如何使用?

flexFlexible Box的缩写,意为"弹性布局"。指定容器display: flexinline-flex即可。

  • 容器属性:
    • display:指定容器使用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六个值。
    • align-items:指定交叉轴上项目的对齐方式,包括flex-start、flex-end、center、baseline 和 stretch五个值。
    • align-content:指定多根轴线的对齐方式,只有在存在多根轴线时才会生效,包括flex-start、flex-end、center、space-between、space-around 和 stretch六个值。
  • 项目(子元素)属性:
    • order:指定项目的排列顺序。
    • flex-grow:指定项目在空间充足时,放大比例的大小。
    • flex-shrink:指定项目在空间不足时,缩小比例的大小。
    • flex-basis:指定项目在分配多余空间之前的初始大小。
    • flex:是flex-grow, flex-shrink 和 flex-basis的缩写属性。
    • align-self:指定单个项目的对齐方式,覆盖容器的align-items属性。

6、🔥grid布局如何使用?

Grid布局是一种二维网格布局模型,指定容器display: gridinline-grid即可。

  • 容器属性:
    • grid-template-columns:定义列的数量和大小。
    • grid-template-rows:定义行的数量和大小。
    • grid-template-areas:定义网格区域的名称和排列方式。
    • grid-template:是grid-template-rows, grid-template-columns 和 grid-template-areas的缩写属性。
    • grid-column-gap:定义列之间的间隔大小。
    • grid-row-gap:定义行之间的间隔大小。
    • grid-gap:是grid-row-gap 和 grid-column-gap的缩写属性。
    • justify-items:定义单元格内容在列方向上的对齐方式。
    • align-items:定义单元格内容在行方向上的对齐方式。
    • justify-content:定义整个网格沿着列方向上的对齐方式。
    • align-content:定义整个网格沿着行方向上的对齐方式。
  • 项目(子元素)属性:
    • grid-column-startgrid-column-end:定义单元格跨越的列区域。
    • grid-row-startgrid-row-end:定义单元格跨越的行区域。
    • grid-columngrid-row:是grid-column-start, grid-column-end, grid-row-start 和 grid-row-end的缩写属性。
    • grid-area:定义单元格所占据的全部区域。
    • justify-self:定义单元格内容在列方向上的对齐方式,覆盖容器的justify-items属性。
    • align-self:定义单元格内容在行方向上的对齐方式,覆盖容器的align-items属性。

7、⭐分析比较 opacity: 0、visibility: hidden、display: none区别、优劣和适用场景

opacity:0visibility:hiddendisplay:none都可以隐藏元素,但它们的实现方式不同,适用的场景也不同。

  • opacity: 0:元素依然占据屏幕空间,但变得完全透明。该属性可以通过动画效果实现淡入淡出等过渡效果,同时仍会影响页面布局,同时也会响应绑定的监听事件。
  • visibility: hidden:元素被隐藏,但它仍占据它原来的位置和空间。该属性通常用于需要在用户交互后显示/隐藏的元素,例如下拉菜单或弹出框,但是不会响应绑定的监听事件。
  • display: none:元素从页面中移除,并且不占据任何屏幕空间。该属性可以完全移除元素,同时避免对页面布局的影响,但也意味着该元素无法再次被检索到,也不会响应绑定的监听事件。

使用场景:

  • opacity: 0:适用于需要在当前位置播放动画或过渡效果的元素,如图片轮播、页面滚动等。
  • visibility: hidden:适用于需要在用户操作后显示的元素,如下拉菜单、输入框等。
  • display: none:适用于需要完全隐藏元素且不影响页面布局的场景,如模态框、某个状态下不需要显示的元素等。

128、隐藏元素的background-image到底加不加载?

  • display: none;: 设置的背景图片不会加载;
  • visibility: hidden;: 设置的背景图片会加载;
  • opacity: 0;: 设置的背景图片会加载;

129、隐藏的img标签的图片到底加不加载?

  • display: none;: 设置的图片会加载;
  • visibility: hidden;: 设置的图片会加载;
  • opacity: 0;: 设置的图片会加载;

130、无依赖绝对定位是什么?

无依赖绝对定位是一种CSS中的布局技术,它允许元素相对于其最近的已定位祖先元素进行定位,而不考虑其他元素的影响。

无依赖绝对定位是指通过设置元素的top、right、bottom、left属性来精确地定位元素,而不依赖于其他元素或父容器的位置和大小。

以下是一个简单的例子:

html
<style>
  .box {
    position: absolute;
    top: 50px;
    left: 100px;
    width: 200px;
    height: 100px;
    background-color: yellow;
  }
</style>
<div class="box">我是一个绝对定位的元素</div>

8、🔥如何用 css 或 js 实现多行文本溢出省略效果,考虑兼容性

CSS 实现方式

  • 单行
    css
    overflow: hidden;
    text-overflow:ellipsis;
    white-space: nowrap;
    
  • 多行
    css
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3; //行数
    overflow: hidden;
    
  • 兼容
    css
    p{
      position: relative;
      line-height: 20px;
      max-height: 40px;
      overflow: hidden;
    }
    p::after{
      content: "...";
      position: absolute;
      bottom: 0;
      right: 0;
      padding-left: 40px;
      background: -webkit-linear-gradient(left, transparent, #fff 55%);
      background: -o-linear-gradient(right, transparent, #fff 55%);
      background: -moz-linear-gradient(right, transparent, #fff 55%);
      background: linear-gradient(to right, transparent, #fff 55%);
    }
    

JS 实现方式:

  • 使用split + 正则表达式将单词与单个文字切割出来存入words
  • 加上 '...'
  • 判断scrollHeightclientHeight,超出的话就从wordspop一个出来

9、居中为什么要使用 transform(为什么不使用 marginLeft/Top)

在实现元素居中时,使用transform属性进行平移的优点在于它可以实现更加灵活和精准的位置控制。相比于使用margin-leftmargin-top来控制元素居中,使用transform有以下优势:

  1. 使用transform不会影响文档流和元素的盒模型,而使用margin可能会影响页面布局和其他元素的位置。

这意味着使用transform更加可靠且不容易出现不良的副作用。

  1. 由于transform是通过GPU加速实现的,因此它通常比margin更加高效和快速。

即在需要频繁更新或动画的场景下,使用transform可以提高性能和用户体验。

  1. 使用transform还可以允许我们使用其他的transform属性(如旋转、缩放、斜切等),从而实现更加复杂和丰富的视觉效果。
  2. 使用transform不会使页面进行重排和重绘

但需要注意的是,虽然transform在许多情况下是居中的首选方法,但它也有一些局限性。

例如: 使用transform进行变换可能会导致一些渲染问题,特别是在处理3D变换或在大规模项目中。

10、🔥介绍下粘性布局(sticky)

position中的sticky值是 CSS3 新增的,设置了 sticky 值后,在屏幕范围(viewport)时该元素的位置并不受到定位影响(设置使topleft等属性无效),当该元素的位置将要移出偏移范围时,定位又会变成fixed,根据设置的lefttop等属性成固定位置的效果。

注意

position: sticky必须结合topleftrightbottom使用,否则无效

  • 当同时设置topbottom时,top优先级高;
  • 当同时设置leftright时,left优先级高;
html
<style>
  .tips {
    height: 100px;
    background: #ccc;
  }
  header {
    height: 60px;
    background: blue;
    position: sticky; /* 必须结合top,left,right,bottom四个属性使用 */
    top: 0;
  }
  main {
    height: 1000px;
    background: #eee;
  }
</style>
<body>
  <div class="tips">tips</div>
  <header>header</header>
  <main>content</main>
</body>

演示效果 2023031610081310.gif

sticky 属性值有以下几个特点:

  • 该元素并不脱离文档流,仍然保留元素原本在文档流中的位置。
  • 当元素在容器中被滚动超过指定的偏移值时,元素在容器内固定在指定位置。亦即如果你设置了top: 50px,那么在sticky元素到达距离相对定位的元素顶部50px的位置时固定,不再向上移动。
  • 元素固定的相对偏移是相对于离它最近的具有滚动框的祖先元素,如果祖先元素都不可以滚动,那么是相对于viewport来计算元素的偏移量

11、⭐说出 space-between 和 space-around 的区别?

这个是flex布局的内容,其实就是一个边距的区别,按水平布局来说:

  • space-between是两端对齐,在左右两侧没有边距,元素中间间距相等; 202303160953243.png
  • space-around是每个子项目左右方向的margin相等,所以子项目之间的间隔比项目与边缘的间隔大一倍; 202303160953469.png
  • space-evenly是每个子项目和两端间距相等; 202303160954084.png

12、⭐CSS3 中transition和animation的区别,属性分别有哪些

区别

  • transition: 是过渡属性,强调过渡,它的实现需要触发一个事件(比如鼠标移入移出、焦点、点击等)才执行动画;
    • transition-property:指定过渡的css属性的name
    • transition-duration:指定过渡所需的完成时间
    • transition-timing-function:指定过渡函数
    • transition-delay:指定过渡的延迟时间
    css
    div{
      width:100px;
      height:100px;
      background:red;
      transition: width 2s ease-out 1s;
    }
    div:hover{
      width: 300px;
    }
    
    202303171625518.gif
  • animation: 是动画属性,它的实现不需要触发事件,设定好时间之后可以自己执行,且可以循环一个动画;
    • animation-name:指定要绑定到选择器的关键帧的名称
    • animation-duration:动画指定需要多少秒或毫秒完成
    • animation-timing-function:设置动画将如何完成一个周期
    • animation-delay:设置动画在启动前的延迟间隔
    • animation-iteration-count:定义动画的播放次数
    • animation-direction:指定是否应该轮流反向播放动画
    • animation-fill-mode:规定当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到元素的样式
    • animation-play-state:指定动画是否正在运行或已暂停
    js
    div {
      width:100px;
      height:100px;
      background:red;
      position:relative;
      animation: mymove 5s linear infinite;
    }
    @keyframes mymove {
      from { left: 0px; }
      to { left: 200px; }
    }
    
    202303171630317.gif

13、⭐讲一下png8、png16、png32的区别,并简单讲讲png的压缩原理

PNG(Portable Network Graphics)是一种广泛使用的图像格式,支持透明度,常用于网页和在线图形。PNG图像有不同的变种,包括PNG8、PNG16和PNG32,它们的主要区别在于颜色深度和透明度支持的不同。

  • PNG8:这是一种8位颜色深度的PNG图像格式,最多支持256种颜色。对于颜色相对简单、不需要透明度的图像,使用PNG8可以获得较小的文件大小。PNG8图像使用调色板(Palette)技术来存储颜色信息,它会创建一个包含所有使用的颜色的列表,并在图像中通过索引来引用这些颜色。这种格式不支持透明度。
  • PNG16:这是一种16位颜色深度的PNG图像格式,支持更多的颜色,最多可达65536种颜色。PNG16适用于一些颜色较丰富的图像,但同样不支持透明度。
  • PNG32:这是一种32位颜色深度的PNG图像格式,支持上千万种颜色,并且支持完全透明度(alpha通道)。PNG32适用于需要精确透明度控制的图像,例如图标、Logo等。

压缩原理

其原理是基于无损压缩算法,主要使用LZ77派生算法进行文件压缩。这种压缩方法可以在保证图像数据不损失的情况下,通过标记和编码重复出现的数据,以及利用特殊的编码方法,减小图像文件的大小。此外PNG还支持调色板技术和透明度通道,这使得PNG图像在保持高质量的同时,也具有更好的灵活性和适应性。

14、🔥如何用 CSS 实现一个三角形

可以利用 border 属性 利用盒模型的border属性上下左右边框交界处会呈现出平滑的斜线这个特点,通过设置不同的上下左右边框宽度或者颜色即可得到三角形或者梯形。

如果想实现其中的任一个三角形,把其他方向上的border-color都设置成透明即可。

html
<div></div>
<style>
  div {
    width: 0;
    height: 0;
    border: 10px solid red;
    border-top-color: transparent;
    border-left-color: transparent;
    border-right-color: transparent;
  }
</style>

15、⭐如何实现一个自适应的正方形

方法1:利用 CSS3 的 vw 单位

vw会把视口的宽度平均分为 100 份

css
.square {
 width: 10vw;
 height: 10vw;
 background: red;
}

方法2:利用 margin 或者 padding 的百分比计算是参照父元素的 width 属性

css
.square {
 width: 10%;
 padding-bottom: 10%; 
 height: 0; // 防止内容撑开多余的高度
 background: red;
}

16、🔥清除浮动的方法

  • 浮动的原理: 使当前元素脱离普通流,相当于浮动起来一样,浮动的框可以左右移动。
  • 浮动的设置: css属性的float设置,可选值:
    • left: 左浮动
    • right: 右浮动
    • none: 默认值,不浮动
  • 浮动的影响: 对附近的元素布局造成改变,使得布局混乱
  • 清除浮动的几种方法:
    • 1、为父元素设置overflow属性,可以是autohidden

      解决高度塌陷问题

      html
      <style>
        .div1{
          background: #000080;
          border: 1px solid red;
          overflow: hidden; /* 不设置会导致div1高度不撑开 */
        }
        .left{
          float: left;
          width: 20%;
          height: 200px;
          background: #DDD;
        }
      </style>
      <div class="div1">
        <div class="left">Left</div>
      </div>
      
    • 2、clear: both清除浮动

      在父元素的末尾添加一个空div标签,并设置clear: both属性

      html
      <style>
        .div1{
          background: #000080;
          border: 1px solid red;
        }
        .left{
          float: left;
          width: 20%;
          height: 200px;
          background: #DDD;
        }
      </style>
      <div class="div1">
        <div class="left">Left</div>
        <div style="clear: both;"></div>
      </div>
      
    • 3、为父级元素设置height高度
      html
      <style>
        .div1{
          background: #000080;
          border: 1px solid red;
          height: 200px;
        }
        .left{
          float: left;
          width: 20%;
          height: 200px;
          background: #DDD;
        }
      </style>
      <div class="div1">
        <div class="left">Left</div>
      </div>
      
    • 4、为父级设置after伪类,万能法()
      html
      <style>
        .div1 {
          background: #000080;
          border: 1px solid red;
          *zoom: 1; /* ie6清除浮动的方式 *号只有IE6-IE7执行,其他浏览器不执行 */
        }
        .div1::after {
          content: "";
          display: block;
          height: 0;
          clear: both;
        }
        .left{
          float: left;
          width: 20%;
          height: 200px;
          background: #DDD;
        }
      </style>
      <div class="div1">
        <div class="left">Left</div>
      </div>
      
  • 5、使用flexbox布局清除浮动:将浮动元素的父元素设置为display: flex,并使用flex-wrap属性来控制换行。例如:
    css
    .parent {
      display: flex;
      flex-wrap: wrap;
    }
    

17、🔥说说两种盒模型以及区别

盒模型也称为框模型,它规定了元素如何在页面上呈现,包括元素的内容、内边距(padding)、边框(border)和外边距(margin)的处理方式。盒子模型主要有两种:标准盒模型(Standard Box Model)和 IE 盒模型(IE Box Model)。 202302091538234.png2023020915383510.png

盒模型都是由四个部分组成:margin、border、padding、content

标准盒模型的IE盒模型的区别在于设置widthheight时,所对应的范围不同:

  • 标准盒模型:widthheight属性的范围只包含content的宽度和高度,不包括内边距、边框和外边距。

这就意味着如果你设置了一个元素的 width200px,那么这个元素的整个宽度(包括内容、内边距和边框)将会大于200px

  • IE盒模型:widthheight的范围包含了borderpaddingcontent的宽度和高度。

这意味着如果你设置了一个元素的width200px,那么这个元素的整个宽度(包括内容、内边距和边框)将会是200px

可以通过修改元素的box-sizing属性来改变元素的盒模型:

  • box-sizing: content-box;表示标准盒模型(默认值)
  • box-sizing: border-box;表示IE模型(怪异盒模型)

18、🔥如何触发重排和重绘?

任何改变用来构建渲染树的信息都会导致一次重排或重绘:

  • 添加、删除、更新DOM节点 - 重排和重绘
  • 通过display: none隐藏一个DOM节点 - 重排和重绘
  • 通过visibility: hidden隐藏一个DOM节点 - 只重绘,因为没有几何变化
  • 移动或者给页面中的DOM节点添加动画 - 重排和重绘
  • 添加一个样式表,调整样式属性 - 重排和重绘
  • 用户行为,例如调整窗口大小,改变字号,或者滚动 - 重排和重绘

19、🔥重绘、重排与复合的区别?

  • 重排(reflow):指的是元素在页面中的位置和布局发生了变化,例如添加、删除或修改了元素的尺寸、位置、内容等。重排会触发浏览器重新计算元素的位置和大小,并且重新布局整个页面,因此代价较高,应该尽量避免频繁发生。
  • 重绘(repaint):指的是元素外观的更新,例如颜色、背景等样式属性的变化,但元素在页面中的位置和布局不会发生改变。
  • 复合(Recombination):涉及到将多个图形层(Layers)组合在一起以形成最终的渲染结果。这个过程是在GPU(图形处理器)上进行的,而不是在CPU上。通过复合,浏览器可以更加高效地处理页面渲染,特别是当页面包含许多动态或复杂的图形元素时。

单单改变元素的外观,肯定不会引起网页重新生成布局,但当浏览器完成重排之后,将会重新绘制受到此次重排影响的部分

重排和重绘代价是高昂的,它们会破坏用户体验,并且让UI展示非常迟缓,而相比之下重排的性能影响更大,在两者无法避免的情况下,一般我们宁可选择代价更小的重绘。

『重绘』不一定会出现『重排』,『重排』必然会出现『重绘』

20、⭐如何优化图片

  1. 对于很多装饰类图片,尽量不用图片,因为这类修饰图片完全可以用 CSS 去代替。
  2. 对于移动端来说,屏幕宽度就那么点,完全没有必要去加载原图浪费带宽。一般图片都用 CDN 加载,可以计算出适配屏幕的宽度,然后去请求相应裁剪好的图片。
  3. 小图使用 base64 格式
  4. 将多个图标文件整合到一张图片中(雪碧图)
  5. 选择正确的图片格式:
  • 对于能够显示 WebP 格式的浏览器尽量使用 WebP 格式。因为 WebP 格式具有更好的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量,缺点就是兼容性并不好
  • 小图使用 PNG,其实对于大部分图标这类图片,完全可以使用 SVG 代替
  • 照片使用 JPEG

21、你能描述一下渐进增强和优雅降级之间的不同吗?

渐进增强 (progressive enhancement):针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。

优雅降级 (graceful degradation):一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

优雅降级是从复杂的现状开始,并试图减少用户体验的供给,而渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要。降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带。

22、🔥CSS3 新增了那些东西?

CSS3 新增东西众多,这里列举出一些关键的新增内容:

  • 选择器: :not(.input)
  • 盒子模型属性:border-radius、box-shadow、border-image
  • 背景:background-size、background-origin、background-clip
  • 文本效果:text-shadow、word-wrap
  • 颜色:新增 RGBA,HSLA 模式
  • 渐变:线性渐变(linear-gradient)、径向渐变(radial-gradient)
  • 字体:@font-face
  • 2D/3D转换:transform、transform-origin
  • 过渡与动画:transition、@keyframes、animation
  • 多列布局
  • 媒体查询

23、🔥隐藏页面中的某个元素的方法有哪些?

隐藏类型

屏幕并不是唯一的输出机制,比如说屏幕上看不见的元素(隐藏的元素),其中一些依然能够被读屏软件阅读出来(因为读屏软件依赖于可访问性树来阐述)。为了消除它们之间的歧义,我们将其归为三大类:

  • 完全隐藏:元素从渲染树中消失,不占据空间。
  • 视觉上的隐藏:屏幕中不可见,占据空间。
  • 语义上的隐藏:读屏软件不可读,但正常占据空。

完全隐藏

  • display 属性
    css
    display: none;
    
  • hidden 属性 HTML5 新增属性,相当于 display: none
    html
    <div hidden></div>
    

视觉上的隐藏

  • 设置 posoition 为 absolute 或 fixed,通过设置 top、left 等值,将其移出可视区域。
    css
    position:absolute;
    left: -99999px;
    
  • 设置 position 为 relative,通过设置 top、left 等值,将其移出可视区域。
    css
    margin-left: -99999px;
    height: 0;
    

语义上隐藏

  • aria-hidden 属性:读屏软件不可读,占据空间,可见。
    html
    <div aria-hidden="true"></div>
    

24、🔥css选择器及其优先级

对于选择器的优先级:

  • 通用选择器(*)、子选择器(>)、相邻选择器(+)、同胞选择器(~): 0
  • 标签选择器、伪元素选择器:1
  • 类选择器、伪类选择器、属性选择器:10
  • id选择器:100
  • 内联样式:1000
  • !important: 10000

总结: !important > 内联选择器 > id选择器 > 类选择器 > 标签选择器 > 通配选择器

权重值计算

js
div#app.child[name="appName"] = 标签选择器 + id选择器 + 类选择器 + 属性选择器
权重 = 1 + 100 + 10 + 10 = 121

.class p[type="text"] = 类选择器 + 标签选择器 + 属性选择择器
权重 = 10 + 1 + 10 = 21

同胞选择器~演示

html
<style>
	.box1 { width: 200px;height: 200px;background: #ddd; }
	.box2 { width: 200px;height: 200px;background: red; }
	.box1 ~ div {
	 border: 1px solid blue;
	}
</style>
<div class="box1">
  <div></div>
</div>
<div class="box2"></div>

202303171730108.png

25、CSS中可继承与不可继承属性有哪些?

不可继承属性

  • display:规定元素应该生成的框的类型
  • 文本属性:vertical-align(文本垂直对齐)、text-decoration(文本的装饰)、tex-shadow(文本阴影)、white-space(空白符的处理)、unicode-bidi(文本的方向)
  • 盒子模型的属性:width、height、margin、border、padding
  • 背景属性:background、background-color、background-image、background-repeat、background-position、background-attachment
  • 定位属性:float、clear、position、top、right、left、bottom、min-width、min-height、max-width、max-height、overflow、clip、z-index
  • 生成内容属性:content、counter-reset、counter-increment
  • 轮廓样式属性:outline、outline-style、outline-width、outline-color
  • 页面样式属性:size、page-break-before、page-break-after
  • 声音样式属性:pause-before、pause-after、pause、cue-before、cue-after、cue、play-during

可继承属性

  • 字体系列属性:font-family(字体系列)、font-weight(字体粗细)、font-size(字体大小)、font-style(字体风格)
  • 文本系列属性:text-indent(文本缩进)、text-align(文本水平对齐)、line-height(文本行高)、word-spacing(单词间距)、letter-spacing(中文或者字母间距)、text-transform(文本大小写,uppercase、lowercase、capitalize)、color(字体颜色)
  • 元素可见属性:visibility(元素显示隐藏)
  • 列表布局属性:list-style(列表风格)、list-style-type、list-style-image、list-style-position
  • 光标属性:cursor(光标显示状态)

26、display的属性值及其作用

  • none:隐藏对象。与visibility属性的hidden值不同,其不为被隐藏的对象保留其物理空间
  • inline:指定对象为内联元素。
  • block:指定对象为块元素。
  • list-item:指定对象为列表项目。
  • inline-block:指定对象为内联块元素。(CSS2)
  • table:指定对象作为块元素级的表格。类同于html标签<table>(CSS2)
  • inline-table:指定对象作为内联元素级的表格。类同于html标签<table>(CSS2)
  • table-caption:指定对象作为表格标题。类同于html标签<caption>(CSS2)
  • table-cell:指定对象作为表格单元格。类同于html标签<td>(CSS2)
  • table-row:指定对象作为表格行。类同于html标签<tr>(CSS2)
  • table-row-group:指定对象作为表格行组。类同于html标签<tbody>(CSS2)
  • table-column:指定对象作为表格列。类同于html标签<col>(CSS2)
  • table-column-group:指定对象作为表格列组显示。类同于html标签<colgroup>(CSS2)
  • table-header-group:指定对象作为表格标题组。类同于html标签<thead>(CSS2)
  • table-footer-group:指定对象作为表格脚注组。类同于html标签<tfoot>(CSS2)
  • run-in:根据上下文决定对象是内联对象还是块级对象。(CSS3)
  • box:将对象作为弹性伸缩盒显示。(伸缩盒最老版本)(CSS3)
  • inline-box:将对象作为内联块级弹性伸缩盒显示。(伸缩盒最老版本)(CSS3)
  • flexbox:将对象作为弹性伸缩盒显示。(伸缩盒过渡版本)(CSS3)
  • inline-flexbox:将对象作为内联块级弹性伸缩盒显示。(伸缩盒过渡版本)(CSS3)
  • flex:将对象作为弹性伸缩盒显示。(伸缩盒最新版本)(CSS3)
  • inline-flex:将对象作为内联块级弹性伸缩盒显示。(伸缩盒最新版本)(CSS3)

27、display的block、inline和inline-block的区别

  • block:元素会独占一行,多个元素会令其一行,可以设置width、height、margin和padding属性;
  • inline:元素不会独占一行,设置width、height属性无效,但可以设置水平方向的margin和padding属性,垂直方向设置无效;
  • inline-block:允许元素像inline元素一样被定位,但同时也可以设置高度、宽度、内边距和外边距,就像block元素一样。
    html
    <style>
      .container {
        display: inline-block;
        height: 100px;
        background: red;
      }
    </style>
    <span class="container">
      <span>item1</span>
      <span>item2</span>
      <span>item3</span>
    </span>
    

对于行内元素和块级元素,特点如下:

  • 行内元素
    • 设置宽高无效
    • 可以设置水平方向的margin和padding,垂直方向设置则无效
    • 不会自动换行
  • 块级元素
    • 可以设置宽高
    • 设置margin和padding都有效
    • 会自动换行
    • 多个块状,排列方式从上往下

27、隐藏元素的方法有哪些?

  • display: none:渲染树不会包含该渲染对象,因此该元素不会在页面中占据位置,也不会响应绑定的监听事件
  • visibility: hidden:元素在页面中仍占据空间,但是不会响应绑定的监听事件
  • opacity: 0:将元素的透明度设置为0,以此隐藏元素,元素在页面中仍占据空间,同时也会响应绑定的监听事件
  • z-index: 负值:通过调整元素的层级,使其被其他元素遮盖
  • position: absolute:通过使用绝对定位将元素移除可视区域内
  • clip/clip-path:使用元素裁剪的方式,元素仍在页面中占据空间,但是不会响应绑定的监听事件
  • transform: scale(0, 0):将元素缩放为0,元素仍在页面中占据空间,但是不会响应绑定的监听事件

28、link和@import的区别

两者都可以用来引入外部样式表文件,但是有以下几点区别:

  1. 加载顺序:在页面加载时,link标签引入的CSS会同时被加载,而@import引入的CSS会等到页面加载完毕后再加载。
  2. 兼容性@import只能被IE5及以上版本的浏览器识别,而link标签没有这个限制。
  3. DOM可控性link标签可以通过JavaScript操作DOM动态地改变样式,而@import不支持。
  4. 权重:当存在相同选择器时,link引入的样式优先级更高,而@import引入的样式优先级较低。

因此,在实际使用中,尽量使用link标签引入外部样式表。只有在某些特殊情况下(如需要在某些条件下才引入样式),才考虑使用@import

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

  • 伪元素使用 2 个冒号,伪类使用1个冒号;
  • 伪元素添加了一个页面中没有的元素(只是从视觉效果上添加了,不是在文档树中添加), 伪类是给页面中已经存在的元素添加一个类

伪元素

用于创建一些不在文档树中的元素,并为其添加样式,例如:

css
p::before { content: '第一章' }
p::after { content: '第一章' }
p::first-line { background: red; }
p::first-letter { font-size: 20px; }
p::selection { color: #ccc; }

伪类

用于当已有元素处于某个状态的时候,我们为其添加对应的样式,例如:

css
a:hover { color: red }
p:first-child { color: blue; }

CSS3新增伪类:

  • p:first-of-type: 选择属于其父元素的首个<p>元素的每个<p>元素。
  • p:last-of-type: 选择属于其父元素的最后<p>元素的每个<p>元素。
  • p:only-of-type: 选择属于其父元素唯一的<p>元素的每个<p>元素。
  • p:only-child : 选择属于其父元素的唯一子元素的每个<p>元素。
  • p:nth-child(2): 选择属于其父元素的第二个子元素的每个<p>元素。
  • :enabled、:disabled: 控制表单控件的禁用状态。
  • :checked: 单选框或复选框被选中。

总结:伪类的操作对象是文档树中已有的元素,而伪元素则创建了一个文档树外的元素。因此,伪类和伪元素的区别在于:有没有创建一个文档树之外的元素。 参考

30、对requestAnimation的理解

requestAnimationFrame是一个浏览器的API,主要用于执行动画。它告诉浏览器你希望执行一个动画,并请求浏览器在下一次重绘之前调用特定的函数来更新动画。这个方法使用一个回调函数作为参数,这个回调函数会在浏览器下一次重绘之前执行。

requestAnimationFrame的主要优点在于它可以由浏览器进行优化。如果页面不处于激活状态或者隐藏在其他标签页后面,requestAnimationFrame会暂停调用,从而节省CPU资源。当页面重新被激活或者用户切换到该标签页时,requestAnimationFrame才会继续调用。而且requestAnimationFrame的调用频率与屏幕的刷新频率相匹配,通常是每秒60次,这可以确保动画的流畅性。

js
const element = document.getElementById('box');
let position = 0;
function animate() {
  position += 1;
  element.style.transform = `translateX(${position}px)`;
  requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

这段代码会让一个id"box"的元素向右移动,每次移动一个像素。通过调用requestAnimationFrame函数,浏览器会在下一次页面重绘之前执行animate函数,实现了动画效果。由于requestAnimationFrame的使用方式较为简单,因此它经常被用于实现各种网页动画。

31、为什么有时候用translate来改变位置而不是定位?

translatetransform属性的一个值,改变transformopacity不会触发浏览器重排(reflow)或重绘(repaint),只会触发复合(compositions),而改变绝对定位会触发重排,进而触发重绘和复合。

transform使浏览器为元素创建一个GPU图层,但改变绝对定位会使用到CPU,因此translate更高效,可以缩短平滑动画的绘制时间,而translate改变位置时,元素依然会占据原始空间,绝对定位就不会发生这种情况。

32、li与li之间有看不见的空白间隔是什么原因引起?如何解决?

浏览器会把inline内联元素间的空白字符(空格、换行、tab等)渲染成一个空格,为了美观,通常是一个<li>放在一行,如下面所示:

html
<ul>
  <li>
    哈哈
  </li>
</ul>

这样就导致产生了换行字符,它变成了一个空格,占用了一个字符的宽度。

解决方法

  • 为所有<li>设置float: left。不足:有些容器是不能设置浮动的,如左右切换的焦点图等
  • 将所有<li>写在同一行。不足:代码不美观
    html
    <ul>
      <li>哈哈</li>
    </ul>
    
  • <ul>内的字符尺寸设为0,即font-size: 0。不足:<ul>中的其他字符尺寸也被设为0,需要额外重新设定其他字符尺寸,且在Safari浏览器依然会出现空白间隔
    css
    ul {
      font-size: 0px;
    }
    
  • 消除<ul>的字符间隔letter-spacing: -8px。不足:这也设置了<li>内的字符间隔,一次需要将<li>内的字符间隔设置为默认letter-spacing: normal
    css
    ul {
      letter-spacing: -8px;
    }
    ul li {
      letter-spacing: normal;
    }
    

33、替换元素的概念及计算规则

替换元素指的是在渲染过程中,由浏览器根据元素的标签和属性生成的具有固定大小和内容的元素。例如,imgvideoiframe等元素就是替换元素。

CSS计算替换元素的尺寸时,会根据以下规则进行计算:

  1. 如果元素有明确的尺寸(如width和height属性),则使用这些值作为尺寸。
  2. 如果元素没有明确的尺寸,但有默认的尺寸(如img元素的默认宽度为实际图片宽度),则使用默认尺寸。
  3. 如果元素既没有明确的尺寸也没有默认的尺寸,则按照其父元素的尺寸或其他相关因素来计算尺寸。
  4. 如果元素的尺寸无法确定,则视情况而定,可能会显示为空白或者以默认尺寸渲染。

34、常见的图片格式及使用场景

常见的图片格式有:

  1. JPEG(.jpg/.jpeg):适用于照片和图像,支持高压缩比,但是可能会损失一些细节和质量。
  2. PNG(.png):适用于图标、透明图片以及需要无损压缩的图片,支持透明度,文件大小相对较大。
  3. GIF(.gif):适用于动画和简单图形,支持动画和透明度,但是色彩表现力较差。
  4. SVG(.svg):矢量图形格式,支持无限放大而不失真,适用于图标和简单图形。
  5. WebP(.webp):由谷歌开发的图片格式,支持高压缩比和透明度,文件大小相对较小。

使用场景如下:

  1. 如果需要在网页上显示照片或图像,通常使用JPEG格式。
  2. 如果需要显示透明图片或者图片需要无损压缩,通常使用PNG格式。
  3. 如果需要制作动画,通常使用GIF格式。
  4. 如果需要制作图标或简单图形,通常使用SVG格式。
  5. 如果需要提高网页加载速度或者需要在移动设备上显示图片,可以考虑使用WebP格式。

34、对 CSSSprites 的理解

CSSSprites(精灵图或雪碧图),将一个页面涉及到的所有图片都包含到一张大图中去,然后利用CSS的 background-image,background-repeat,background-position属性的组合进行背景定位。

实践:以JD首页最底部版权栏为例

html
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>
<div class="box5"></div>
<div class="box6"></div>
css
div {
  width: 103px;
  height: 32px;
  float: left;
  margin: 10px;
  background-image: url(http://img.itchenliang.club/img/202302141017007.png);
}
.box1{background-position: -205px -111px;}  /*第一个图的位置,从图片的左上角开始计算*/
.box2{background-position:-205px  -74px;}
.box3{background-position: -205px -37px;}
.box4{background-position: -205px -0px;}
.box5{background-position: 0px 79px;}
.box6{background-position:-205px 86px;}

效果如下:

  • 原图 202302141015522.png
  • 效果图 202302141018594.png

优点:

  • 减少 HTTP 请求数,极大地提高页面加载速度。
  • 增加图片信息重复度,提高压缩比,减少图片大小。
  • css sprites 能减少图片的字节,把3张图片合并成1张图片的字节总是小于这3张图片的字节总和
  • 更换风格方便,只需在一张或几张图片上修改颜色或样式即可实现。

缺点:

  • 在图片合并时,要把多张图片有序的、合理的合并成一张图片,还要留好足够的空间,防止板块内出现不必要的背景。在宽屏及高分辨率下的自适应页面,如果背景不够宽,很容易出现背景断裂;
  • 在开发的时候相对来说有点麻烦,需要借助 photoshop或其他工具来对每个背景单元测量其准确的位置;
  • 在维护的时候比较麻烦,页面背景有少许改动时,就要改这张合并的图片,无需改的地方尽量不要动,这样避免改动更多的 css,如果在原来的地方放不下,又只能(最好)往下加图片,这样图片的字节就增加了,还要改动css;

35、什么是物理像素,逻辑像素和像素密度,为什么在移动端开发时需要用到@3x, @2x这种图片?

物理像素

物理像素(Physical Pixel)也被称为实际像素或硬件像素,是显示器、手机屏幕等数字显示设备上的物理光点,是组成图像的最基本单元。每个物理像素都代表了屏幕上的一个固定区域,可以发出一定亮度和颜色的光。物理像素的数量决定了屏幕的分辨率,即一个设备的物理像素越多,屏幕的分辨率就越高,显示的图像也就越清晰。

逻辑像素

逻辑像素(Logical Pixel)则是一种用于描述颜色信息的虚拟像素,通常用于描述图像的尺寸。逻辑像素并非实际存在的物理单元,而是图像处理软件(如Photoshop)用于表示图像中微小彩色方块网格上的某个位置的颜色值。这些颜色值被存储在逻辑像素中,并通过屏幕上的物理像素显示出来。

像素密度

像素密度(Pixel Density)是指单位面积内像素的数量,通常以像素每英寸(PPI)或像素每厘米(PPC)来表示。像素密度越高,显示设备的图像质量就越好,因为更多的像素可以显示更多的细节和颜色。

在移动端开发中,使用@3x、@2x等图片的原因是为了解决由于设备分辨率和像素密度不同导致的图像显示问题。由于不同设备的物理像素数量和像素密度不同,如果直接使用相同尺寸的图片,可能会导致在某些设备上显示模糊或失真。因此开发者需要根据设备的像素密度提供不同尺寸的图片,以确保图像在不同设备上都能以最佳的方式显示。

可以使用 CSS 媒体查询来判断不同的像素密度,从而选择不同的图片:

css
<img srcset="image-1x.jpg 1x, image-2x.jpg 2x, image-3x.jpg 3x" src="image-1x.jpg" alt="Responsive Image">
img {  
  width: 100%; /* 让图片填满容器宽度 */  
  height: auto; /* 保持图片的宽高比 */  
  display: block; /* 移除图片底部的空白 */  
}  

/* 针对像素密度大于 1 的设备,选择更高分辨率的图片 */  
@media screen and (-webkit-min-device-pixel-ratio: 1.5),  
      screen and (min-resolution: 1.5dppx) {  
  img {  
    srcset: "image-2x.jpg 2x, image-3x.jpg 3x";  
    src: "image-2x.jpg"; /* 在不支持 srcset 的浏览器中回退使用 */  
  }  
}  

/* 针对像素密度大于 2 的设备,选择最高分辨率的图片 */  
@media screen and (-webkit-min-device-pixel-ratio: 2),  
      screen and (min-resolution: 2dppx) {  
  img {  
      srcset: "image-3x.jpg 3x";  
      src: "image-3x.jpg"; /* 在不支持 srcset 的浏览器中直接使用最高分辨率图片 */  
  }  
}

上面例子中<img>标签使用了srcset属性来定义多组图片资源及对应的像素密度。默认情况下,浏览器会使用src属性中指定的图片(即image-1x.jpg),然后我们在css代码中使用了两个媒体查询来针对像素密度大于1.5和大于2的设备。在这些媒体查询中,我们重新定义了srcsetsrc的值,以便浏览器选择更高分辨率的图片。如果浏览器不支持srcset属性,它会回退到使用src属性中指定的图片。

36、margin和padding的使用场景

  • 需要在border外侧添加空白,且空白处不需要背景(色)时,使用 margin;
  • 需要在border内测添加空白,且空白处需要背景(色)时,使用 padding;

37、对 line-height 的理解及其赋值方式

line-height的概念:

  • line-height指一行文本的高度,包含了字间距,实际上是下一行基线到上一行基线距离;
  • 如果一个标签没有定义 height 属性,那么其最终表现的高度由 line-height 决定;
  • 把 line-height 值设置为 height 一样大小的值可以实现单行文字的垂直居中;
  • line-height 和 height 都能撑开一个高度;

line-height的赋值方式:

  • 带单位:px 是固定值,而 em 会参考自身元素 font-size 值计算自身的行高
  • 纯数字:会把比例传递给后代。例如,父级行高为 1.5,子元素字体为 18px,则子元素行高为 1.5 * 18 = 27px
  • 百分比:将计算后的值传递给后代

38、实现三列布局,side1 和 side2 左右两列宽度固定(200px),main 中间宽度自适应(不能用弹性盒)

html
<style>
  * {
    margin: 0;
    padding: 0;
    font-size: 50px;
  }

  .main {
    position: relative;
    width: 100%;
    height: 500px;
  }

  .left {
    position: absolute;
    top: 0;
    left: 0;
    width: 200px;
    height: 100%;
    background-color: #3898b1;
  }

  .right {
    position: absolute;
    top: 0;
    right: 0;
    width: 200px;
    height: 100%;
    background-color: #ce7486;
  }

  .middle {
    margin: 0 200px;
    height: 100%;
    background-color: #cbaf91;
  }
</style>
<div class="main">
  <div class="left">left</div>
  <div class="middle">middle</div>
  <div class="right">right</div>
</div>

效果如下: 202302091635511.png

39、使用 CSS3 设计一个立起的圆形,并围绕自身中轴线做 360° 持续旋转

https://blog.csdn.net/qq_48085286/article/details/126534588

40、要求实现以下效果:字体颜色在 IE6 下为黑色(#000000);IE7下为红色(#ff0000); 而其他浏览器下为绿色(#00ff00)

html
<style>
p{
color: green;
}
</style>
<!-- 参考:https://blog.csdn.net/weixin_33704234/article/details/92419637 -->
<!--[if lte IE6]>
<style>
p{
color: black;
}
</style>
<![endif] -->

<!--[if IE 7]>
<style>
p{
color: red;
}
</style>
<![endif]-->

或者

css
p {
  color: green;
  *color: red;
  _color: black;
}

41、position 属性有哪些值,分别代表什么意思? 使用与什么场景?

  • static: 正常文档流定位,此时 top, right, bottom, left 和 z-index 属性无效,块级元素从上往下纵向排布,行级元素从左向右排列。
  • relative:相对定位,此时的『相对』是相对于正常文档流的位置。
  • absolute:相对于最近的非 static 定位祖先元素的偏移,来确定元素位置,比如一个绝对定位元素它的父级、和祖父级元素都为relative,它会相对他的父级而产生偏移。
  • fixed:指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变,比如那种回到顶部的按钮一般都是用此定位方式。
  • sticky:粘性定位,特性近似于relative和fixed的合体,其在实际应用中的近似效果就是IOS通讯录滚动的时候的『顶屁股』。

42、style 标签写在 body 后和 body 前有什么区别?

<style>标签放置在<head>元素内,可以更好地优化页面性能和用户体验。

  • 将样式表放置在<head>元素中的<style>标签内,可以让页面更快地呈现出来。因为浏览器会先加载和渲染页面的基础结构,然后才会处理样式信息。
  • 如果将<style>标签放置在<body>元素后面,浏览器需要等到整个文档都被解析和加载之后才能开始渲染页面,这会导致页面显示延迟,用户可能会感到不舒服。

43、::bofore 和 :hover 中双冒号和单冒号有什么区别?

实则是考伪类和伪元素的区别,参考

44、有哪些手段可以优化 CSS, 提高性能

  1. 首推的是合并css文件,如果页面加载10个css文件,每个文件1k,那么也要比只加载一个100k的css文件慢。
  2. 减少css嵌套,最好不要套三层以上。
  3. 不要在ID选择器前面进行嵌套,ID本来就是唯一的而且人家权值那么大,嵌套完全是浪费性能。
  4. 建立公共样式类,把相同样式提取出来作为公共类使用,比如我们常用的清除浮动等。
  5. 减少通配符*或者类似[hidden="true"]这类选择器的使用,挨个查找所有... 这性能能好吗?当然重置样式这些必须 的东西是不能少的。
  6. 巧妙运用css的继承机制,如果父节点定义了,子节点就无需定义。
  7. 拆分出公共css文件,对于比较大的项目我们可以将大部分页面的公共结构的样式提取出来放到单独css文件里,这样一次下载后就放到缓存里,当然这种做法会增加请求,具体做法应以实际情况而定。
  8. 不用css表达式,表达式只是让你的代码显得更加炫酷,但是他对性能的浪费可能是超乎你的想象的。
  9. 少用css rest,可能你会觉得重置样式是规范,但是其实其中有很多的操作是不必要不友好的,有需求有兴趣的 朋友可以选择normolize. css
  10. cssSprite,合成所有icon图片,用宽高加上bacgroud-position的背景图方式显现出我们要的icon图,这是一种 十分实用的技巧,极大减少了http请求。
  11. 当然我们还需要一些善后工作,CSS压缩(这里提供一个在线压缩 YUI Compressor ,当然你会用其他工具来压缩是十 分好的),
  12. GZIP压缩,Gzip是一种流行的文件压缩算法,详细做法可以谷歌或者百度。

45、说下 CSS3 中一些样式的兼容,分别指兼容哪些浏览器

浏览器前缀

css
IE9:-ms-
Firfox: -moz-
Chrome and Safari: -webkit-
Opera: -o-
  1. border-image、 border-radius 和 box-shadow 属性兼容性
  • IE不支持border-image
  • IE9+支持 border-radius 和 box-shadow 属性
  • 对于 border-image,Safari 5 以及更老的版本需要前缀 -webkit-。
  • Opera 支持 border-radius 和 box-shadow 属性,但是对于 border-image 需要前缀 -o-
  1. 文本效果属性
  • IE9以及更早的版本,不支持 text-shadow 属性。其他浏览器均支持。
  1. transform 属性
  • IE10、Firefox 以及 Opera 支持 transform 属性。
  • Chrome 和 Safari 需要前缀 -webkit-
  • IE9 需要前缀 -ms-
  1. 过渡效果transtion属性
  • IE10、Firefox、Chrome 以及 Opera 支持 transition 属性。
  • Safari 需要前缀 -webkit-
  • IE9以及更早的版本,不支持 transition 属性
  • Chrome25 以及更早的版本,需要前缀 -webkit-。
  1. 动画效果@keyframes属性
  • IE10、Firefox 以及 Opera 支持 @keyframes 规则和 animation 属性。
  • Chrome 和 Safari 需要前缀 -webkit-。
  • IE9,以及更早的版本,不支持 @keyframe 规则或 animation 属性。

46、怎么样实现边框0.5个像素?

html
<div class="box box1"></div>
  • 方法一: 伪元素+scale
    • 原理:将容器设置伪元素,设置绝对定位,宽高设置200%,边框设置为1px,然后用transform:scale(0.5),使伪元素缩小到原来的一半,此时伪元素的边框会和容器的边缘重合。
    • 优点:兼容性好
    css
    .box {
      width: 360px;
      height: 50px;
      border-radius: 5px;
      margin-top: 20px;
      line-height: 50px;
    }
    .box1 {
      position: relative;
    }
    .box1::after {
      position: absolute;
      bottom: 0;
      z-index: -1;
      width: 200%;
      height: 200%;
      content: "";
      display: block;
      border: 1px solid red;
      border-radius: 5px;
      transform: scale(0.5);
      transform-origin: left bottom;
    }
    
  • 方法二:背景渐变
    • 原理:给容器设置伪元素,设置绝对定位,高度1px,背景图设置线性渐变,一半设置颜色,一半设置透明,就可以实现0.5px边框了。但是不能展示圆角
    • 优点:简单,适合一根线的边框
    css
    .box {
      width: 360px;
      height: 50px;
      border-radius: 5px;
      margin-top: 20px;
      line-height: 50px;
    }
    .box1 {
      position: relative;
    }
    .box1::after {
      position: absolute;
      content: "";
      width: 100%;
      height: 1px;
      bottom: 0px;
      background-color: red;
      background: linear-gradient(to bottom, transparent 50%, red 50%);
    }
    
  • 方法三:利用阴影代替边框
    • 原理:利用盒子阴影设置
    • 优点:可以实现更细的边框
    css
    .box {
      width: 360px;
      height: 50px;
      border-radius: 5px;
      margin-top: 20px;
      line-height: 50px;
    }
    .box1 {
      box-shadow: 0 0 0 0.5px red;
    }
    

47、如何理解z-index?

CSS 中的z-index属性控制重叠元素的垂直叠加顺序,默认元素的z-index0,我们可以修改z-index来控制元素的图层位置,而且z-index只能影响设置了position值的元素。

48、如何理解层叠上下文?

在CSS2.1规范中,每个盒模型的位置是三维的,分别是平面画布上的x轴,y轴以及表示层叠的z轴。层叠上下文即元素在某个层级上z轴方向的排列关系

可以想象一张桌子,上面有一堆物品,这张桌子就代表着一个层叠上下文。如果在第一张桌子旁还有第二张桌子,那第二张桌子就代表着另一个层叠上下文。

产生条件

  • 根元素 (HTML),
  • position值为absolute|relative,且z-index值不为auto
  • position值为fixed|sticky
  • z-index值不为autoflex元素,即:父元素display:flex|inline-flex
  • opacity属性值小于1的元素
  • transform属性值不为none的元素
  • mix-blend-mode属性值不为normal的元素
  • filterperspectiveclip-pathmaskmask-imagemask-bordermotion-path值不为none的元素
  • isolation属性被设置为isolate的元素
  • will-change中指定了任意 CSS 属性,即便你没有直接指定这些属性的值
  • -webkit-overflow-scrolling属性被设置touch的元素

49、你对媒体查询的理解?

媒体查询是自 CSS3 开始加入的一个功能。它可以进行响应式适配展示。

  • 使用@media查询,可以针对不同的媒体类型定义不同的样式
  • @media可以针对不同的屏幕尺寸设置不同的样式
  • 当你重置浏览器大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面
  • 目前针对很多苹果手机、Android手机,平板等设备都用得到媒体查询

语法规范

css
@media mediatype and|not|only (media feature){
  css-code;
}
  • mediatype: 媒体类型,all(所有设备)、print(打印机和打印预览)、screen(电脑屏幕、平板电脑、智能手机等)
  • 关键字: 关键字将媒体类型或多个特性连接到一起做为媒体查询的条件
    • and: 可以将多个媒体特性连接到一起,相当"且"于的意思
    • not: 排除某个媒体类型,相当于"非"的意思,可以省略
    • only: 指定某个特定的媒体类型,可省略
  • media feature: 媒体特性,他们要加小括号包含
    • width: 定义输出设备中页面可见区域的宽度
    • min-width: 定义输出设备中最小页面可见区域的宽度
    • max-width: 定义输出设备中最大页面可见区域的宽度

如何使用

html
<!-- link元素中的CSS媒体查询 -->
<link rel="stylesheet" media="(max-width: 800px)" href="example.css" />
<!-- 样式表中的CSS媒体查询 -->
<style>
@media screen and (max-width: 600px) {
  .facet_sidebar {
    display: none;
  }
}
</style>

50、实现不使用 border 画出 1px 高的线,在不同浏览器的标准模式与怪异模式下都能保持一致的效果。

html
<div style="height:1px;overflow:hidden;background:red"></div>

51、什么是外边距重叠?重叠的结果是什么?

外边距重叠就是margin-collapse,在 CSS 当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。

折叠结果遵循下列计算规则:

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

52、rgba()和opacity的透明效果有什么不同?

rgba()opacity都能实现透明效果,但最大的不同:

  • opacity作用于元素,以及元素内的所有内容的透明度,
  • rgba()只作用于元素的颜色或其背景色。(设置rgba透明的元素的子元素不会继承透明效果!)

53、css 中可以让文字在垂直和水平方向上重叠的两个属性是什么?

  • 垂直方向:line-height
  • 水平方向:letter-spacing

那么问题来了,关于letter-spacing的妙用知道有哪些么?

可以用于消除inline-block元素间的换行符空格间隙问题。

54、如何水平垂直居中一个元素?

html
<!-- 基础布局代码 -->
<div class="box">
  <div class="center"></div>
</div>
  • 1、margin:auto
    css
    .box {
      width: 200px;
      height: 200px;
      background-color: #eee;
      position: relative;
      margin-top: 20px;
    }
    .center {
      width: 50px;
      height: 50px;
      background-color: #00ACED;
      margin: auto;
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
    }
    
  • 2、position:absolute
    css
    .box {
      width: 200px;
      height: 200px;
      background-color: #eee;
      position: relative;
      margin-top: 20px;
    }
    /** 结合margin */
    .center {
      width: 50px;
      height: 50px;
      background-color: #00ACED;
      position: absolute;
      left: 50%;
      top: 50%;
      margin-top: -25px;
      margin-left: -25px;
    }
    /** 使用calc */
    .center {
      width: 50px;
      height: 50px;
      background-color: #00ACED;
      position: absolute;
      left: calc(50% - 25px);
      top: calc(50% - 25px);
    }
    /** 结合 transform */
    .center {
      width: 50px;
      height: 50px;
      background-color: #00ACED;
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
    }
    
  • 3、line-height = height
    html
    <style>
      .box {
        width: 200px;
        height: 200px;
        background-color: #eee;
        position: relative;
        margin-top: 20px;
      }
      .center {
        line-height: 200px;
        text-align: center;
      }
    </style>
    <div class="box">
      <div class="center">文字居中</div>
    </div>
    
  • 4、弹性布局
    css
    .box {
      width: 200px;
      height: 200px;
      background-color: #eee;
      position: relative;
      margin-top: 20px;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .center {
      width: 50px;
      height: 50px;
      background-color: #00ACED;
    }
    
  • 5、网格布局
    css
    /** 第一种: 对元素本身属性进行设置 */
    .box {
      width: 200px;
      height: 200px;
      background-color: #eee;
      position: relative;
      margin-top: 20px;
      display: grid;
    }
    .center {
      width: 50px;
      height: 50px;
      background: #00ACED;
      align-self: center;
      justify-content: center;
      margin: auto;
    }
    
    /** 第二种: 在元素的父级元素中设置 */
    .box {
      width: 200px;
      height: 200px;
      background-color: #eee;
      position: relative;
      margin-top: 20px;
      display: grid;
      display: grid;
      align-items: center;
      justify-content: center;
    }
    .center {
      width: 50px;
      height: 50px;
      background: #00ACED;
    }
    
  • 6、table-cell布局
    css
    .box {
      width: 200px;
      height: 200px;
      background-color: #eee;
      position: relative;
      margin-top: 20px;
      display: table-cell;
      text-align: center;
      vertical-align: middle;
    }
    .center {
      width: 50px;
      height: 50px;
      background: #00ACED;
      display: inline-block;
    }
    

    那么问题来了,如何垂直居中一个img(用更简便的方法)

    css
    .content {
      /** img的容器设置如下 */
      display: table-cell;
      text-align: center;
      vertical-align: middle;
    }
    

55、Sass、Less、Stylus 是什么?大家为什么要使用他们?

是 CSS 预处理器。他是 CSS 上的一种抽象层。他们是一种特殊的语法/语言编译成 CSS。

  • Less 是一种动态样式语言. 将 CSS 赋予了动态语言的特性,如变量,继承,运算, 函数. LESS 既可以在客户端上运行 (支持 IE 6+, Webkit, Firefox),也可一在服务端运行 (借助 Node.js)。
  • Sass 是一种 CSS 的预编译语言。它提供了 变量(variables)、嵌套(nested rules)、 混合(mixins)、 函数(functions)等功能,并且完全兼容 CSS 语法。Sass 能够帮助复杂的样式表更有条理, 并且易于在项目内部或跨项目共享设计。
  • Stylus 是一款 CSS 的预处理器,也就是我们常说的 CSS 框架。

为什么要使用它们?

  • 结构清晰,便于扩展。
  • 可以方便地屏蔽浏览器私有语法差异。这个不用多说,封装对浏览器语法差异的重复处理,减少无意义的机械劳动。
  • 可以轻松实现多重继承。
  • 完全兼容 CSS 代码,可以方便地应用到老项目中。LESS 只是在 CSS 语法上做了扩展,所以老的 CSS 代码也可以与 LESS 代码一同编译。

使用 CSS 预处理的优缺点分别是什么?

优点

  • 提高 CSS 可维护性。
  • 易于编写嵌套选择器。
  • 引入变量,增添主题功能。可以在不同的项目中共享主题文件。
  • 通过混合(Mixins)生成重复的 CSS。
  • Splitting your code into multiple files. CSS files can be split up too but doing so will require a HTTP request to - - download each CSS file.
  • 将代码分割成多个文件。不进行预处理的 CSS,虽然也可以分割成多个文件,但需要建立多个 HTTP 请求加载这些文件。

缺点

  • 需要预处理工具。
  • 重新编译的时间可能会很慢。

56、移动端 1px 问题的解决办法

推荐解决方法:媒体查询 + transfrom

css
/* 2倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 2.0) {
    .border-bottom::after {
        -webkit-transform: scaleY(0.5);
        transform: scaleY(0.5);
    }
}
/* 3倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 3.0) {
    .border-bottom::after {
        -webkit-transform: scaleY(0.33);
        transform: scaleY(0.33);
    }
}

57、几种常见的 CSS 布局

参考

单列布局

202302251608595.png 常见的单列布局有两种:

  • header,content和footer等宽的单列布局
    先通过对header,content,footer统一设置width:1000px;或者max-width:1000px(这两者的区别是当屏幕小于1000px时,前者会出现滚动条,后者则不会,显示出实际宽度);然后设置margin:auto实现居中即可得到。
    html
    <div class="header"></div>
    <div class="content"></div>
    <div class="footer"></div>
    
    css
    .header{
      margin:0 auto; 
      max-width: 960px;
      height:100px;
      background-color: blue;
    }
    .content{
      margin: 0 auto;
      max-width: 960px;
      height: 400px;
      background-color: aquamarine;
    }
    .footer{
      margin: 0 auto;
      max-width: 960px;
      height: 100px;
      background-color: aqua;
    }
    
  • header与footer等宽,content略窄的单列布局
    header、footer的内容宽度不设置,块级元素充满整个屏幕,但header、content和footer的内容区设置同一个width,并通过margin:auto实现居中。
    html
    <div class="header">
      <div class="nav"></div>
    </div>
    <div class="content"></div>
    <div class="footer"></div>
    
    css
    .header{
      margin:0 auto;
      max-width: 960px;
      height:100px;
      background-color: blue;
    }
    .nav{
      margin: 0 auto;
      max-width: 800px;
      background-color: darkgray;
      height: 50px;
    }
    .content{
      margin: 0 auto;
      max-width: 800px;
      height: 400px;
      background-color: aquamarine;
    }
    .footer{
      margin: 0 auto;
      max-width: 960px;
      height: 100px;
      background-color: aqua;
    }
    

两列自适应布局

两列自适应布局是指一列由内容撑开,另一列撑满剩余宽度的布局方式。实现方式主要有如下几种:

  1. float+overflow:hidden
    如果是普通的两列布局,浮动+普通元素的margin便可以实现,但如果是自适应的两列布局,利用float+overflow:hidden便可以实现,这种办法主要通过overflow触发BFC,而BFC不会重叠浮动元素。由于设置overflow:hidden并不会触发IE6-浏览器的haslayout属性,所以需要设置zoom:1来兼容IE6-浏览器。具体代码如下:
html
<div class="parent" style="background-color: lightgrey;">
  <div class="left" style="background-color: lightblue;">
    <p>left</p>
  </div>
  <div class="right"  style="background-color: lightgreen;">
    <p>right</p>
    <p>right</p>
  </div>        
</div>
css
.parent {
  overflow: hidden;
  zoom: 1;
}
.left {
  float: left;
  margin-right: 20px;
}
.right {
  overflow: hidden;
  zoom: 1;
}

注意: 如果侧边栏在右边时,注意渲染顺序。即在HTML中,先写侧边栏后写主内容。 2. Flex布局
Flex布局,也叫弹性盒子布局,区区简单几行代码就可以实现各种页面的的布局。

css
// html部分同上
.parent {
  display:flex;
}  
.right {
  margin-left:20px; 
  flex:1;
}
  1. grid布局
    Grid布局,是一个基于网格的二维布局系统,目的是用来优化用户界面设计。
css
// html部分同上
.parent {
  display:grid;
  grid-template-columns:auto 1fr;
  grid-gap:20px
} 

三栏布局(圣杯布局、双飞翼布局)

特征:中间列自适应宽度,旁边两侧固定宽度,主要实现方式有如下几种:

圣杯布局

比较特殊的三栏布局,圣杯布局使用了相对定位和负边距的技巧,中间栏通过设置padding来让内容占满整个空间,实现自适应宽度,两侧栏设置固定宽度并通过相对定位脱离文档流和使用负边距向中间栏释放空间。该布局的优点是可以完全兼容所有浏览器,但是实现过程比较复杂。

html
<div class="container">
  <div class="left"></div>
  <div class="main"></div>
  <div class="right"></div>
</div>
css
.container {
  padding: 0 150px;
  margin: 0 auto;
}

.left, .main, .right {
  float: left;
  height: 200px;
}

.left {
  width: 150px;
  margin-left: -100%;
  position: relative;
  right: 150px;
}

.main {
  width: 100%;
  padding: 0 200px;
}

.right {
  width: 150px;
  margin-right: -150px;
  position: relative;
  left: -150px;
}

双飞翼布局

同样也是三栏布局,双飞翼布局使用了 CSS 的盒子模型和浮动布局,中间栏和两侧栏都使用div元素实现,中间栏宽度为100%,包含左右两个自定义的div元素,作为内容容器。两侧栏使用负边距、相对定位和 div 元素设置边框实现宽度为固定宽度的效果。该布局的优点是实现比较简单,但不兼容 IE6 及以下版本。

html
<div class="container clearfix">
  <div class="main"></div>
</div>
<div class="left"></div>
<div class="right"></div>
css
.container {
  margin: 0 150px;
}

.main {
  float: left;
  width: 100%;
}

.left, .right {
  float: left;
  position: relative;
  width: 150px;
  height: 200px;
}

.left {
  margin-left: -100%;
  right: 150px;
  border: 1px solid #ccc;
}

.right {
  margin-right: -150px;
  left: -150px;
  border: 1px solid #ccc;
}

两种布局实现方式对比:

  • 两种布局方式都是把主列放在文档流最前面,使主列优先加载。
  • 两种布局方式在实现上也有相同之处,都是让三列浮动,然后通过负外边距形成三列布局。
  • 两种布局方式的不同之处在于如何处理中间主列的位置:
    • 圣杯布局是利用父容器的左、右内边距+两个从列相对定位;
    • 双飞翼布局是把主列嵌套在一个新的父级块中利用主列的左、右外边距进行布局调整

等高布局

等高布局是指子元素在父元素中高度相等的布局方式,主要实现方式有如下几种:

  • 利用正padding+负margin
    我们通过等布局便可解决圣杯布局的第二点缺点,因为背景是在 padding 区域显示的,设置一个大数值的 padding-bottom,再设置相同数值的负的 margin-bottom,并在所有列外面加上一个容器,并设置 overflow:hidden 把溢出背景切掉。这种可能实现多列等高布局,并且也能实现列与列之间分隔线效果,结构简单,兼容所有浏览器。新增代码如下:
    css
    .center,
    .left,
    .right {
      padding-bottom: 10000px;
      margin-bottom: -10000px;
    }
    .container {
      padding-left: 220px;
      padding-right: 220px;
      overflow: hidden;//把溢出背景切掉
    }
    
    202302251617099.png
  • 利用背景图片
    这种方法是我们实现等高列最早使用的一种方法,就是使用背景图片,在列的父元素上使用这个背景图进行Y轴的铺放,从而实现一种等高列的假象。实现方法简单,兼容性强,不需要太多的css样式就可以轻松实现,但此方法不适合流体布局等高列的布局。
    在制作样式之前需要一张类似下面的背景图: 202302251617448.png
    html
    <div class=”container clearfix”>
      <div class=”left”></div>
      <div  class=”content”></div>
      <div class=”right”></div>
    </div>
    
    css
    .container {
      background: url("column.png") repeat-y;
      width: 960px;
      margin: 0 auto;
    }
    .left {
      float: left;
      width: 220px;
    }
    .content {
      float: left;
      width: 480px;
    }
    .right {
      float: left;
      width: 220px;
    }
    
  • 模仿表格布局
    这是一种非常简单,易于实现的方法。不过兼容性不好,在ie6-7无法正常运行。
    html
      <div class="container table">
      <div class="containerInner tableRow">
        <div class="column tableCell cell1">
          <div class="left aside">
            ....
          </div>
        </div>
        <div class="column tableCell cell2">
          <div class="content section">
            ...
          </div>
        </div>
        <div class="column tableCell cell3">
          <div class="right aside">
            ...
          </div>
        </div>
      </div>
    </div>
    
    css
    .table {
      width: auto;
      min-width: 1000px;
      margin: 0 auto;
      padding: 0;
      display: table;
    }
    .tableRow {
      display: table-row;
    }
    .tableCell {
      display: table-cell;
      width: 33%;
    }
    .cell1 {
      background: #f00;
      height: 800px;
    }
    .cell2 {
      background: #0f0;
    }
    .cell3 {
      background: #00f;
    }
    
  • 使用边框和定位
    这种方法是使用边框和绝对定位来实现一个假的高度相等列的效果。结构简单,兼容各浏览器,容易掌握。假设你需要实现一个两列等高布局,侧栏高度要和主内容高度相等。
    html
    <div id="wrapper">
      <div id="mainContent">...</div>
      <div id="sidebar">...</div>
    </div>
    
    css
    #wrapper {
      width: 960px;
      margin: 0 auto;
    }
    #mainContent {
      border-right: 220px solid #dfdfdf;
      position: absolute;
      width: 740px;
      height: 800px;  
      background: green;
    }
    #sidebar {
      background: #dfdfdf;
      margin-left: 740px;
      position: absolute;
      height: 800px;
      width: 220px;
    }
    

粘连布局

所谓粘连布局(也可以叫做 sticky footer 布局),就是当内容区域元素没有超出容器时,网页底部 footer 紧贴在网页底部,当内容区域超长时,底部 footer 就会紧跟在内容区域底部,而不是紧贴在网页底部。

粘连布局示意图: 202302251620482.png

  • 特点:
    • 有一块内容<main>,当<main>的高康足够长的时候,紧跟在<main>后面的元素<footer>会跟在<main>元素的后面。
    • <main>元素比较短的时候(比如小于屏幕的高度),我们期望这个<footer>元素能够“粘连”在屏幕的底部 202302251621176.png
    html
    <div id="wrap">
      <div class="main">
        main <br />
        main <br />
        main <br />
      </div>
    </div>
    <div id="footer">footer</div>
    
    css
    * {
      margin: 0;
      padding: 0;
    }
    html,
    body {
      height: 100%;//高度一层层继承下来
    }
    #wrap {
      min-height: 100%;
      background: pink;
      text-align: center;
      overflow: hidden;
    }
    #wrap .main {
      padding-bottom: 50px;
    }
    #footer {
      height: 50px;
      line-height: 50px;
      background: deeppink;
      text-align: center;
      margin-top: -50px;
    }
    
  • 实现步骤
    • (1) footer必须是一个独立的结构,与wrap没有任何嵌套关系
    • (2) wrap区域的高度通过设置min-height,变为视口高度
    • (3) footer要使用margin为负来确定自己的位置
    • (4) 在main区域需要设置 padding-bottom。这也是为了防止负 margin 导致 footer 覆盖任何实际内容。

瀑布流布局

瀑布流(Waterfall Flow),也称为瀑布式布局、瀑布流布局等,是一种常见的网页设计布局。它的特点是将不同大小和高度的元素按照一定规则排列在一起,呈现出像瀑布一样流动的效果。

通常,瀑布流布局会将页面内容分成多列,在每列中依次排列元素。由于元素的高度不同,因此每列的高度也会不同,但它们都紧贴着上方元素的底部排列。瀑布流布局最早被应用于图片展示和商品展示等领域,由于其独特的视觉效果和较好的用户体验,目前已经广泛应用于各种类型的网站和应用程序中,如社交网络、新闻聚合网站、电子商务平台等。

58、设置元素浮动后,该元素的 display 值是多少?

自动变成display: block

59、怎么让 Chrome 支持小于 12px 的文字?

  1. 使用-webkit-text-size-adjust属性:将其设置为none可以禁用 Chrome 的字体大小调整机制,这样可以使得小于12px的字体正常显示。例如:
css
body {
  -webkit-text-size-adjust: none;
}
  1. 使用transform缩放:将父元素的font-size设置为大于等于12px的值,然后再对子元素使用transform缩放来达到小于12px的效果。例如:
css
.parent {
  font-size: 12px;
}
.child {
  transform: scale(0.8);
}

上面代码中,parent元素的font-size被设置为12px,然后child元素使用transform缩放为原来的80%,从而实现了小于12px的效果。需要注意的是,这种方法可能会导致模糊和锯齿效果,因此不适合用在大段文本中。

60、display:inline-block什么时候会显示间隙?

间隙产生的原因是因为,换行或空格会占据一定的位置

解决办法:父元素中设置font-size:0; letter-spaceing:-4px;

61、超链接访问过后 hover 样式就不出现的问题是什么?如何解决?

被点击访问过的超链接样式不在具有 hover 和 active 了, 解决方法是改变 CSS 属性的排列顺序: L-V-H-A(link, visited, hover, active)

62、什么是 Css Hack?ie6, 7, 8 的 hack 分别是什么?

CSS Hack是一种针对不同浏览器(如Internet Explorer、Firefox、Opera等)的CSS样式特殊写法,通过使用不同的CSS语法或者使用特定条件的判断语句,让CSS代码能够针对不同的浏览器进行差异化渲染,从而达到兼容的目的。

CSS Hack是因为现有浏览器对标准的解析不同,为了兼容各浏览器,所采用的一种补救方法。

CSS Hack常见的有三种形式:CSS属性Hack、CSS选择符Hack以及IE条件注释Hack,Hack主要针对IE 浏览器。

  • 属性级Hack:比如 IE6 能识别下划线_和星号*,IE7能识别星号*,但不能识别下划线_
  • 选择符级Hack:比如IE6能识别*html .class{},IE7能识别*+html .class{}或者*:first-child+html .class{}
  • IE条件注释Hack:IE条件注释是微软从IE5开始就提供的一种非标准逻辑语句。比如针对所有IE:<!–[if IE]><!–您的代码–><![endif]–>,针对IE6及以下版本:<!–[if lt IE 7]><!–您的代码–><![endif]–>,这类Hack不仅对CSS生效,对写在判断语句里面的所有代码都会生效。

对于IE6、7、8的hack,分别可以采用以下方式:

  • IE6的hack可以使用*或者_,例如*html .class { }或者_class { }
  • IE7的hack可以使用+html .class { }或者:first-child+html .class { }
  • IE8的hack可以使用\0或者\9,例如color:red\0;或者color:red\9;

随着浏览器的不断升级和标准化,CSS Hack的使用已经逐渐减少。现在,许多现代的前端开发技术,如使用CSS预处理器、模块化CSS、CSS-in-JS等,都能够帮助开发者更好地处理跨浏览器兼容性问题,减少CSS Hack的使用。

63、重置(resetting)CSS 和 标准化(normalizing)CSS 的区别是什么?你会选择哪种方式,为什么?

重置(Resetting)CSS

CSS 重置的主要思想是消除所有浏览器的默认样式,然后开发者再从零开始定义自己的样式。

例如reset.css会将所有的HTML元素的margin、padding和font-size等属性设置为相同的值,从而消除浏览器之间的默认样式差异。

标准化(Normalizing)CSS

CSS 标准化的主要思想则是保留一些有用的默认样式,同时纠正一些常见的浏览器布局问题和差异。

例如normalize.css会尽量保持浏览器的默认样式,但会修复一些常见的浏览器之间的不一致性,比如表单元素在不同浏览器中的默认样式差异。

对于选择哪种方式,主要取决于你的项目需求和个人喜好。

如果你想要完全控制所有的样式,并且希望从一个一致的起点开始,那么 CSS 重置可能是个不错的选择。这样就可以清楚地知道每个元素的默认样式,并且可以根据自己的需求来重新定义它们。 但如果你希望保留一些浏览器的默认样式,并且更关心的是解决浏览器之间的布局问题,那么 CSS 标准化可能更适合你。这种方式可以节省你重新定义所有元素样式的时间,同时也可以确保你的网站在不同浏览器中的一致性。

64、什么是 FOUC? 如何避免

FOUC,全称为Flash of Unstyled Content,也被称为文档样式短暂失效。它发生在HTML已加载而样式表尚未加载的时候,此后当样式表加载时,页面会重新渲染,产生闪烁现象。FOUC可能会导致用户在页面加载时看到未样式化的内容,从而影响用户体验。

FOUC通常是由以下原因引起的:

  • 使用@import方法导入样式表:当HTML文件被加载时,@import引用的文件会等待页面全部下载完毕再被加载,这可能导致页面在加载时出现没有样式的情况,从而产生FOUC现象。
    html
    <link rel="stylesheet" href="./style.css">
    <!-- style.css -->
    @import url('./other-style.css');
    .container {
      display: inline-block;
      height: 100px;
      background: red;
    }
    
  • 将样式表放在页面底部:如果样式表在HTML结构之后加载,那么在样式表加载之前,页面将按照原始HTML渲染,导致FOUC。
    html
    <span class="container">
      <span>item1</span>
      <span>item2</span>
      <span>item3</span>
    </span>
    <style>
      @import url('./style.css');
    </style>
    
  • 当有多个样式表且它们位于HTML结构的不同位置时,也可能导致FOUC

为了避免FOUC,可以采取以下措施:

  • 尽量避免使用@import,而使用<link>来引入CSS样式表。因为<link>引用的文件会在HTML文件加载时同时被加载,从而避免FOUC现象。
  • 将CSS样式表放在<head>标签内,以确保样式表尽早加载。
  • 使用CSS内联样式,将CSS样式直接嵌入在HTML内容中,这样可以避免样式表的延迟加载导致的FOUC问题。

65、行内元素 float:left 后是否变为块级元素?

  • 行内元素设置成浮动之后变得更加像是 inline-block
  • 行内块级元素,设置成这个属性的元素会同时拥有行内和块级的特性,最明显的不同是它的默认宽度不是 100%,行内元素默认 100%宽度占据一行
  • 这时候给行内元素设置 padding-top 和 padding-bottom 或者 width、height 都是有效果的

66、在网页中的应该使用奇数还是偶数的字体?为什么呢?

在网页中,应该使用偶数像素值的字体。

因为当使用奇数像素值的字体时,如13px15px等,在某些设备上可能会出现模糊和不清晰的问题,这是由于这些设备的屏幕分辨率与像素之间的对应关系导致的。而选择偶数像素值的字体,则可以避免这样的问题,并且能够在不同的设备上保持更加一致的显示效果。

67、CSS 合并方法

css
@import url(css 文件地址)

68、列出你所知道可以改变页面布局的属性

displaypositionfloatclearflexboxgridcolumnswidthheightmarginpaddingoverflowvisibilityz-indextransformtransitionanimation

69、CSS 在性能优化方面的实践

  • 1、压缩CSS文件,减小文件大小,可以使用压缩工具或者Webpack等打包工具自带的压缩功能。
  • 2、避免使用@import加载CSS文件,因为每个@import都会增加HTTP请求。
  • 3、使用CSS Sprites技术来减少图片请求,将多张小图标合并成一张大图,并通过background-position属性和定位来显示不同的图标。
  • 4、避免使用过多的CSS选择器,因为选择器越复杂,匹配元素所需的时间就越长。如果可能的话,尽量缩短选择器的层级。
  • 5、尽量避免使用!important,因为它会增加样式计算的复杂度,使得浏览器更难进行优化。
  • 6、使用类代替标签选择器,因为类的查找速度比标签要快。
  • 7、使用CSS前缀来支持不同浏览器的特性,但要避免使用过多的前缀。
  • 8、使用flexboxgrid布局来代替传统的布局方法,因为它们的性能更好。
  • 9、避免使用大量的阴影、边框和渐变效果等CSS3特性,因为它们对性能有一定的影响。
  • 10、使用媒体查询和响应式设计来减少不必要的CSS代码和布局计算。

70、CSS3 动画(简单动画的实现,如旋转等)

让一个 div 元素旋转 360 度示例

  1. div 的样式结构:
css
div {
  margin: 50px auto;
  width: 200px;
  height: 200px;
  background-color: pink;
}
  1. 设置旋转属性的类名:
css
div.rotate {
  /* 旋转360度 */
  transform: rotate(360deg);
  /* all表示所有属性,1s表示在一秒的时间完成动画 */
  transition: all 1s;
}

transition 有四个属性:

  • property: 规定应用过渡的 CSS 属性的名称。
  • duration: 定义过渡效果花费的时间。默认是 0,单位是 s。
  • timing-function: 规定过渡效果的时间曲线。默认是 "ease"。匀速'linear',加速'ease-in',减速'ease-out',先快后慢'ease-in-out'。
  • delay: 规定过渡效果何时开始。默认是 0。单位 s。 可以连写: transition: property duration timing-function delay;
  1. 给 div 元素设置鼠标移入时旋转, 也就是给它加上. rotate 类名. 鼠标移出时移除类名
js
 $(function() {
  $("div")
      .mouseenter(function() {
          $(this).addClass("rotate");
      })
      .mouseleave(function() {
          $(this).removeClass("rotate");
      });
}); 

71、base64 的原理及优缺点

Base64编码的基本原理是将任意二进制数据转换为纯文本格式。

具体实现上,Base64将每3个字节(共24位)的二进制数据转换为4个6位的字节,然后在6位的前面补两个0,形成8位一个字节的形式。如果剩下的字符不足3个字节,则用0填充,输出字符使用“=”。为了保证所输出的编码位可读字符,Base64制定了一个编码表,以便进行统一转换。

优点:

  • 占用内存小:Base64格式的图片是文本格式,相对于二进制格式的图片,占用内存更小。
  • 减少HTTP请求:将图片嵌入到网页中可以减少对服务器的请求次数,从而提高网页的加载速度。
  • 适合在不同平台、不同语言传输:Base64编码的字符串适合在不同平台、不同语言之间传输。
  • 解码方便:Base64编码是可逆的,可以通过解码得到原始数据。

缺点:

  • 增加字节数:Base64编码会增加数据的大小,大约会增加33%。
  • 不适合用于存储和传输大量图片:由于Base64编码会增加数据的大小,因此对于大量图片的存储和传输并不适合。
  • **可读性强:**Base64编码后的字符串具有可读性,不适合用于存储和传输敏感信息。

手写实现:

js
function base64EncodeManual(input) {  
    // 确保输入是字符串  
    if (typeof input !== 'string') {  
        throw new Error('Input must be a string.');  
    }  
  
    // Base64字符集  
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';  
  
    // 将输入字符串转换为UTF-8编码的字节数组  
    const utf8Bytes = [];  
    for (let i = 0; i < input.length; i++) {  
        const charCode = input.charCodeAt(i);  
        if (charCode < 128) {  
            utf8Bytes.push(charCode);  
        } else if (charCode < 2048) {  
            utf8Bytes.push((charCode >> 6) | 192);  
            utf8Bytes.push((charCode & 63) | 128);  
        } else {  
            utf8Bytes.push((charCode >> 12) | 224);  
            utf8Bytes.push(((charCode >> 6) & 63) | 128);  
            utf8Bytes.push((charCode & 63) | 128);  
        }  
    }  
  
    // 对字节数组进行Base64编码  
    const base64 = [];  
    let byteIndex = 0;  
    while (byteIndex < utf8Bytes.length) {  
        const byte1 = utf8Bytes[byteIndex++];  
        const byte2 = byteIndex < utf8Bytes.length ? utf8Bytes[byteIndex++] : 0;  
        const byte3 = byteIndex < utf8Bytes.length ? utf8Bytes[byteIndex++] : 0;  
  
        const triplet = (byte1 << 16) | (byte2 << 8) | byte3;  
  
        base64.push(chars[(triplet >>> 18) & 63]);  
        base64.push(chars[((triplet >>> 12) & 63)]);  
        if (byte2 !== 0) {  
            base64.push(chars[((triplet >>> 6) & 63)]);  
        }  
        if (byte3 !== 0) {  
            base64.push(chars[(triplet & 63)]);  
        }  
    }  
  
    // 处理剩余的字节,添加'='填充  
    while (base64.length % 4 !== 0) {  
        base64.push('=');  
    }  
  
    // 将字节数组转换为字符串  
    return base64.join('');  
}  
  
// 使用示例  
const text = 'Hello, World!';  
const encodedText = base64EncodeManual(text);  
console.log(encodedText); // 输出:SGVsbG8sIFdvcmxkIQ==

72、position 的值, relative 和 absolute 分别是相对于谁进行定位的?

  • absolute : 生成绝对定位的元素, 相对于最近一级的 定位不是 static 的父元素来进行定位。
  • fixed (老 IE 不支持)生成绝对定位的元素,通常相对于浏览器窗口或 frame 进行定位。
  • relative 生成相对定位的元素,相对于其在普通流中的位置进行定位。
  • static 默认值。没有定位,元素出现在正常的流中
  • sticky 生成粘性定位的元素,容器的位置根据正常文档流计算得出

73、对偏移、卷曲、可视的理解

  • 偏移(Offset): 指元素相对于某个参照物的位置。通常指元素相对于其父级元素或文档的位置

    offset包含widthpaddingborder

    • offsetWidth、offsetHeight、offsetLeft、offsetTop、offsetParent,注意:没有offsetRight和offsetBottom
  • 卷曲(Scroll): 指当页面内容超出可视区域时,通过滚动条进行上下左右滚动,以便查看被遮挡的部分内容。

    scroll包含widthpadding

    • scrollWidth、scrollHeight、scrollLeft、scrollTop
  • 可视(Visible): 指在当前浏览器窗口可见的部分。

    client包含widthpadding

    • clientWidth、clientHeight、clientLeft、clientTop

注意: 上面所说的只是基于标准盒模型情况,如果是怪异盒模型时,则需要去除padding的宽高。

html
<style>
  .father {
    width: 300px;
    height: 300px;
    padding: 20px;
    border: 2px solid #ddd;
    overflow: auto;
  }
  .child {
    width: 100px;
    height: 300px;
    background: red;
    padding: 10px;
    overflow: auto;
    border: 1px solid #ddd;
  }
</style>
<div class="father">
  <div class="child">
    <div style="height: 500px;background: #ccc;"></div>
  </div>
</div>
<script>
const box = document.querySelector('.father')
console.log('offset:', box.offsetHeight) // 344 = 300 + 20*2 + 2*2
console.log('client:', box.clientHeight) // 340 = 300 + 20*2
console.log('scroll:', box.scrollHeight) // 362 = 300 + 20*2 + 10*2 + 1*2

const child = document.querySelector('.child')
console.log('offset:', child.offsetHeight) // 322 = 300 + 20*2 + 1*2
console.log('client:', child.clientHeight) // 320 = 300 + 20*2
console.log('scroll:', child.scrollHeight) // 520 = 500 + 10*2
</script>

74、如果设计中使用了非标准的字体,你该如何去实现?

使用 @font-face 并为不同的 font-weight 定义 font-family

css
@font-face {
  font-family: 'CustomFont';
  src: url('path/to/custom-font.woff2') format('woff2'),
       url('path/to/custom-font.woff') format('woff');
}

h1 {
  font-family: 'CustomFont', sans-serif;
}

75、知道 css 有个 content 属性吗?有什么作用?有什么应用?

content属性用于在文档中插入生成的内容或样式化标记。该属性通常与:before:after伪元素一起使用,这两个伪元素可以添加在选定元素的前面和后面,并允许开发人员通过 CSS 将样式添加到这些虚拟的元素上。

content属性可以设置如下值:

  • 字符串:将一个字符串作为元素内容插入文档中,需要用双引号或单引号括起来。
  • URL:指向要插入的资源,例如图像。
  • 普通计数器:可以用于自动生成序列号。
  • 特殊字符:可以用于插入 Unicode 编码字符。

使用场景:

  1. :before伪元素插入文本
html
<style>
p:before {
  content: "注意:";
  font-weight: bold;
  color: red;
}
</style>
<p>哈哈哈哈</p>

202303241728367.png 2. attr()函数:用于将 HTML 元素的属性值映射到CSS属性的值上

html
<style>
  div:before {
    content: attr(data-tooltip);
  }
</style>
<div data-tooltip="这里是提示信息">Hover me</div>

202303241729533.png 3. counter(), counters()函数:用于生成自动编号的序列。

html
<style>
  body {
    counter-reset: section; /* 设置计数器初始值 */
  }

  h2:before {
    content: counter(section) ". "; /* 显示当前计数器的值 */
    counter-increment: section; /* 计数器自增1 */
  }
</style>
<body>
  <h2>第一章</h2>
  <h2>第二章</h2>
</body>

76、请阐述 float 定位的工作原理

浮动(float)是 CSS 定位属性。浮动元素从网页的正常流动中移出,但是保持了部分的流动性,会影响其他元素的定位(比如文字会围绕着浮动元素)。这一点与绝对定位不同,绝对定位的元素完全从文档流中脱离。

float定位的工作原理如下:

  1. 浮动元素会从正常的文档流中脱离出来,不再占据原先在文档流中所占的位置,而是被视为一层覆盖在文档流之上。
  2. 如果浮动元素前面有非浮动元素,那么浮动元素会尽可能地靠近前面的元素,直到不能再靠近为止。
  3. 如果浮动元素前面也是浮动元素,则会按照源代码中的顺序依次排序,尽量靠近前面的浮动元素。
  4. 在浮动元素后面的文本和行内元素会环绕在浮动元素周围,形成文字环绕效果。
  5. 父元素的高度会因为浮动元素的脱离而发生塌陷,需要使用清除浮动的方法来避免这种情况。

注意: 在使用float定位时,可能会出现浮动元素重叠、对齐问题等,需要通过设置clear和使用其他布局技巧进行解决。

77、请阐述 z-index 属性,并说明如何形成层叠上下文(stacking context)

z-index是CSS中的一个属性,用于控制元素在层叠上下文中的显示顺序。层叠上下文是一种概念,它定义了元素如何在三维空间中堆叠,并影响元素的可见性。

具体来说,当一个元素的z-index属性值为正数时,在同一个层叠上下文中,它会覆盖在z-index值较小的元素之上;如果z-index值相同,则后出现的元素会覆盖先出现的元素。当一个元素的z-index属性值为负数时,会将该元素放置到当前层叠上下文的下方。

层叠上下文的形成有以下几种方式:

  1. 根元素(标签)是最初的层叠上下文,所有其他元素默认位于这个上下文中。
  2. 每个定位元素(position属性值为absolute、relative、fixed)和flex项(display:flex或inline-flex)都会创建一个新的层叠上下文。
  3. z-index不为auto的元素创建层叠上下文。(注意:z-index属性只能应用于定位元素)
  4. 元素的opacity小于1时,会创建一个新的层叠上下文。

78、如何解决不同浏览器的样式兼容性问题?

  • 在确定问题原因和有问题的浏览器后,使用单独的样式表,仅供出现问题的浏览器加载。这种方法需要使用服务器端渲染。
  • 使用已经处理好此类问题的库,比如 Bootstrap。
  • 使用 autoprefixer 自动生成 CSS 属性前缀。
  • 使用 Reset CSS 或 Normalize. css。

79、如何为功能受限的浏览器提供页面? 使用什么样的技术和流程?

  • 优雅的降级:为现代浏览器构建应用,同时确保它在旧版浏览器中正常运行。
  • 渐进式增强:在旧的或较少功能的浏览器中提供基本的功能,为现代浏览器提供更高级的功能。
  • 特性检测:使用特性检测来检查浏览器是否支持所需功能。如果不支持,则提供另一种方法或替代方案。

    利用caniuse.com检查特性支持。

  • Polyfills或Shims: Polyfills或Shims可以补充浏览器缺失的API或功能,以确保网站在所有浏览器上都可以正常运行。
  • 使用autoprefixer自动生成 CSS 属性前缀。

80、除了 screen ,你还能说出一个 @media 属性的例子吗?

  • all:适用于所有设备。
  • print:用于打印机和打印预览。
  • screen:用于电脑屏幕,平板电脑,智能手机等。
  • speech:应用于屏幕阅读器等发声设备。

81、对于你使用过的 CSS 预处理,说说喜欢和不喜欢的地方?

优点

  • 在CSS的语法基础上增加了变量(variable)、嵌套(nested rules)、混合(mixins)、导入(inline imports)、继承(extend)等高级功能,这些拓展令CSS更加强大与优雅。
  • 让你的CSS更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处。
  • 提高开发效率

缺点

  • 需要多一个编译器来重新编译一次你的CSS代码,也就是给浏览器多了一道工序,网页显示的速度会减慢
  • 需要一个学习的过程,用之不当反而弄巧反拙

82、* { box-sizing: border-box; } 会产生怎样的效果?

浏览器默认值是box-sizing: content-box。 在如下所示css代码中,不同的box-sizing会导致元素实际宽高

css
.page {
  width: 200px;
  height: 200px;
  padding: 10px;
  border: 2px solid red;
}
  • box-sizing: content-box元素的宽高只会决定内容(content)的大小,如下所示: 元素实际宽度:width = content的宽 + 水平方向padding的宽度(左右) + 水平方向border的宽度(左右) = 200px + 10px * 2 + 2px * 2 = 224px
  • box-sizing: border-box改变计算元素widthheight的方式,borderpadding的大小也将计算在内,如下所示: 元素实际宽度:width = 200px

83、你使用过哪些现有的 CSS 框架?你是如何改进它们的?

  • Bootstrap:更新周期缓慢。Bootstrap 4 已经处于 alpha 版本将近两年了。添加了在页面中广泛使用的微调按钮组件。
  • Semantic UI:源代码结构使得自定义主题很难理解。非常规主题系统的使用体验很差。外部库的路径需要硬编码(hard code)配置。变量重新赋值没有 Bootstrap 设计得好。
  • Bulma:需要很多非语义的类和标记,显得很多余。不向后兼容,以至于升级版本后,会破坏应用的正常运行。
  • tailwind.css: 通过提供大量预定义的样式类来帮助开发人员快速构建网站和应用程序。

84、响应式设计与自适应设计有何不同?

响应式设计和自适应设计都旨在提供更好的用户体验,确保网站能够在不同设备和屏幕尺寸上正确显示。

  • 响应式设计: 是一种通过使用CSS媒体查询弹性布局等技术,使页面能够根据浏览器窗口大小和设备类型动态地调整布局和样式的设计方法。
  • 自适应设计: 是一种通过通过检测视口分辨率来判断当前访问的设备类型(如pc端、平板、手机),从而请求服务层返回不同的页面。

虽然这两种方法都旨在提供更好的用户体验,但响应式设计通常是更常见和更灵活的做法,因为它只需要维护一个代码库,并且可以适应新设备的出现。与此相比,自适应设计需要为每个设备类型维护单独的代码库,这可能会变得难以管理。

85、你有没有使用过视网膜分辨率的图形?当中使用什么技术?

视网膜分辨率的图形是指在视网膜屏幕上显示的图像,它们通常具有比普通屏幕更高的像素密度。由于物理尺寸和像素密度之间的关系,视网膜屏幕可以在相同的物理尺寸下显示更多的像素,从而提供更清晰、更锐利的图像。

我倾向于使用更高分辨率的图形(显示尺寸的两倍)来处理视网膜显示。更好的方法是使用媒体查询,像@media only screen and (min-device-pixel-ratio: 2) { ... },然后改变background-image

对于图标类的图形,我会尽可能使用svg图标字体,因为它们在任何分辨率下,都能被渲染得十分清晰。

还有一种方法是,在检查了window.devicePixelRatio的值后,利用 JavaScript 将<img>src属性修改,用更高分辨率的版本进行替换。

86、一边固定宽度一边宽度自适应

可以使用 flex 布局 复制下面的 HTML 和 CSS 代码 用浏览器打开可以看到效果

html
<div class="wrap">
    <div class="div1"></div>
    <div class="div2"></div>
</div>
css
html, body, div {
  height: 100%;
  margin: 0;
}
.wrap {
  display: flex;
  justify-content: space-between;
}

.div1 {
  min-width: 200px;
}
.div2 {
  width: 100%; /** 或者 flex: 1; */
  background: #e6e6e6;
}

87、为什么要初始化 CSS 样式

  • 初始化 CSS 样式是为了确保网页在不同浏览器和设备上呈现的效果一致,并且避免浏览器的默认样式对页面造成干扰。
  • 不同的浏览器对于相同的标签和属性可能会有不同的默认样式,这可能会导致网页在不同浏览器上呈现出不同的外观。另外,浏览器的默认样式也可能会影响网页的布局和性能。
  • 通过初始化 CSS 样式,可以清除掉浏览器的默认样式,从而避免以上问题的出现,同时也提供了更好的可定制性和维护性,使得网页开发更加方便和高效。

88、transform translate transition 的区别

  • translate:移动,transform的一个方法; 通过 translate() 方法,元素从其当前位置移动,根据给定的 left(x 坐标) 和 top(y 坐标) 位置参数,用法如下:
    css
    transform: translate(50px, 100px);
    -ms-transform: translate(50px,100px);
    -webkit-transform: translate(50px,100px);
    -o-transform: translate(50px,100px);
    -moz-transform: translate(50px,100px);
    
  • transform:变形,CSS3中主要包括
    • 旋转:rotate()顺时针旋转给定的角度,允许负值rotate(30deg)
    • 扭曲:skew()元素翻转给定的角度,根据给定的水平线(X 轴)和垂直线(Y 轴)参数:skew(30deg,20deg)
    • 缩放:scale()放大或缩小,根据给定的宽度(X 轴)和高度(Y 轴)参数:scale(2,4)
    • 移动:translate()平移,传进 x,y值,代表沿x轴和y轴平移的距离
    • 所有的2D转换方法组合在一起:matrix()旋转、缩放、移动以及倾斜元素matrix(scale.x ,, , scale.y , translate.x, translate.y)
    • 改变起点位置transform-origin: bottom left; 综合起来使用:transform: 30deg 1.5 30deg 20deg 100px 200px;
  • transition: 允许CSS属性值在一定的时间区间内平滑的过渡, 需要事件的触发,例如单击、获取焦点、失去焦点等transition:property duration timing-function delay;
    • property:CSS的属性,例如:width height 为none时停止所有的运动,可以为transform
    • duration:持续时间
    • timing-function:ease等
    • delay:延迟 例子:transition:width 2s ease 0s;
      注意:当property为all的时候所有动画。

89、全屏滚动的原理是什么?用到了 CSS 的那些属性?

全屏滚动的原理是通过 JavaScript 监听鼠标滚轮事件或者触摸事件,根据用户的操作来切换显示区域,从而实现页面的滚动效果。

一般来说,全屏滚动会将整个页面分为多个区块,每个区块占据一屏的高度,并且使用 CSS 的定位和过渡属性来实现页面滑动的效果。在切换不同的区块时,会通过 JavaScript 来修改 CSS 中的 transform 属性,从而改变页面的位置。

具体来说,在实现全屏滚动的过程中,通常会用到以下 CSS 属性:

  • position: absolute/fixed:用于控制页面元素的定位方式。
  • top/bottom/left/right:用于控制页面元素的位置。
  • width/height:用于控制页面元素的尺寸大小。
  • transform:用于控制页面元素的平移、旋转、缩放等变换效果。
  • transition:用于控制页面元素的过渡动画效果。

例子:

html
<style>
body, html {
  margin: 0;
  padding: 0;
  height: 100%;
}
.wrapper {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
.section {
  position: absolute;
  width: 100%;
  height: 100%;
  transition: transform 0.5s ease;
}
.section1 {
  background-color: red;
}
.section2 {
  background-color: green;
  top: 100%;
}
.section3 {
  background-color: blue;
  top: 200%;
}
</style>
<div class="wrapper">
  <div class="section section1"></div>
  <div class="section section2"></div>
  <div class="section section3"></div>
</div>
<script>
var sections = document.querySelectorAll(".section");
var currentSectionIndex = 0;

function scrollToSection(index) {
  if (index < 0 || index > sections.length - 1) {
    return;
  }
  var translateY = index * -100;
  for (var i = 0; i < sections.length; i++) {
    sections[i].style.transform = "translateY(" + translateY + "%)";
  }
  currentSectionIndex = index;
}
document.addEventListener("wheel", function(event) {
  event.preventDefault();
  var delta = event.deltaY;
  var direction = delta > 0 ? 1 : -1;
  scrollToSection(currentSectionIndex + direction);
});
document.addEventListener("touchstart", function(event) {
  touchStartY = event.touches[0].clientY;
});
document.addEventListener("touchmove", function(event) {
  event.preventDefault();
  var touchMoveY = event.touches[0].clientY;
  var delta = touchMoveY - touchStartY;
  var direction = delta > 0 ? -1 : 1;
  scrollToSection(currentSectionIndex + direction);
});
</script>

以上代码实现了一个简单的全屏滚动页面,当用户通过鼠标滚轮或者触摸屏幕时,会自动滑动到下一个或上一个区块,并且使用 CSS 的transform属性来实现平移效果。

90、什么是响应式设计?响应式设计的基本原理是什么?如何兼容低版本的IE?

  • 概念:响应式设计就是网站能够兼容多个终端,而不是为每个终端做一个特定的版本。
  • 基本原理:是利用CSS3媒体查询,为不同尺寸的设备适配不同样式。
  • 兼容:对于低版本的IE,可采用JS获取屏幕宽度,然后通过resize方法来实现兼容:
    js
    $(window).resize(function () {
      screenRespond();
    });
    screenRespond();
    
    function screenRespond(){
      var screenWidth = $(window).width();
      if(screenWidth <= 1800){
        $("body").attr("class", "w1800");
      }
      if(screenWidth <= 1400){
        $("body").attr("class", "w1400");
      }
      if(screenWidth > 1800){
        $("body").attr("class", "");
      }
    }
    

91、如何修改 chrome 记住密码后自动填充表单的黄色背景?

方法一:阴影覆盖:由于是设置颜色覆盖,所以只对非透明的纯色背景有效;

css
input:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 1000px white inset !important;
}

方法二:设置表单属性autocomplete="off/on"关闭自动填充表单,自己实现记住密码。如下:

html
<!-- 对整个表单设置 -->
<form autocomplete="off" method=".." action="..">
<!-- 或对单一元素设置 -->
<input type="text" name="textboxname" autocomplete="off">

92、用 css 分别实现某个 div 元素上下居中和左右居中

html
<style>
  * {
    padding: 0;
    margin: 0;
  }
  html, body {
    width: 100vw;
    height: 100vh;
  }
  .container {
    position: relative;
    width: 100%;
    height: 100%;
  }
</style>
<div class="container">
  <div class="box"></div>
</div>
  • 方式一:子元素定宽高,绝对定位4个方向值为0 + margin: auto
    css
    .box {
      width: 100px;
      height: 100px;
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      margin: auto;
      background: red;
    }
    
  • 方式二:子元素定宽高,绝对定位,上和 左偏50%,margin负宽度和负高度的一半
    css
    .box {
      width: 100px;
      height: 100px;
      position: absolute;
      top: 50%;
      left: 50%;
      margin-top: -50px;
      margin-left: -50px;
      background: red;
    }
    
  • 方式三:子元素定宽高、不定宽高有内容均可
    css
    .box {
      width: 100px;
      height: 100px;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background: red;
    }
    
  • 方式四:flex布局,父元素必须有宽高,子元素宽高没有限制
    css
    .container {
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .box {
      width: 100px;
      height: 100px;
      background: red;
    }
    
  • 方式五:grid布局,父元素必须有宽高,子元素宽高没有限制
    css
    .container {
      width: 100%;
      height: 100%;
      display: grid;
      justify-content: center;
      align-items: center;
    }
    .box {
      width: 100px;
      height: 100px;
      background: red;
    }
    
  • 方式六:table + vertical-align (主要针对多行文本垂直居中)
    css
    .container {
      display: table;
      width: 100%;
      height: 100%;
    }
    .box {
      display: table-cell;
      text-align: center;
      vertical-align: middle;
    }
    <div class="container">
      <div class="box">多行文本多行文本多行文本多行文本多行文本多行文本多行文本多行文本多行文本多行文</div>
    </div>
    

93、让页面里的字体变清晰,变细用 CSS 怎么做?

要让页面上的字体变得更清晰和更细,可以使用CSS的font-weightfont-smoothing属性来实现。例如:

css
/* 让字体变细 */
body {
  font-weight: 300;
}
/* 让字体更清晰 */
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
  • font-weight属性用于设置字体的粗细程度,值越大表示越粗,值越小表示越细。常见的取值包括100-900之间的整数值,以及“normal”(默认)、“bold”(加粗)等关键字。
  • font-smoothing属性则用于控制字体的平滑度,即是否启用反锯齿技术来使字体显示更加平滑。不同浏览器支持的取值可能有所差异,常见的取值包括“antialiased”(启用反锯齿,Webkit浏览器),“subpixel-antialiased”(启用亚像素级反锯齿,Webkit浏览器)、“grayscale”(启用灰阶反锯齿,Firefox浏览器)等。

94、font-style属性的Oblique和Italic的区别

font-style属性用于设置字体的风格,可以取值为normalitalicoblique

  • normal表示正常的字体风格,没有任何倾斜或扭曲。
  • italic表示斜体字(英文),通常是对原始字体进行倾斜变形以产生视觉上的斜体效果。Italic字体通常具有一些特殊设计,如较窄的字母间距和弯曲的字母形状等,以使其在斜体状态下更加易读。
  • oblique也是表示斜体字,但它是通过向右倾斜原始字体来实现,而非使用专门设计的斜体字体。因此,Oblique 字体通常与 Normal 字体相比略微变形,并且可能会导致一些字母看起来不太自然。

95、position:fixed; 在 android 下无效怎么处理?

在Android下,可能会遇到position: fixed无法生效的问题。这是因为某些Android浏览器(例如低版本的Android默认浏览器)对于fixed定位的支持存在一定的兼容性问题。

解决这个问题的方法之一是使用JavaScript实现fixed效果,具体步骤如下:

  1. 监听scroll事件,当页面滚动时执行相应的操作;
  2. 获取需要固定的元素和页面滚动的距离;
  3. 判断页面滚动的距离是否超过了需要固定的元素的位置,如果超过了,则将元素的position属性设为fixed,否则设置为static
  4. 设置元素的topleft值,使其固定在页面的指定位置。
html
<style>
#fixed-element {
  position: static; /* 初始状态 */
  width: 100%;
  height: 50px;
  background-color: #ccc;
}

.fixed {
  /* 加上 !important 的原因,在于id选择器的优先级高于类选择器*/
  position: sticky !important; /* 粘性定位 */
  top: 0;
  left: 0;
}
</style>
<div id="fixed-element">我是需要固定的元素</div>
<div style="height: 1000px;"></div>
<script>
// 获取需要固定的元素和页面滚动的距离
var fixedElement = document.getElementById("fixed-element");
// 监听scroll事件
window.addEventListener("scroll", function() {
  var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  // 判断页面滚动的距离是否超过了需要固定的元素的位置
  if (scrollTop > 50) { // 假设元素需要固定的位置距离页面顶部50px
    fixedElement.classList.add("fixed"); // 添加固定样式
  } else {
    fixedElement.classList.remove("fixed"); // 移除固定样式
  }
});
</script>

96、如果需要手动写动画,你认为最小时间间隔是多久,为什么?

16.7ms。多数显示器默认频率是60Hz,即1秒刷新60次,所以理论上最小间隔为1/60*1000ms = 16.7ms

97、overflow: scroll 时不能平滑滚动的问题怎么处理?

css
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;

98、如何美化 CheckBox

实现思路:

  1. 首先让原来的input不可见
  2. 利用label for设置替代input的样式
  3. 设置input:checked + label:before的样式
html
<input id="check1" type="checkbox"/>
<label  for="check1"></label>
css
/*lable标签的大小、位置、背景颜色更改,在css选择时,“+”代表相邻元素,即当前元素的下一元素*/
#check1 + label{
  width: 20px;
  height: 20px;
  cursor: pointer;
  position: absolute;
  border:1px solid grey;
}
/*当input框为选中状态时,lable标签的样式,其中在css选择时,“:”表示当前input框的值,即checked; \2714 代表对号*/
#check1:checked + label::before{ 
  display: block;
  content: "\2714";
  text-align: center;
  font-size: 16px;
  background: blue;
  color: white;
}
#check1{
  display:none;
}

99、float 和 display:inline-block 的区别是什么?

  • 对元素设置display:inline-block,元素不会脱离文本流
  • float就会使得元素脱离文本流,且还有父元素高度坍塌的效果。

100、rem 布局字体太大怎么处理?

getComputedStyle方法能够获取到计算后的样式、大小。

js
(function(doc, win) {

    var isAndroid = win.navigator.appVersion.match(/android/gi);
    var isIPhone = win.navigator.appVersion.match(/iphone/gi);

    var scale = 1.0;
    var ratio = 1;
    if (isIPhone) {
        if (window.devicePixelRatio == 2) {
            scale *= 0.5;
            ratio *= 2;
        }
        if (window.devicePixelRatio == 3) {
            scale *= (1 / 3);
            ratio *= 3;
        }
    }
    var text = '<meta name="viewport" content="initial-scale=' + scale + ', maximum-scale=' + scale + ',' + ' minimum-scale=' + scale + ', width=device-width,' + ' user-scalable=no" />';
    document.write(text);

    var docEl = doc.documentElement
    var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'
    var recalc = function() {
        var clientWidth = docEl.clientWidth
        if (!clientWidth) return
        docEl.style.fontSize = 100 * (clientWidth / 750) + 'px'

        // 解决部分rem特别大的问题
        var docElFontSize = docEl.style.fontSize.replace(/px/gi, '')
        var computedFontSize = win.getComputedStyle(docEl)['font-size'].replace(/px/gi, '')
        docElFontSize != computedFontSize && (docEl.style.fontSize = docElFontSize * docElFontSize / computedFontSize + 'px')
    }
    if (!doc.addEventListener) return
    recalc()
    win.addEventListener(resizeEvt, recalc, false)
})(document, window);

101、介绍css3中position:sticky

position:sticky是一个新的css3属性,它的表现类似position:relativeposition:fixed的合体,在目标区域在屏幕中可见时,它的行为就像position:relative; 而当页面滚动超出目标区域时,它的表现就像position:fixed,它会固定在目标位置。

102、使用css实现一个持续的动画效果

css
animation:mymove 5s infinite;
@keyframes mymove {
  from {
    top: 0px;
  }

  to {
    top: 200px;
  }
}

103、什么是包含块,对于包含块的理解?

包含块(containing block)是视觉格式化模型的一个重要概念,可以理解为一个矩形区域,为元素提供了一个参考系,元素的尺寸和位置的计算通常都基于这个包含块。包含块与框模型类似,但它更多的是用于定位和布局的计算。

包含块的主要特性和理解如下:

  • 根元素所在的包含块被称为初始包含块。在xhtml中,根元素通常是<html>。对于连续媒体设备,初始包含块的大小等于视口的大小。对于分页媒体,初始包含块是页面区域。
  • 对于其他元素,包含块的确定方式依赖于该元素的position属性:
    • 如果元素的position属性是static或relative,那么包含块由其最近的块级祖先元素的content box边界形成。
    • 如果元素的position属性是fixed,那么包含块由视口建立。
    • 如果元素的position属性是absolute,那么包含块由最近的position属性不为static的祖先元素建立。
  • 包含块可以看作是一个定位参考框或坐标系,元素一旦定义了定位显示(如相对、绝对、固定定位),都会以包含块为坐标系进行定位和调整。

104、CSS 里的 visibility 属性有个 collapse 属性值是干嘛用的?在不同浏览器下以后什么区别?

在 CSS 中,visibility属性用于控制一个元素是否可见。该属性有三个可能的值:visiblehiddencollapse

  • visibility: visible;是默认值,意味着元素是可见的。
  • visibility: hidden;会使元素不可见,但是该元素仍然会占据页面上的空间。换句话说,元素虽然不可见,但是它仍然会影响页面的布局。当这个值应用于表格行或列时,它不仅会使行或列不可见,而且会移除行或列占据的空间,就像 display: none; 一样。但如果 collapse 值应用于非表格元素,它的行为就像 hidden 一样,即元素不可见但仍占据空间。

关于不同浏览器下的区别:

  • 在谷歌浏览器(Chrome)中,collapse 值和 hidden 值的行为是一样的。即使应用于表格行或列,collapse 也不会移除行或列占据的空间。
  • 在火狐浏览器(Firefox)、Opera 和 IE11 中,collapse 值对于表格行或列的行为就像它的字面意思一样:行或列会完全消失,其下面的行或列会填补其位置。

105、width:auto 和 width:100%的区别

一般而言

  • width:100%会使元素box的宽度等于父元素的content box的宽度。
  • width:auto会使元素撑满整个父元素,marginborderpaddingcontent区域会自动分配水平空间。

106、使用 clear 属性清除浮动的原理?

clear属性用于控制元素是否允许其旁边有浮动元素。当为元素设置了clear属性后,该元素会调整其位置以确保其不会在浮动元素的旁边。

注意: clear属性只对块级元素有效。对于行内元素和替换元素,clear属性不会起作用。而且clear属性并不会影响元素的浮动状态,它只是调整元素的位置以避免与浮动元素重叠。

clear属性可以有以下四个值:

  • none:默认值,允许两边都有浮动元素。
  • left:不允许元素的左边有浮动元素。
  • right:不允许元素的右边有浮动元素。
  • both:不允许元素的左右两边有浮动元素。

当元素设置了clear属性后,浏览器会为该元素计算一个新的位置,以确保其不会在浮动元素的旁边。

具体来说就是浏览器会先找到最近的浮动元素(根据clear属性的值可能是左边、右边或两边的浮动元素),然后调整当前元素的位置,使其出现在该浮动元素的下方。

这种机制可以用于解决浮动布局带来的问题,比如父元素高度塌陷等。通过将子元素的clear属性设置为both,可以确保子元素不会出现在浮动元素的旁边,从而避免父元素高度塌陷的问题。

108、简单说一下 css3 的 all 属性。

all属性实际上是所有CSS属性的缩写,表示,所有的CSS属性都怎样怎样,但是,不包括unicode-bidi和direction这两个CSS属性。支持三个CSS通用属性值,initial,inherit,unset。

  • initial是初始值的意思,也就是该元素元素都除了unicode-bidi和direction以外的CSS属性都使用属性的默认初始 值。
  • inherit是继承的意思,也就是该元素除了unicode-bidi和direction以外的CSS属性都继承父元素的属性值。
  • unset是取消设置的意思,也就是当前元素浏览器或用户设置的CSS忽略,然后如果是具有继承特性的CSS,如color,则 使用继承值;如果是没有继承特性的CSS属性,如background-color,则使用初始值。

109、absolute 的 containingblock(包含块)计算方式跟正常流有什么不同?

  • (1)内联元素也可以作为“包含块”所在的元素;
  • (2)“包含块”所在的元素不是父块级元素,而是最近的position不为static的祖先元素或根元素;
  • (3)边界是padding box而不是content box。

111、视差滚动效果,如何给每页做不同的动画?(回到顶部,向下滑动要再次出现,和只出现一次分别怎么做?)

视差滚动(Parallax Scrolling)效果是一种在网页滚动时使背景图像或元素相对于前景内容移动较慢的效果。要实现这种效果,通常需要使用CSS的transform属性和scroll事件监听器。

要给每页(或每个特定的滚动区域)设置不同的视差滚动动画,你需要将每个区域的滚动动画效果单独定义,并使用JavaScript或jQuery来检测用户滚动的位置,然后应用相应的动画效果。

回到顶部,向下滑动要再次出现

这种效果通常可以通过监听滚动事件,结合CSS类来实现。当用户滚动到页面顶部时,移除动画效果;当用户向下滚动时,添加动画效果。

html
<div class="parallax-layer" id="layer1">  
  <!-- 背景图像或内容 -->  
</div>  
<div class="parallax-layer" id="layer2">  
  <!-- 另一层背景图像或内容 -->  
</div>  
<!-- ...更多层 -->  
<div id="content">  
  <!-- 页面内容 -->  
</div>
<style>
.parallax-layer {  
  position: fixed;  
  width: 100%;  
  height: 100%;  
  pointer-events: none;  
}  
  
#layer1 {  
  /* 第一层的动画效果 */  
  transform: translateY(0);  
  transition: transform 0.5s ease-in-out;  
}  
  
#layer2 {  
  /* 第二层的动画效果 */  
  transform: translateY(0);  
  transition: transform 0.7s ease-in-out;  
}  
  
/* ...更多层的样式 */  
  
#content {  
  /* 页面内容样式 */  
} 
</style>
<script>
window.addEventListener('scroll', function() {  
  var scrollTop = window.pageYOffset || document.documentElement.scrollTop;  
  
  if (scrollTop <= 0) {  
    // 用户滚动到页面顶部  
    document.getElementById('layer1').classList.remove('active');  
    document.getElementById('layer2').classList.remove('active');  
    // ...移除其他层的动画效果  
  } else {  
    // 用户向下滚动  
    document.getElementById('layer1').classList.add('active');  
    document.getElementById('layer2').classList.add('active');  
    // ...添加其他层的动画效果  
  }  
});
</script>

在上面的CSS中,.active类可以包含使背景图像或元素开始移动的CSS属性。你可以为每个.parallax-layer元素定义不同的.active类,以实现不同的动画效果。

只出现一次的动画效果

如果你希望动画效果只出现一次,而不是每次用户滚动时都出现,你可以使用一个标志变量来跟踪动画是否已经播放过。一旦动画播放过,就不再添加CSS类。

html
<div class="parallax-layer" id="layer1">  
  <!-- 背景图像或内容 -->  
</div>  
<div class="parallax-layer" id="layer2">  
  <!-- 另一层背景图像或内容 -->  
</div>  
<!-- ...更多层 -->  
<div id="content">  
  <!-- 页面内容 -->  
</div>
<style>
.parallax-layer {  
  position: fixed;  
  width: 100%;  
  height: 100%;  
  pointer-events: none;  
}  
  
#layer1 {  
  /* 第一层的动画效果 */  
  transform: translateY(0);  
  transition: transform 0.5s ease-in-out;  
}  
  
#layer2 {  
  /* 第二层的动画效果 */  
  transform: translateY(0);  
  transition: transform 0.7s ease-in-out;  
}  
  
/* ...更多层的样式 */  
  
#content {  
  /* 页面内容样式 */  
} 
</style>
<script>
var isAnimated = false; // 标志变量,用于跟踪动画是否已播放  
window.addEventListener('scroll', function() {  
  var scrollTop = window.pageYOffset || document.documentElement.scrollTop;  
  if (scrollTop > 0 && !isAnimated) {  
    // 用户向下滚动,且动画尚未播放  
    document.getElementById('layer1').classList.add('active');  
    document.getElementById('layer2').classList.add('active');  
    // ...添加其他层的动画效果  
    isAnimated = true; // 设置标志变量,表示动画已播放  
  }  
});
</script>

在这个示例中,isAnimated变量初始值为false,表示动画尚未播放。当用户向下滚动时,代码会检查这个变量,如果动画尚未播放,则添加CSS类以应用动画效果,并将isAnimated设置为true,表示动画已播放。这样,即使用户再次向下滚动,动画也不会再次播放。

112、layout viewport、visual viewport 和 ideal viewport 的区别?

  • Layout viewport(布局视口)是网页在移动设备上默认的视口大小,它通常等于设备的物理分辨率。在 Layout viewport 中,网页中的元素按照默认的布局和尺寸进行排列和显示。
  • Visual viewport(视觉视口)是用户实际看到的网页区域,也就是屏幕上实际可见的部分。Visual viewport 的大小可以根据用户缩放或旋转设备等操作而改变。
  • Ideal viewport(理想视口)是为了适应移动设备而提出的一个概念,它是指网页在移动设备上最佳的视口大小。Ideal viewport 能够确保在各种不同尺寸的移动设备上都能够以最佳的显示效果呈现。通常情况下,Ideal viewport 的大小会大于 Layout viewport 的大小,以便在 Visual viewport 中正确显示网页内容。

为了实现 Ideal viewport,可以使用meta标签来设置Viewport,例如:

html
<meta name="viewport" content="width=device-width, initial-scale=1">

这个 meta 标签将视口的宽度设置为设备的宽度,同时把初始缩放比例设置为 1,从而让 Ideal viewport 等于设备的宽度。

113、浏览器如何判断是否支持webp格式图片?

  • 宽高判断法

    通过创建image对象,将其src属性设置为webp格式的图片,然后在onload事件中获取图片的宽高,如果能够获取,则说明浏览器支持webp格式图片。如果不能获取或者触发了onerror函数,那么就说明浏览器不支持webp格式的图片。

    js
    const image = new Image()
    image.onload = () => {
      console.log(image.width, image.height)
    }
    image.onerror = () => {
      console.log('不支持')
    }
    image.src = './images/banner.webp'
    
  • canvas判断方法

    我们可以动态的创建一个canvas对象,通过canvas的toDataURL将设置为webp格式,然后判断返回值中是否含有image/webp字段,如果包含则说明支持WebP,反之则不支持。

    html
    <canvas width="200" height="200"></canvas>
    <script>
      const canvas = document.querySelector('canvas')
      const url = canvas.toDataURL('image/webp')
      console.log(url)
    </script>
    

114、什么是CSS后处理器?

CSS后处理器是对CSS进行处理,并最终生成CSS的预处理器,它属于广义上的CSS预处理器。我们很久以前就在用CSS后处理器了,最典型的例子是CSS压缩工具(如clean-css),只不过以前没单独拿出来说过。还有最近比较火的Autoprefixer,以CanIUse上的浏览器支持数据为基础,自动处理兼容性问题。

后处理器例如:PostCSS,通常被视为在完成的样式表中根据CSS规范处理CSS,让其更有效;目前最常做的是给CSS属性添加浏览器私有前缀,实现跨浏览器兼容性的问题。

115、使用rem布局的优缺点?

优点

  • 在屏幕分辨率千差万别的时代,只要将rem与屏幕分辨率关联起来就可以实现页面的整体缩放,使得在设备上的展现都统一起来了。
  • 而且现在浏览器基本都已经支持rem了,兼容性也非常的好。

缺点

  • 在奇葩的dpr设备上表现效果不太好,比如一些华为的高端机型用rem布局会出现错乱。
  • 使用iframe引用也会出现问题。
  • rem在多屏幕尺寸适配上与当前两大平台的设计哲学不一致。即大屏的出现到底是为了看得又大又清楚,还是为了看的更多的问题。

116、什么是首选最小宽度?

“首选最小宽度”指的是元素最适合的最小宽度。在CSS中,这个宽度主要涉及到文字和图片元素的显示。

  • 对于东亚文字(如中文),每个汉字的宽度通常被视为最小宽度。而对于西方文字,其最小宽度则是由特定的连续的英文字符单元决定的。需要注意的是,并不是所有的英文字符都会组成连续单元,一般会终止于空格(普通空格)、短横线、问号以及其他非英文字符等。
  • 在CSS布局中,当元素的宽度被设置为0时,其实际表现出来的宽度就是“首选最小宽度”。此外,对于图片和文字的权重远大于布局,因此在处理这些因素时,“首选最小宽度”的概念尤为重要。
  • 如果开发者希望让英文字符和中文一样,每一个字符都用最小宽度单元来显示,可以尝试使用CSS中的word-break: break-all属性。

利用首选最小宽度这个表现形式,实现一个“凸”字

  • 原理:外部容器宽度设置为 0,显示为块级-行内元素,通过 :before 添加文字,设置轮廓,文字颜色设置为白色。
    html
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title></title>
        <style>
          .ao{
            display: inline-block;
            width: 0;
          }
          .ao:before{
            outline: 2px solid red;
            content: '我aaaa你';
            color: #fff;
          }
        </style>
      </head>
      <body>
        <div class="ao"></div>
      </body>
    </html>
    
    效果如图所示: 2023021410320010.png

117、为什么height:100%会无效?

height: 100%在CSS中可能会无效,这通常是因为百分比高度值是根据其父元素的高度来计算的。以下是可能导致height: 100%无效的一些原因:

  • 父元素没有指定高度:如果父元素没有指定具体的高度(或者高度设置为auto),子元素的height: 100%将无法确定其高度值,因为父元素没有具体的高度可以继承。
  • 父元素的高度为百分比值:如果父元素的高度也是以百分比值来设置的,那么它的实际高度将取决于其祖先元素的高度。如果没有任何祖先元素设置高度或设置的高度为auto,那么height: 100%仍然无法确定正确的高度。
  • 绝对定位的元素:绝对定位的元素(position: absolute)不受其父元素高度的影响,因此height: 100%在这种情况下可能不会按照预期工作。
  • 文档流和浮动元素:在普通文档流中,如果父元素包含浮动元素,并且没有清除浮动(例如使用clear属性),那么父元素的高度可能不会被正确地计算,从而导致height: 100%无效。
  • Flexbox和Grid布局:在Flexbox或Grid布局中,height: 100%的行为可能与常规文档流不同。你可能需要调整布局属性来确保元素高度按照预期工作。

118、min-width/max-width 和 min-height/max-height 属性间的覆盖规则?

  • 如果一个元素同时指定了 min-width 和 max-width 属性(或者 min-height 和 max-height 属性),那么它们之间的关系由更限制元素的属性来确定。
  • 如果一个元素只指定了其中一个属性,那么另一个属性将默认为 none。
  • 如果一个元素同时包含多个约束条件,并且这些条件具有相同的级别,那么按照以下顺序解决冲突:max-width、min-width、max-height、min-height。也就是说,如果 max-width 和 min-width 之间存在冲突,那么 max-width 将优先于 min-width 生效;如果 max-height 和 min-height 之间存在冲突,那么 max-height 将优先于 min-height 生效。

119、内联盒模型基本概念

内联盒模型是一个内联盒子的集合,其中包括很多更为抽象的盒子,如内容区域、内联盒子、行框盒子和包含块。

  • 内容区域(content area):这是一种围绕文字看不见的盒子,其大小仅受字符本身特性控制,本质上是一个字符盒子(character box)。然而,对于某些元素,如图片这样的替换元素,其内容显然不是文字,不存在字符盒子之类的,因此对于这些元素,内容区域可以看成元素自身。
  • 内联盒子(inline box):这种盒子不会让内容成块显示,而是排成一行。这里的“内联盒子”实际指的就是元素的“外在盒子”,用来决定元素是内联还是块级。该盒子又可以细分为“内联盒子”和“匿名内联盒子”两类。具有display:inline属性的盒子称为内联盒子,而具有display:inline-block等属性的盒子称为内联级盒子。两者的区别就是能否在同一个行内显示:内联盒子能够被拆分成多行,而内联级盒子不能拆分成多行。
  • 行框盒子(line box):每一行就是一个“行框盒子”,每个“行框盒子”又是由一个一个“内联盒子”组成的。黄色框所在区域就是行框盒子,可以视为由一个个内联盒子组成。
  • 包含块(containing box):由一行一行的“行框盒子”组成。图片所示整个p标签范围就是一个包含块,由行框盒子组成。

120、什么是幽灵空白节点?

幽灵空白节点(Ghost Empty Element)指的是在HTML5文档声明中,内联元素的所有解析和渲染表现就如同每个行框盒子的前面有一个“空白节点”一样。这个“空白节点”是透明的,不占据任何宽度,看不见也无法通过脚本获取,就像幽灵一样,但它确实存在,表现如同文本节点一样。

它在HTML5规范中被称为“void元素”,包括常见的标记如<br>、<img>和<input>等。这些元素是用来插入特定类型的内容而不需要任何文本或元素包裹的情况下使用的。例如<br>用于在段落中创建换行符。

121、什么是替换元素?

在HTML中,替换元素指的是一些元素的内容可以被其他内容替换的元素。

常见的替换元素包括img、input、textarea、select、video、audio、iframe、canvas和object等。这些元素都有一个占位符,用来显示元素在文档流中的位置,并且元素本身的内容会被浏览器根据元素的属性值进行替换。这些元素有一个共同的特点,就是它们的显示内容并非由HTML标签中的内容直接决定,而是由元素的“src”或“value”等属性决定。

替换元素除了内容可替换这一特性以外,还有一些其他的特性。例如,替换元素都是内联水平元素,也就是说,替换元素和替换元素、替换元素和文字都可以在一行显示。而且替换元素的尺寸由元素的属性决定,而不是由CSS的widthheight属性决定。

122、替换元素的计算规则?

替换元素主要有三种尺寸:固有尺寸、HTML尺寸和CSS尺寸。

  • 固有尺寸:这是替换内容原本的尺寸,例如图片或视频文件本身的宽度和高度。
  • HTML尺寸:这是通过HTML元素的属性(如<img>的width和height属性,或<input>的size属性)设置的尺寸。
  • CSS尺寸:这是通过CSS的width和height属性,或max-width/min-width和max-height/min-height设置的尺寸,它对应盒模型中的content box。

替换元素的尺寸计算规则如下:

  • 如果没有设置CSS尺寸和HTML尺寸,那么将使用固有尺寸作为最终的宽高。
  • 如果没有设置CSS尺寸,那么将使用HTML尺寸作为最终的宽高。
  • 如果设置了CSS尺寸,那么最终尺寸将由CSS属性决定。需要注意的是,如果CSS尺寸只设置了宽度或高度其中一个,那么另一个尺寸将按照固有尺寸的比例进行计算。

如果替换元素是内联元素,那么其宽度和高度将只受CSS尺寸的影响,HTML尺寸将无效。同时替换元素在文档流中的尺寸由其自身的尺寸决定,而不受父元素或其他元素的影响。

123、content与替换元素的关系?

content属性生成的对象称为“匿名替换元素”。

  • (1)我们使用content生成的文本是无法选中、无法复制的,好像设置了user-select:none声明一般,但是普通元素的文本却可以被轻松选中。同时,content生成的文本无法被屏幕阅读设备读取,也无法被搜索引擎抓取,因此千万不要自以为是地把重要的文本信息使用content属性生成,因为这对可访问性和SEO都很不友好。
  • (2)content生成的内容不能左右:empty伪类。
  • (3)content动态生成值无法获取。

124、margin:auto的填充规则?

margin的'auto'可不是摆设,是具有强烈的计算意味的关键字,用来计算元素对应方向应该获得的剩余间距大小。但是触发margin:auto计算有一个前提条件,就是width或height为auto时,元素是具有对应方向的自动填充特性的。

  • (1)如果一侧定值,一侧auto,则auto为剩余空间大小。
  • (2)如果两侧均是auto,则平分剩余空间。

125、margin无效的情形

  • (1)display计算值inline的非替换元素的垂直margin是无效的。对于内联替换元素,垂直margin有效,并且没有margin合并的问题。
  • (2)表格中的<tr><td>元素或者设置display计算值是table-cell或table-row的元素的margin都是无效的。
  • (3)绝对定位元素非定位方位的margin值“无效”。
  • (4)定高容器的子元素的margin-bottom或者宽度定死的子元素的margin-right的定位“失效”。

126、什么是基线和x-height?

基线通常是字母的底部,大多数字符(如“g”或“p”)都会延伸到基线以下。基线对于确定文本行的高度以及行距(line spacing)的计算至关重要。

x-height,又称小写x高度,指的是小写字母x的高度,即基线和等分线(mean line,也称作中线,midline)之间的距离。选择小写“x”是因为它通常是所有其他小写字母高度的准确表示。在CSS中,ex是一个相对单位,它指的就是x-height。ex的价值在于其不受字体和字号影响的内联元素的垂直居中对齐效果。

127、overflow 的特殊性?

  • (1)一个设置了overflow:hidden声明的元素,假设同时存在border属性和padding属性,则当子元素内容超出容器宽度高度限制的时候,剪裁的边界是border box的内边缘,而非padding box的内边缘。
  • (2)HTML中有两个标签是默认可以产生滚动条的,一个是根元素<html>,另一个是文本域<textarea>
  • (3)滚动条会占用容器的可用宽度或高度。
  • (4)元素设置了overflow:hidden声明,里面内容高度溢出的时候,滚动依然存在,仅仅滚动条不存在!

131、clip裁剪是什么?

CSSclip是一种用于裁剪元素的属性,它可以将一个元素裁剪成一个矩形区域,并只显示该区域内的内容,超出区域的部分则被隐藏掉。

clip属性

clip属性需要指定一个裁剪区域,以左上角和右下角的坐标值表示,具体语法如下:

css
clip: rect(top, right, bottom, left);
clip: rect(30px 120px 80px 20px);

其中top、right、bottom、left四个值分别表示裁剪区域上边界、右边界、下边界和左边界的位置,可以使用像素、百分比等单位来指定。

注意: clip属性已经在 CSS3 中被废弃了,推荐使用更加灵活的clip-path属性进行裁剪。

clip-path属性

clip-path属性是一种用于裁剪元素的属性,它可以指定一个SVG路径或基本形状来定义一个裁剪区域,以将元素的可见部分限制在该区域内。相比于已经被废弃的clip属性,clip-path更加灵活和强大。

css
clip-path: url | basic-shape | geometry-box | none;

取值可以为以下三种类型之一:

  • <url>:指定 SVG 文件中定义的路径元素(例如<path>、<circle>等);
  • <basic-shape>:指定基本几何形状,包括inset()、circle()、ellipse()、polygon()等;
  • <geometry-box>:指定参考的盒模型,包括padding-box、border-box、content-box等。 例如,要将一个元素裁剪成一个四边形,可以这样设置clip-path属性:
css
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);

这会将元素裁剪成一个居中的菱形区域。

Released under the MIT License.