CSS面试题

1,527 阅读42分钟

CSS

1.CSS有哪些基本选择器?它们的权重是如何表示的?

内联样式(行内的style属性)ID选择器类名选择器/属性选择器/伪类选择器标签名选择器/伪元素选择器
1000010000100001

元素样式渲染时,权重高的选择器样式会覆盖权重低的选择器样式。

!important 关键字优先级最高

注意: !important 并非选择器,而是针对选择器内的单一样式设置的。当然,不同选择器内应用

!important的权重也是不一样的。(权重越高的选择器 !important关键字权重越高 )

2.CSS的引入方式有哪些? link@import 的区别是什么?

css有三种引入方式:

  • 行内式指将样式写在元素的 style 属性内
  • 内嵌式是指将样式写在style元素内
  • 外链式是指通过 link(@import)标签,引入css文件内的样式

通过 link标签引入样式与通过 @import方法引入样式有如下区别

  • 加载资源的限制

link是XHTML标签,除了加载CSS文件外,还可以加载RSS等其他事物,如加载模板等。

@import只能加载CSS样式

  • 加载方式

如果用 link引用CSS,在页面载入时同时加载,即同步加载

如果用 @import引用CSS,则需要等到网页完全载入后,再加载CSS文件,即异步加载

  • 兼容性

link是XHTML的标签,没有兼容问题

@import是在CSS2.1中提出的,不支持低版本的浏览器

  • 改变样式

link的标签是DOM元素,支持使用 JavaScript控制DOM和修改样式

@import是一种方法,不支持控制DOM和修改样式

3.浮动元素引起的问题和解决办法是什么?

引起的问题:

  1. 父元素的高度无法被撑开,影响与父元素同级的元素
  2. 与元素同级的非浮动元素会紧随其后(类似遮盖现象)
  3. 如果一个元素浮动,则该元素之前的元素也需要浮动;否则,会影响页面显示的结构(即通常所说的串行现象)。

解决办法:

  1. 为父元素设置固定的高度
  2. 为父元素声明一个BFC,BFC计算高度的时候会计算内部浮动元素的高度
  3. 内墙法是指在父元素内部,浮动元素的最后面,添加“一道墙”设置属性 clear:both
  4. 伪元素是指为了少创建元素,对父元素添加 after伪元素,设置属性 content:“”;display:block;clear:both
    .clearfix:after{
        content:'';
        display:block;
        clear:both;
    }
    

4. position的值分别是相对于哪个位置定位的?

  • relative :表示相对定位,相对于自己本身所在正常文档流中的位置进行定位
  • absolute :表示绝对定位,相对于最近一级(从直接父级元素往上数,直到根元素)定位,相对于非 static的父元素进行定位
  • fixed :用于生成绝对定位,相对于浏览器窗口或frame进行定位
  • static: 是默认值,没有定位,元素出现在正常的文档流中
  • sticky :是生成粘性定位的元素,容器的位置根据正常文档流计算得出

5.请说明 position:absolutefloat属性的异同

共同点:对内联元素设置 floatabsolute属性,可以让元素脱离文档流,并且可以设置其宽高。

不同点: float仍可占据位置,不会覆盖在另一个BFC区域上,浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。 absolute会覆盖围挡流中的其他元素,即遮盖现象。

6.CSS选择器(符)有哪些?

  1. id选择器 #myID
  2. 类选择器 .myClassName
  3. 标签选择器 div,p,h1
  4. 相邻选择器 h1+p
  5. 子选择器 ul>li
  6. 后代选择器 li a
  7. 通配符选择器 *
  8. 属性选择器 button[disabled=''true]
  9. 伪类选择器 a:hover 、li:nth-child 表示一种状态
  10. 伪元素选择器 li:before 、:after 表示文档某个部分的表现

注意: 在CSS3 规范中,为了区别伪元素和伪类,CSS3建议伪类用单冒号 “:”,伪元素用双冒号 “::”

7.CSS有哪些样式可以继承?哪些不可以继承?

可继承:

  • 跟文本相关的属性:

    color、font、font-family、font-size、 font-weight、font-variant、font-style、line-height、letter-spacing、text-align、 text-indent、text-transform、white-space 以及 word-spacing。

  • 列表属性:

    list-style、list-style-type、 list-style-position 以及 list-style-image

  • 表格的边框属性 border-collapse 和 border-spacing

不可继承: borderpaddingmarginwidthheight等尺寸属性

元素显示隐藏属性:visibility可以继承,diaplay:none不可以继承。

注意:与字体相关的样式通常可以继承,与尺寸相关的样式通常不能继承

8.HTML是什么?CSS是什么?JavaScript是什么?

  1. HTML:(HyperText Markup Language,超文本标记语言)是做网站时使用的一些文本标记标签,比如 div ,span
  2. CSS:(Cascading Style Sheet ,层叠样式表)是做网站时为美化网站而为标签添加的样式,比如 background(北京)color(字体颜色)
  3. JavaScript:是网站中实现前后台交互效果、网页动画效果的一种开发语言。比如鼠标单击( click )事件、前后台数据请求( Ajax )等

9.为什么初始化CSS?

因为浏览器的兼容问题,不同浏览器对有些标签的默认值时不同的,如果没有初始化CSS,往往会导致页面在不同浏览器之间出现差异。

当然初始化样式有时会对SEO产生一定的影响。但是相比较起来,初始化相对重要,则我们应该在力求影响最小的情况下完成CSS初始化。

10.display有哪些值?说明它们的作用?

block: 块状类型。默认宽度为父元素宽度,可设置宽高,换行显示。

none:元素不会显示,已脱离文档流。

inline:行内元素类型。默认宽度为内容宽度,宽高和纵向的外边距不生效,纵向内边距不会撑起父元素高度(可能会产生覆盖的问题),同行显示。

inline-block:指默认宽度为内容宽度,可以设置宽高,同行显示。

list-item:指像块元素一样显示,并添加样式列表标记。

table:指此元素会作为块级表格显示。

inherit:指从父元素继承 display属性的值。

11.简述块级元素和行内元素的区别

  • 块级元素:独占一行,宽高可以设置,内外边距可以设置

  • 行内元素:同行显示,宽高和纵向的外边距不生效,纵向内边距不会撑起父元素高度(可能会产生覆盖的问题)

  • 行内块级元素:比如 <image><input>元素等。同行显示,宽高可以设置,内外边距可以设置。

12.解释浮动及其工作原理

浮动元素可以向左或向右移动,直到它的外边缘碰到包含元素(父元素)或另一个浮动元素的边框为止。

虽然浮动元素已不在文档流中,但是它浮动后所处的位置依然在浮动之前的水平方向上。因为浮动元素不在文档流中,所以文档流中的块元素表现的就像浮动元素不存在一样,下面的元素会填补原来的位置。有些元素会在浮动元素的下面,但是这些元素的内容并不一定会被浮动的元素遮盖。当定位内联元素时,需考虑浮动元素的边界,围绕浮动元素防止内联元素。也可以把内联元素想象成块元素忽略的元素,而内联元素会关注的元素。

什么是浮动?

通过让元素浮动,我们可以使元素在水平上左右移动,在通过 margin属性调整位置

浮动的原理?

使当前元素脱离普通流,相当于浮动起来一样,浮动的框可以左右移动,直至它的外边缘遇到包含框或者另一个浮动框的边缘。

13.解释一下CSS Sprite,以及如何在页面或网站中使用

CSS Sprite 其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的 background-imagebackground-repeatbackground-position的组合进行背景定位, background-position可以用数字精确的定位出背景图片的位置。

优点:当页面加载时,不是加载每一个单独的图片,而是一次加载整个组合图片。它大大减少了HTTP请求的次数,减轻服务器压力,同时缩短了悬停加载图片所需要的时间延迟,使效果更流畅,不会停顿。

缺点:做图像拼合的时候很麻烦,而且不容易维护,后续添加图片时需要修改定位

14.在书写高效CSS时有哪些问题需要考虑?

  • 样式,从右向左解析一个选择器
  • 类型选择器的速度,ID选择器最快,(*)通配符最慢。对于常用的四种类型选择器,解析速度由快到慢一次是 IDclasstaguniversal通配符
  • 不要用标签限制ID选择器(如 ul#main-navigation{},ID已经是唯一了,不需要tag来限制,这样做会让选择器变慢 )
  • 后代选择器最糟糕(换句话说,html body ul li a {}这个选择器是很低效的)
  • 想清楚你的需求,再去书写 选择器
  • CSS选择器(如u nth-child )能够漂亮的定位我们想要的元素,又能保证CSS整洁易读。然而,这些神奇的选择器会浪费很多的浏览器资源
  • 我们知道ID选择器的速度最快,但是如果都用ID选择器,会降低代码的可读性和可维护性等。在大型项目中,相对于使用ID选择器提升速度,代码的可读性和可维护性带来的收益更大。

15.页面重构怎样操作?

页面重构:根据原有页面内容和结构的基础上,通过 div+css写出符合web标准的页面结构,让页面结构更加合理化,提升用户体验,达到良好的页面效果并提升性能。

具体实现要达到以下三点:

  1. 功能符合用户体验,用户交互结构完整,可通过标准验证
  2. 代码重构:代码质量、SEO优化、页面性能、更好的语义化、浏览器兼容、CSS优化
  3. 充分考虑到页面在站点中的“作用和重要性”,并对其进行有针对性的优化

16.内联元素可以实现浮动吗?

在CSS中,任何元素都可以实现浮动。不论浮动元素本身是何种元素,都会生成一个块级框。因此,对于内联元素,如果设置为浮动,会产生和块级框相同的效果。

17.简要描述CSS中content属性的作用

content属性与 :before:after伪元素配合使用,用来插入生成的内容,可以在元素之前或之后放置生成的内容。可以插入文本、图像、引号,并可以结合计数器,为页面元素插入编号。

18.如何定义高度很小的容器?

因为有一个默认的行高,所以在IE6下无法定义小高度的容器

两种解决方案分别是 overflow:hiddenfont-size:容器高度px

20.如何让超出宽度的单行文字显示为省略号?

{
    overflow:hidden;
    width:30px;
    white-space:nowrap;
    text-overflow:ellipsis;
}

21.多行文字超出部分显示省略号

        .morelineEllipsis {
            overflow: hidden;
            width: 100px;
            text-overflow: ellipsis;

             display: -webkit-box;/*容器元素的显示方式设置为弹性盒子*/
            -webkit-line-clamp: 3; /* 指定行数,根据需求调整 */
            -webkit-box-orient: vertical;/*设置弹性盒子的排列方式为垂直方向*/

        }

22.如何让英文单词发生词内断行?

输入 word-warp:break-word或者word-break: break-all

word-break指定了怎样在单词内断行,其MDN:

image.png

word-warp由于和word-break长得太像,难免会让人记不住搞混淆,晕头转向,于是在CSS3规范里,把这个属性的名称给改了,叫做:overflow-wrap。这个新属性名称显然语义更准确,也更容易区别和记忆。

但是呢,也就Chrome/Safari等WebKit/Blink浏览器支持。

所以,为了兼容使用,目前,还是乖乖使用word-wrap吧。

image.png

image.png

23.什么叫优雅降级和渐进增强?两者有什么区别?

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

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

两者的区别如下:

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

在现实工作中我们应该根据用户中浏览器占比进行选择:高版本的浏览器占比高就选择优雅降级,低版本浏览器占比高就选择渐进增强。

但实际上大部分的工作都是渐进增强的,先有一套基本的东西上线,后边再追加功能。

24.网页制作会用到哪些图片格式?

在网页制作中,常见的图片格式有多种,每种格式都有自己的优势和用途。以下是几种常见的图片格式及其特点:

  1. JPEG (Joint Photographic Experts Group):

    • 优势: 适用于照片和图像中颜色丰富、渐变过渡的场景。通常具有较小的文件大小。
    • 不适用: 不适合包含透明区域的图像,因为JPEG不支持透明度
  2. PNG (Portable Network Graphics):

    • 优势: 支持透明度(alpha通道),适合图像需要有透明背景的情况。也适用于图像中包含文本或细节较多的情况。
    • 不适用: 对于照片等颜色丰富、渐变过渡的图像,文件大小可能较大
  3. GIF (Graphics Interchange Format):

    • 优势: 支持动画效果和简单的透明度。适用于简单的图标、动画、简单图形等。
    • 不适用: 对于颜色丰富、细节复杂的图像,文件大小可能较大,不如JPEG或PNG效果好。
  4. SVG (Scalable Vector Graphics):

    • 优势: 基于矢量图形,支持无损缩放,适用于图标、简单的图形和动画。由于是矢量图,文件通常较小。
    • 不适用: 对于包含大量颜色和复杂细节的图像,可能不如位图格式效果好。
  5. WebP:

    • 优势: 由Google开发,支持有损和无损压缩,通常具有更小的文件大小和更高的图像质量。支持透明度和动画。
    • 不适用: 目前主要在Chrome和部分其他浏览器中支持,兼容性相对较差。

在实际应用中,根据图片的内容和需求选择合适的格式是重要的。通常,JPEG适用于照片,PNG适用于需要透明度的图像,GIF适用于简单动画,SVG适用于矢量图形,而WebP可以作为一种新兴格式在支持的浏览器中提供更高效的压缩和质量。

25.对行内元素设置 margin-topmargin-bottom是否起作用?

不起作用。

需要注意行内元素的替换元素(也就是行内块元素) imginput,它们是行内块元素,可以设置它们的宽度和高度,并且 margin属性也对它们起作用。

26.div+css的布局较 table布局有什么优势?

使用 div+CSS 进行布局相对于使用 table 有一些明显的优势,主要体现在以下几个方面:

  1. 语义化: div+CSS 布局更符合语义化的 HTML 结构,而 table 元素则是为表格而设计的,使用它来进行布局不符合 HTML 的语义化。

  2. 可维护性: 结构和表现分离

  3. 性能优势: div+CSS 布局通常比 table 布局具有更好的性能。table 的渲染机制涉及到更多的计算,对于大型页面可能影响性能。而使用 div+CSS 布局能够更轻量、更高效地渲染页面。

  4. 响应式设计: div+CSS 布局更适合响应式设计。通过使用媒体查询、弹性盒子(Flexbox)和网格布局(Grid Layout),可以更容易地实现页面在不同屏幕尺寸和设备上的适应性布局,而 table 布局相对较难实现这种响应性。

  5. 可访问性: div+CSS 布局有助于提高页面的可访问性。使用语义化的 HTML 结构以及正确的标签和角色可以让屏幕阅读器等辅助技术更好地理解和解释页面内容,提高用户体验。

  6. 模块化: div+CSS 布局更符合模块化开发的思想。每个 div 可以视为一个模块,更容易独立开发、测试和维护。而 table 布局可能导致页面结构的紧密耦合,不利于模块化的实现。

总体而言,在现代 Web 开发中,推荐使用 div+CSS 进行布局,特别是结合弹性盒子和网格布局等新的布局技术,以实现更灵活、语义化、易维护和性能优越的页面布局。

27.谈谈你对BFC规范的理解

BFC(Block Formatting Context)指块级格式化上下文,即一个创建了新的BFC的盒子是独立布局的,盒子里面的子元素的样式不会影响到外面的元素。在同一个BFC中,两个毗邻的块级盒在垂直方向上(和布局方向有关系)的 margin会发生重叠

  • BFC是页面上的独立容器,内外元素互不影响
  • BFC内部box在竖直方向上一个个排列
  • box的纵向距离由margin决定,同一个BFC相邻的box外边距重叠
  • BFC不与float box重叠
  • BFC计算高度,浮动元素也参与计算

如何创建一个BFC:

image.png

BFC的作用:

  • 避免margin重叠:同一个BFC下相邻的box外边距会产生重叠,若想避免,可以让每个box单独生成一个BFC
  • 清除浮动:由于BFC计算高度的时候会计算浮动元素的高度,所以可以通过为父元素添加overflow:hidden生成BFC,避免浮动元素父元素的高度无法撑起的问题
  • 自适应两栏布局:因为BFC不与float box重叠,所以可以通过设置左栏float:left,设置右栏overflow:hidden完成两栏布局

28.谈谈你对IFC规范的理解

IFC(Inline Formitting Context)指内联格式化上下文。IFC的线框(Line box)高度由其包含行内元素中最高的实际高度计算而来(不受竖直方向的 padding/margin的影响)。IFC中的线框一般左右都贴近整个IFC,但是会被 float元素扰乱。同一个IFC下的多个线框高度不同。IFC中是不可能有块级元素的,当插入块级元素时(如在 p中插入 div ),会产生两个匿名矿,两者与 div分隔开,即产生两个IFC,每个IFC对外表现为块级元素,与 div垂直排列。

29.谈谈你对GFC规范的理解

GFC(GridLayout Formatting Style)指网格布局格式化上下文,即当把一个元素的 display值设为 grid的时候,此元素将会获得一个独立的渲染区域。可以通过在网格容器(grid container)上定义网格定义行和网格定义列,再往个项目上定义网格行和网格列来为每一个网格项目定义位置和空间

30.谈谈你对FFC规范的理解

FFC(Flex Formatting Style)指自适应格式化上下文,即 display值为 flexinline-flex的元素将会生成自适应容器。伸缩容器中的每一个子元素都是一个伸缩单元。伸缩单元可以是任意数量的。伸缩单元内和伸缩单元外的一切元素都不受影响。简单地说, Flexbox定义了伸缩容器内伸缩单元的布局

31.访问超链接后 hover样式就不出现的原因是什么?应该如何解决?

因为访问过的超链接样式覆盖了原有的 hoveractive伪类选择器样式,解决办法是将CSS属性的排列顺序改为:L->V->H->A(link,visited,hover,active)

32.什么是外边距重叠?重叠的结果是什么?

在CSS中,垂直方向上相邻的块级元素(可能是兄弟关系也可能是祖先关系)外边距发生重叠。左右不存在重叠现象。

有些情况不会产生外边距折叠:

  • 有设定浮动绝对定位的元素不会发生外边距折叠。

  • display 设置为 flex 或 grid 的容器中不会发生外边距折叠。

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

  • 当两个相邻的外边距都是正数时,折叠的结果是它们两者中较大的值
  • 如果所有的外边距都为负值,折叠后的外边距的值为最小(绝对值最大)的负边距的值。
  • 如果包含负边距,折叠后的外边距的值为最大的正边距与最小(绝对值最大)的负边距的和。

可以通过声明BFC阻止外边距重叠。

33. rgba()opacity的透明度有什么不同?

两者都能实现透明效果。

opacity作用于元素,并且可以设置元素内所有内容的透明度(opacity也不具有继承性)。

opacity 属性的值应用于某个元素上时,是把这个元素(包括它的内容)当成一个整体看待,即使这个值没有被子元素继承。因此,一个元素和它包含的子元素都会具有和元素背景相同的透明度,哪怕这个元素和它的子元素有不同的 opacity 属性值。

rgba()只作用于元素的颜色或其背景颜色(设置rgba透明的元素的子元素不会继承透明效果)

使用 rgba给元素的背景设置透明度的方式来替代使用 opacity,可以解决子元素继承父元素透明度的问题

34.常用的块属性标签及其特征有哪些?

常用块标签有 divh1-h6olullidltablepbrform

块标签的特征有独占一行,换行显示,可以设置 宽、高,可以设置内外边距,块可以嵌套块和行标签

35.常用的行内属性标签及其特征有哪些?

行标签有 spanaimgvaremstrongtextareaselectoptioninput

行标签的特征有在行内显示,内容撑开宽、高,不可以设置宽、高( imginputtextarea 等替换元素除外 ),行只能套用行标签。

36.如何避免文档流中的空白字符合并现象?

空格、制表符、换行符(创建新行)、回车符、换页符、垂直制表符属于空白字符,它们只用来占位,并没有实际的内容,也显示不出具体的字符。

空白符合并是标准文档流的特征之一,可以通过设置 white-space 修改这一特征,

这个属性指定了两件事:

  • 空白字符是否合并,以及如何合并。
  • 是否换行,以及如何换行。

具体属性表现可以看MDN

image.png

37.CSS中,自适应的单位有哪些?

  • 百分比: %
  • 相对于视口宽度的单位: vw
  • 相对于视口高度的单位: vh
  • 相对于视口宽度或高度(取决于哪个小)的单位: vm
  • 相对于当前元素字体大小或者父元素字体大小的单位: em
  • 相对于根元素字体大小的单位: rem

38.什么是 FOUC?如何避免 FOUC

FOUC即无样式内容闪烁(Flash Of Unstyled Content),是在IE下通过 @import 导入css文件引起的。

IE会首先加载整个HTML文档的DOM,然后再导入外部的css文件。因此,在页面DOM加载完成到css导入完成之间,有一段时间页面上的内容是没有样式的,这段时间的长短跟网速和电脑速度都有关系。

解决方法:在<head>之间加入一个<link>标签来导入css文件。

39.CSS中类(class)和ID的区别

  • 书写上的差别:class名用 “.”号开头来定义,id名用“#”号开头来定义
  • 优先级不同(权重不同)
  • 调用上的区别:在同一个html网页页面中class是可以被多次调用的(在不同地方)。而id名作为标签的身份则是唯一的,id在页面中只能出现一次。在js脚本中经常会用到id来修改一个标签的属性
  • id作为元素的标签,用于区分不同结构和内容,而class作为一个样式,它可以应用到任何结构和内容上
  • 在布局思路上,一般坚持这样的原则:id是先确定页面的结构和内容,然后再为它定义样式;而class相反,它先定义好一类样式,然后在页面中根据需要把类样式应用到不同的元素和内容上面
  • 在实际应用时,class更多地被应用到文字版块或页面修饰等等,而id更多地被用来实现宏伟布局和设计包含块或包含块的样式

一般原则:类应该应用于概念上相似的元素,这些元素可以出现在同一页面上多个位置,而ID应该应用于不同的唯一的元素。

40.如何解决特定浏览器的样式问题?

  • 主张向前兼容,不考虑向后兼容
  • 根据产品的用户群中各大浏览器,来考虑需要兼容的浏览器
  • 把浏览器分为两类,一类历史遗留浏览器,一类是现代浏览器,然后根据这个分类开发两个版本的网站,然后自己定义哪些浏览器是历史遗留浏览器,历史遗留版浏览器,使用历史遗留页面,通过通告栏告知用户使用现代浏览器,功能更全面,提供好的用户体验。
  • 直接在用户的浏览器不能兼容的时候,提示用户至少什么版本的IE和火狐 谷歌浏览器才能支持
  • 项目开始前就得需要确认兼容支持的最低版本是什么,设计一个对应的兼容方案

41.使用CSS预处理器的优缺点有哪些?

缺点:简单来说CSS预处理器语言较CSS玩法变得更高级了,但同时降低了自己对最终代码的控制力。更致命的是提高了门槛,首先是上手门槛,其次是维护门槛,再来是团队整体水平和规范的门槛。这也造成了初学学习成本的昂贵。

优点:用一种专门的编程语言,为CSS增加了一些编程的特性,将CSS作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。通俗的说,CSS预处理器用一种专门的编程语言,进行Web页面样式设计,然后再编译成正常的CSS文件,以供项目使用。CSS预处理器为CSS增加一些编程的特性,无需考虑浏览器的兼容性问题,例如你可以在CSS中使用变量、简单的逻辑程序、函数等等在编程语言中的一些基本特性,可以让你的CSS更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处。

42.请解释浏览器是如何判断元素是否匹配某个CSS选择器?

当浏览器渲染网页时,需要确定哪些元素匹配特定的 CSS 选择器。浏览器通过使用选择器和DOM结构相互匹配的方式来进行这个过程。

浏览器从DOM树的根开始,深度优先遍历每个节点,同时检查节点是否匹配给定的 CSS 选择器。以下是浏览器判断元素是否匹配选择器的一般步骤:

  1. 选择器解析: 首先,浏览器会解析 CSS 选择器,将其转换为内部的数据结构,以便更容易地进行匹配。

  2. 遍历DOM树: 从DOM树的根节点开始,深度优先遍历每个节点。

  3. 元素匹配: 对于每个节点,浏览器检查它是否与给定的 CSS 选择器匹配。

    • 选择器匹配规则: 浏览器根据选择器的不同部分应用不同的匹配规则。例如,标签选择器匹配元素的标签名,类选择器匹配元素的类名,ID 选择器匹配元素的 id,等等。

    • 组合选择器: 如果选择器包含组合选择器,例如后代选择器、子代选择器等,浏览器会相应地检查元素是否满足组合选择器的条件。

    • 伪类和伪元素: 如果选择器包含伪类或伪元素,浏览器会进一步检查元素是否符合这些伪类或伪元素的条件。

  4. 继续遍历: 如果当前节点匹配选择器,浏览器会继续深度优先遍历它的子节点。

  5. 构建匹配集: 浏览器在遍历的过程中会构建一个匹配集,包含所有与给定选择器匹配的元素。

  6. 渲染: 最终,浏览器使用匹配集中的元素来应用相应的样式,完成页面的渲染。

这个过程是相当复杂的,因为 CSS 选择器支持各种复杂的匹配条件。为了优化性能,浏览器通常会使用一些技术,例如匹配算法的优化、选择器引擎的优化等。这些技术有助于加速元素的匹配过程,提高页面渲染的效率。

43.flex实现均匀分布

里边div数量不固定实现等宽、水平均匀分布。

{
 display: flex;
 justify-content: space-around; /*space-between左右两侧靠边位置没有空隙*/
 flex-wrap: wrap; /*换行*/
}

垂直均匀分布

display: flex;
flex-direction: column;
justify-content: space-evenly; /*水平方向均匀分布*/
align-items: center;/*水平居中*/
flex-wrap: wrap;

44.px,%,em,rem,vw/vh的区别

  • px:绝对单位,无论在哪一种情况下都是一样的
  • %:相对父元素的宽度比例
  • em:相对当前元素的font-size,当用em设置font-size时是相对于父元素的font-size
  • rem:相对根元素的font-size 常用于根据屏幕不同的宽度使用media设置html的font-size,从而根据不同的屏幕显示不同的字体。
  • vw:相对屏幕宽度的1%
  • vh:相对屏幕高度的1%
  • vmin:vw和vh中最小的一个
  • vmax:vw和vh中最大的一个

45. background-size中的cover与contain的区别

background-size中的cover与contain都是都是将图片以相同宽高比缩放以适应整个容器的宽高。

不同的是在no-repeat情况下,如果容器宽高比与图片宽高比不同:

  • cover会缩放至图片能够铺满整个容器,可能会有部分图片区域被裁剪,
  • 而contain则是图片会缩放至整个图片都能显示完全,但是容器可能会有留白。

在repeat情况下:

  • cover:与上述相同;
  • contain:容器内至少有一张完整的图,容器留白区域则平铺背景图,铺不下的再裁掉。

ps:这个就是设置大小的,不是位置

46. z-index从父原则

什么是从父原则:

  • 子元素在与父辈元素比较的时候,用父辈的 z-index 去比较
  • 在与同级元素比较的时候,才有自己的 z-index 去比较

什么情况下会出现从父原则:

  • 父元素通过fixed absolute relative定位的元素, 子元素也是fixed absolute relative定位的元素。
  • 在父元素上设置了z-index
  • 跟父元素同级的元素也是通过fixed absolute relative定位的元素,并且设定了z-index

47.简要介绍⼀下, 你在项⽬中, 如何管理各个元素的 z-index

制定使⽤z-index的规范,⽐如 popover,modal,colorpicker 之类的组件,按照组件特性指定其层级的⾼低规范。另外业务布局中如果⽤到了z-index,尽量控制其层级为较低的规范内,如布局中的z-index尽量使⽤1xx,弹出层类的组件使⽤2xx等。

全局维护⼀个获取z-index的⽅法,每次调⽤时数值递增1:

/* 思路:
我们可以把 DOM 中的所有元素集合起来,
然后转化成一个数组,
然后我们遍历这个数组,把所有元素的 z-index 值提取出来,然后就形成了一个纯数字的数组,
最后从中取到最大值,就是当前页面中的最大的 z-index 值了。
*/

function getZIndex(){
    return [...document.all].reduce((r, e) => Math.max(r, +window.getComputedStyle(e).zIndex || 0), 0)
}

在element-ui中,可以统一使用PopupManager管理


import { PopupManager } from ‘element-ui/lib/utils/popup’

PopupManager.nextZIndex()

48.简要介绍⼀下, 你如何在项⽬中管理样式的? 如何避免不同⻚⾯ / 模块中, 样式的互相影响 ?

  • 使用BEM规则,通过区分模块和元素来进⾏样式命名。

  • 通过 css modules 将css进⾏分模块管理。

    import buttons from "./buttons.css";
    import padding from "./padding.css";
    
    element.innerHTML = `<div class="${buttons.red} ${padding.large}">`;
    

49.%都是相对于谁的

在 CSS 中,相对单位 % 的含义取决于它所应用的属性,但一般来说,% 是相对于父元素的某个属性值计算的。以下是一些常见的情况:

  1. 相对于父元素的宽度:

    • 当应用于水平方向的 width 属性时,百分比是相对于父元素的宽度计算的。
    .child {
      width: 50%; /* 相对于父元素的宽度的50% */
    }
    
  2. 相对于父元素的高度:

    • 当应用于垂直方向的 height 属性时,百分比是相对于父元素的高度计算的。
    .child {
      height: 75%; /* 相对于父元素的高度的75% */
    }
    
  3. 相对于父元素的字体大小:

    • font-size 属性中,百分比通常是相对于父元素的字体大小计算的。
    .child {
      font-size: 120%; /* 相对于父元素的字体大小的120% */
    }
    
  4. 相对于父元素的定位属性:

    • 在定位属性 toprightbottomleft 中,百分比通常是相对于包含块的对应边的长度计算的。
    .child {
      top: 25%; /* 相对于包含块的高度的25% */
    }
    

需要注意的是,这些规则是一般性的指导原则,实际效果会受到父元素和上下文的具体情况的影响。在某些情况下,百分比可能相对于其他属性值计算,例如相对于视口的宽度或高度。因此,具体情况还需要根据属性和上下文来具体确定。

50.display:none 和visibility:hidden的区别

  • display:none会将元素从DOM树中卸载,visibility不会,所以visibility只是元素不可见,但是任然占据位置,display则不占据位置
  • display:none会引起回流,visibility引起重绘
  • display不具有继承性,但是由于在DOM中卸载,所以子元素也不可见,visibility具有继承性,子元素可以通过visibility设置visible显示

CSS3

1.css3有哪些新特性?

具体看这里

3. :first-of-type:first-child的区别是什么?

:first-child 匹配的是父元素的第一个子元素,可以说是结构上的第一个子元素。

first-of-type匹配的是该类型的第一个元素,类型就是指冒号前面匹配到的元素。并不限制是第一个子元素,只要是该类型元素的第一个即可,这些元素的范围都属于同一级,也就是同辈。

eg:
<div>
   <p></p>
   <span></span>
</div>

p:first-child 匹配到的 p元素,因为p元素是div的第一个子元素

span:first-child 匹配不到span元素,因为span是div的第二个子元素

p:first-of-type匹配到p元素,因为p是div所有为p的子元素中的第一个。

span:first-of-type匹配到span元素,因为span是div多有span的子元素中的第一个。

4.介绍下 box-sizing属性

该属性主要用来控制元素盒模型的解析模式。默认值是 content-box

content-box让元素维持W3C的标准盒模型。元素的宽度/高度由 border+padding+content的宽度/高度决定,设置width/height属性指的是指定 content部分的宽度/高度。

border-box让元素维持IE传统盒模型(IE以下版本和IE6、IE7的怪异模式)。设置width/height属性指的是指定 border+padding+content的宽度/高度。

标准浏览器下,按照W3C规范解析盒模型。一旦修改了元素的边框或内距,就会影响元素的盒子尺寸,就不得不重新计算元素的盒子尺寸,从而影响整个页面的布局。

5.CSS3动画的优缺点是什么?

CSS3 动画具有许多优点,但也有一些缺点。下面是 CSS3 动画的主要优缺点:

优点:

  1. 易于使用: CSS3 动画相对于使用 JavaScript 或其他动画技术来说更容易使用。它只需要简单的 CSS 样式,而无需编写大量的 JavaScript 代码。

  2. 性能优越: CSS3 动画是在浏览器的合成线程中执行的,因此通常具有更好的性能,能够利用 GPU 加速,提供平滑的动画效果。

  3. 响应式设计: CSS3 动画可以根据不同的屏幕尺寸和设备类型创建响应式动画,使得网站或应用在各种设备上都能够良好地展示。

  4. 轻量级: 对于简单的动画效果,使用 CSS3 动画通常比使用 JavaScript 或 Flash 更轻量级,可以减轻页面加载和渲染的负担。

  5. 无需额外的库: CSS3 动画无需引入额外的 JavaScript 库,这意味着减少了对外部库的依赖,简化了项目的维护和开发流程。

缺点:

  1. 复杂度限制: 对于复杂的动画效果,CSS3 动画的能力可能会受到限制。在某些情况下,需要使用 JavaScript 或其他动画库来实现更高度定制化的动画。

  2. 浏览器兼容性: 尽管现代浏览器已经广泛支持 CSS3 动画,但在一些旧版本的浏览器中可能存在兼容性问题,需要额外的兼容性处理。

  3. 缺乏逻辑控制: CSS3 动画缺乏对动画过程中的逻辑控制的支持,例如条件语句、循环等。这些复杂的控制可能需要通过 JavaScript 来实现。

  4. 学习曲线: 对于复杂的动画效果,需要深入了解 CSS3 动画的各种属性和参数,这可能会增加学习曲线。

总体而言,CSS3 动画适用于许多简单到中等复杂度的动画场景,但在某些情况下,特别是需要更高度控制和逻辑的情况下,可能需要结合 JavaScript 或其他动画技术来实现。

6. background-originbackground-clip的区别是什么?

background-origin 定义的是背景位置( background-position )的起始点;

background-clip 是对背景(图片和背景色)的切割。

7. box-shadow的溢出问题以及解决方案

子容器加了box-shadow在父容器中可能存在溢出:

<!DOCTYPE html>
<html>
  <head lang="en">
    <meta charset="UTF-8" />
    <title></title>
  </head>
  <style>
    .outer {
      width: 200px;
      height: 200px;
      background: #ffffff;
      border: 1px solid #000000;
      border-radius: 10px;
      /* overflow: hidden; */
    }

    .inner {
      width: 100px;
      height: 100px;
      margin: 50px auto;
      background: #eeeeee;
      box-shadow: 75px 75px red;
    }
  </style>
  <body>
    <div class="outer">
      <div class="inner">这里是inner元素</div>
      这里是innter兄弟元素
    </div>
  </body>
</html>

效果:

image.png

可以给父元素outer添加:overflow: hidden;但是相应的超出范围的元素也会被隐藏

image.png

如果想超出范围的元素被展示,可以使用overflow: scroll;

8.box-shadow阴影被覆盖问题

上下相连的块级元素如果下方的元素有设置背景就会把上方元素的下阴影给覆盖掉:

<!DOCTYPE html>
<html>
  <head lang="en">
    <meta charset="UTF-8" />
    <title></title>
  </head>
  <style>
    .outer {
      width: 200px;
      height: 200px;
      background: #ffffff;
      border: 1px solid #000000;
      border-radius: 10px;
      overflow: scroll;
    }

    .inner {
      width: 100px;
      height: 100px;
      background: #eeeeee;
      box-shadow: 75px 75px red;
    }
    .inner1 {
      background-color: yellow;
    }
  </style>
  <body>
    <div class="outer">
      <div class="inner">这里是inner元素</div>
      <div class="inner1">这里是innter兄弟元素</div>
    </div>
  </body>
</html>

image.png

解决方案1:.inner添加transform: translate3d(0, 0, 0);

image.png

解决方案2:.inner使用相对定位position:relative可以把阴影显示出来

css常见布局

两栏布局

  <div class="left">
    <h1>Left Side</h1>
    <p>我是左侧栏</p>
  </div>
  <div class="right">
    <h1>Right Side</h1>
    <p>我是右侧栏</p>
  </div>  

浮动定位法:float + margin-left

    .left{
      width: 200px;
      background-color: antiquewhite;
      float: left;
    }
    .right{
      background-color: cornflowerblue;
      /* 等于左侧的宽度 */
      margin-left: 200px;
    }

绝对定位法:absolute + margin-left

    .left {
        width: 200px;
        background-color: antiquewhite;
        position: absolute;
        background-color: yellow;
    }

    .right {
        background-color: cornflowerblue;
        /* 等于左侧的宽度 */
        margin-left: 200px;
    }

margin负值法

  <div class="aside"></div>
  <div class="main">
      <div class="content"></div>
  </div>
    .aside {
      width: 300px;
      height: 100px;
      background: darkcyan;
      margin-right: -100%;
      float: left;
    }

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

    .content {
      margin-left: 300px;
      height: 100px;
      background: salmon;
    }

flex

  <div class="box"> //关键
    <div class="left">
      <h1>Left Side</h1>
      <p>我是左侧栏</p>
    </div>
    <div class="right">
      <h1>Right Side</h1>
      <p>我是右侧栏</p>
    </div>  
  </div>
    .box{
      display:flex; 
    }
    .left{
      width: 200px;
      background-color: antiquewhite;
    }
    .right{
      flex: 1; //关键
      background-color: cornflowerblue;
    }

flex:1

  • 当 flex 取值为一个非负数字,则该数字为 flex-grow 值,flex-shrink 取 1,flex-basis 取 0%
  • 当 flex 取值为一个长度或百分比,则视为 flex-basis 值,flex-grow 取 1,flex-shrink 取 1,(注意 0% 是一个百分比而不是一个非负数字)
  • 当 flex 取值为两个非负数字,则分别视为 flex-grow 和 flex-shrink 的值,flex-basis 取 0%
  • 当 flex 取值为一个非负数字和一个长度或百分比,则分别视为 flex-grow 和 flex-basis 的值,flex-shrink 取 1

三栏布局

浮动定位法:float + margin

左栏左浮右栏右浮,中间不设宽度用左右margin值撑开距离,且布局中中间栏放最后

  <div class="left">
    <h1>Left</h1>
  </div>
  
  <div class="right">
    <h1>Right</h1>
  </div>
  
  <!--middle  在左右的后边-->
  <div class="middle">
    <h1>Middle</h1>
  </div>
    .left{
      width: 200px;
      height: 300px;
      background-color: darksalmon;

      float: left;
    }
    .middle{
     // 不设置宽度
      height: 300px;
      background-color: darkseagreen;

      margin: 0 200px;
    }
    .right{
      width: 200px;
      height: 300px;
      background-color: firebrick;

      float: right;
    }

绝对定位法:absolute + margin

左右两栏绝对定位,分别固定到页面的左右两侧,中间栏不设宽度,用左右margin撑开距离。

	<div class="left">左栏</div>
	<div class="middle">中间栏</div>
	<div class="right">右栏</div>
    .left {
      width: 200px;
      height: 300px;
      background-color: #DC698A;

      position: absolute;
      left: 0;
      top: 0;
    }

    .middle {
      height: 300px;
      background-color: #8CB08B;

      margin: 0 200px;
    }

    .right {
      width: 200px;
      height: 300px;
      background-color: #3EACDD;

      position: absolute;
      right: 0;
      top: 0;
    }

flex

  <div class="box">
    <div class="left">左边</div>
    <div class="middle">中间</div>
    <div class="right">右边</div>
  </div>

    .box{
      display: flex;
    }
    .left{
      background-color: lightcoral;
      width: 200px;
      height: 300px;
    }
    .right{
      background-color: lightseagreen;
      width: 200px;
      height: 300px;
    }
    .middle{
      background-color: mediumorchid;

      flex: 1 ;      
    }

水平居中

行内元素水平居中

    <p class="inLine">块级元素中的文字居中</p>

    <div class="inLine">
        <span>行内元素的水平居中需要将text-align加入到父级块元素上</span>
    </div>  
    
  <style>
    .inLine{
      text-align: center;
    }
  </style>

定宽块状元素水平居中

  <div class="blockHaveWidth">定宽块状元素水平居中</div>  
  <style>

    .blockHaveWidth{
      border:solid 1px black;
      width:200px;
      text-align: center;
      
      margin: 0 auto;
    }
  </style>

不定宽块状元素水平居中

  • 改变块状元素的display属性为inline, 然后给父级设置 text-aline:center 来实现水平居中, 这种方法的缺点是不能再给元素设置宽高了
  <div class="father">
    <div class="son">不定宽块状元素水平居中</div>
  </div>
  <style>
    .father {
      text-align: center;
    }
    .son{
      display: inline;
    }
  </style>
  • 利用绝对定位,让元素向右偏移50%,然后再向左偏移自身的50%
  <div class="noWidthBlock">不定宽块状元素水平居中</div>
  <style>
    .noWidthBlock {
      position: absolute;
      left: 50%;
      transform: translateX(-50%);
    }
  </style>
  • flex
  <div class="box">
    <div class="inner">不定宽块状元素水平居中</div>
  </div>
  <style>
    .box {
      display: flex;
    }
    .inner{
      margin: 20px auto;
    }
     
 <!--或者-->
  .box {
      display: flex;
      justify-content: center;
      align-items: center;
    }
  </style>

  • 利用CSS3的fit-content配合左右margin为auto实现水平居中方法
  <div class="son">不定宽块状元素水平居中</div>

  <style>
   .son{
      width: fit-content;
      margin-left: auto;
      margin-right: auto;
    }
  </style>

垂直居中

relative+absolute+margin-top(负值) 已知高度

  <div class="parent">
    <div class="child">
      这里被我垂直居中了。
    </div>
  </div>

  <style>
    .parent {
      height: 500px;
      border: 1px solid red;
      position: relative;
    }

    .child {
      border: 1px solid green;
      width: 300px;
      position: absolute;
      background: red;
      top: 50%;
      /* left: 50%; */
      height: 100px;
      /* margin-left: -150px; */
      margin-top: -50px;
    }
  </style>

relative+absolute+margin-top(负值) 未知高度

  <div class="parent">
    <div class="child">
      这里被我垂直居中了。
    </div>
  </div>

  <style>
    .parent {
      height: 600px;
      border: 1px solid red;
      position: relative;
    }

    .child {
      border: 1px solid green;
      position: absolute;
      background: red;
      top: 50%;
      transform: translate(-50% 0);
    }
  </style>

flex

  <div class="parent">
    <div class="child">
      这里被我垂直居中了。
    </div>
  </div>

  <style>
    .parent {
      height: 600px;
      border: 1px solid red;
      
      display: flex;
      align-items: center;
    }

    .child {
      border: 1px solid green;
      height: 200px;
    }
  </style>

水平垂直居中

绝对定位元素的居中

  <div class="center-vertical"></div>
  <style>
    .center-vertical {
      width: 100px;
      height: 100px;
      background: orange;
      position: absolute;
      top: 50%;
      left: 50%;
      margin-top: -50px;
      /*高度的一半*/
      margin-left: -50px;
      /*宽度的一半*/
    }
  </style>

缺点:需要提前知道元素的尺寸。如果不知道元素尺寸,这个时候就需要JS获取了。

CSS3.0的兴起,使这个问题有了更好的解决方法,就是使用 transform 代替 margin 。

transform 中 translate 偏移的百分比是相对于自身大小而说的。

  <div class="center-vertical">水平竖直居中</div>
  <style>
    .center-vertical {
      background: orange;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50% ,-50%);
    }
  </style>

优点:无论绝对定位元素的尺寸是多少,它都是水平垂直居中显示的。

缺点:就是兼容性问题。

margin:auto;实现绝对定位元素居中

  <div class="center-vertical">水平竖直居中</div>
  <style>
    .center-vertical {
      width: 100px;
      height: 100px;
      background-color: aqua;
      
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      margin: auto;
    }
  </style>

相对定位

  <div class="center-vertical">水平竖直居中</div>
  <style>
    html,body{
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
    }
    .center-vertical {
      width: 300px;
      height: 300px;
      background-color: aqua;
      
      margin: 0 auto;
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
    }
    <!--或者-->
    .center-vertical {
        width: 300px;
        height: 300px;
        background-color: yellow;
        
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }
  </style>

flex

  <div class="parent">
    <div class="center-vertical">水平竖直居中</div>
  </div>
  <style>
    html,body{
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
    }
    .parent{
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .center-vertical {
      background-color: aqua;
    }

可能遇到的面试问题

完成左中右布局:左边固定200px,中间自适应右边固定100px,中间部分优先渲染,并解释原理

中间部分优先渲染就是将中间部分放在最前边,越靠前越先执行:

<!DOCTYPE html>
<html>
  <head lang="en">
    <meta charset="UTF-8" />
    <title></title>
  </head>
  <style>
    .container {
      position: relative;
      padding: 0 100px 0 200px;
    }
    .left {
      background-color: red;
      width: 200px;
      position: absolute;
      left: 0;
      top: 0;
    }
    .main {
      background-color: yellow;
    }
    .right {
      background-color: green;
      width: 100px;
      position: absolute;
      right: 0;
      top: 0;
    }
  </style>
  <body>
    <div class="container">
      <div class="main">main</div>
      <div class="left">left</div>
      <div class="right">right</div>
    </div>
  </body>
</html>

原理就是左侧和右侧分别固定到左右方,然后中间部分通过父元素的padding留出两边的距离。

使用CSS画一个扇形 并说出实现原理

  • 基础圆形构建:和之前一样,先利用.sector类定义的元素通过border-radius: 50%将宽高相等的元素变成圆形,作为后续操作的基础形状承载容器,并且设置overflow: hidden用于裁剪超出自身范围的内容,position: relative方便内部伪元素进行相对定位。
  • 伪元素拓展与定位.sector::before伪元素创建了一个更大尺寸且同样是圆形(通过border-radius: 50%)的元素,通过topleft属性进行相对父元素的偏移定位,transform: rotate(45deg)对其进行旋转,确定了大致的一个初始呈现状态,不过此时还不是准确的扇形。
  • 裁剪形成扇形:关键在于clip-path属性的polygon函数所定义的裁剪区域,通过设定特定的坐标点组成的多边形去裁剪这个伪元素,使得经过旋转后的圆形伪元素只有一部分是可见的,再配合父元素的overflow: hidden隐藏超出部分,最终就准确地形成了一个扇形。我们可以通过调整transform中的旋转角度以及polygon中定义的坐标点等,来改变扇形的角度、大小等外观特征,从而实现不同样式的扇形效果。:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>CSS扇形示例</title>
    <style>
      .sector {
        width: 100px;
        height: 100px;
        border-radius: 50%;
        background-color: red;
        overflow: hidden;
        position: relative;
      }

      .sector::before {
        content: '';
        position: absolute;
        width: 200px;
        height: 200px;
        border-radius: 50%;
        background-color: green;
        top: -50px;
        left: -50px;
        transform: rotate(45deg);
        clip-path: polygon(0 0, 100% 0, 0 100%);
      }
    </style>
  </head>

  <body>
    <div class="sector"></div>
  </body>
</html>

CSS中实现0.5px边框 解决安卓兼容性问题

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>0.5px</title>
    <style>
      .half-border {
        position: relative;
      }
      .half-border::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        width: 200%;
        height: 200%;
        border-top: 1px solid black;
        -webkit-transform: scale(0.5);
        transform: scale(0.5);
        -webkit-transform-origin: 0 0;
        transform-origin: 0 0;
      }
    </style>
  </head>

  <body>
    <div class="half-border"></div>
  </body>
</html>