挑战一轮大厂后的面试总结 (含六个方向) - css 篇

4,936 阅读14分钟

在去年底开始换工作,直到现在算是告了一个段落,断断续续的也面试了不少公司,现在回想起来,那段时间经历了被面试官手撕,被笔试题狂怼,悲伤的时候差点留下没技术的泪水。

这篇文章我打算把我找工作遇到的各种面试题(每次面试完我都会总结)和我自己复习遇到比较有意思的题目,做一份汇总,年后是跳槽高峰期,也许能帮到一些小伙伴。

先说下这些题目难度,大部分都是基础题,因为这段经历给我的感觉就是,不管你面试的是高级还是初级,基础的知识一定会问到,甚至会有一定的深度,所以基础还是非常重要的。

我将根据类型分为几篇文章来写:

面试总结:javascript 面试点汇总(已完成) 强烈大家看看这篇,面试中 js 是大头

面试总结:nodejs 面试点汇总(已完成)

面试总结:浏览器相关 面试点汇总(已完成)

面试总结:css 面试点汇总(已完成)

面试总结:框架 vue 和工程相关的面试点汇总(已完成)

面试总结:非技术问题汇总(已完成)

我会抓紧时间把未完成的总结补全的~

这篇文章是对 css 相关的题目做总结,欢迎朋友们先收藏在看。

先看看目录

目录

BFC - 块级格式化上下文

块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。

又多了一个名词,可以先不用纠结 BFC 的概念,先看看它能解决什么问题

清除浮动

在 flex 布局还没流行的时候,我们常常会用到浮动 float ,浮动元素脱离的文档流,带来直接的一个问题就是父级高度塌陷。

清除浮动常用的方法有, clear 属性,还有就是构建 BFC ,看个小栗子

.con{
    border: 1px solid;
    width: 300px;
}
.float{
    float: left;
    height: 100px;
    background-color: sandybrown;
}
<div class="con">
    <div class="float">xxxxxxxx</div>
    <p>dsfsdfwefesfhjkhjkhuhjk</p>
</div>

黄色 div 是个浮动元素,定了 100px 高度,父级不定高,很明显父级高度没有被撑开。

float

给父级 con 加上 overflow: auto; 效果如下

float1

这时候父级div就是一个 BFC

外边距折叠

在CSS中,两个或多个毗邻的普通流中的盒子(可能是父子元素,也可能是兄弟元素)在垂直方向上的外边距会发生叠加,这种形成的外边距称之为外边距叠加。

形成外边距折叠有几个关键要素:毗邻、两个及以上、垂直方向、正常流

毗邻:对于父子元素,他们自己是紧挨着的,子元素没有被父元素 border padding 给隔开,这样他们就是毗邻的;对于兄弟元素,他们的盒模型是挨着一起的就是毗邻的。

正常流:除去浮动定位、绝对定位,也就是正常的文档流。

这是个非常常见的问题。解决方案也挺多的,无外乎打破三要素中的一个即可,比如采用浮动、绝对定位、inline-block、添加空白的flex元素、还有就是我们接下来要说的构建 BFC

.con {
    width: 300px;
    background-color: antiquewhite;
}

.one {
    height: 100px;
    margin-top: 10px;
    margin-bottom: 20px;
    background-color: seagreen;
}

.two {
    height: 100px;
    margin-top: 10px;
    background-color: slateblue;
}
<div class="con">
    <div class="one"></div>
    <div class="two"></div>
</div>

float2

div onemargin-top: 10px; 导致父级向下移动 10px,这是父子元素的外边距折叠,我们用构建 BFC 的方式解决。

.con {
    width: 300px;
    background-color: antiquewhite;
    overflow: auto; /* 构建BFC */
}

效果如下:

float3

那么对于毗邻的兄弟节点,方法也是一样,把一个节点构建成 BFC 即可

<div class="con">
    <div class="one"></div>
    <div style="overflow: auto;">
        <div class="two"></div>
    </div>
</div>

float4

如何创建

方法很多,可根据实际情况选择

  • 根元素(html)
  • 浮动元素(元素的 float 不是 none)
  • 绝对定位元素(元素的 position 为 absolute 或 fixed)
  • 行内块元素(元素的 display 为 inline-block)
  • 表格单元格(元素的 display为 table-cell,HTML表格单元格默认为该值)
  • 表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)
  • 匿名表格单元格元素(元素的 display为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table)
  • overflow 值不为 visible 的块元素
  • display 值为 flow-root 的元素
  • contain 值为 layout、content或 paint 的元素
  • 弹性元素(display为 flex 或 inline-flex元素的直接子元素)
  • 网格元素(display为 grid 或 inline-grid 元素的直接子元素)
  • 多列容器(元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1)
  • column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。

然后

上面可看出 BFC 可以清除浮动,可以解决外边距折叠两问题。

BFC 可通俗理解成是构建一个独立的区域,可包含区域内的所有元素,包括浮动元素,与外界互不打扰的一个空间。

参考文档:

developer.mozilla.org/zh-CN/docs/…

tech.youzan.com/css-margin-…

www.cnblogs.com/libin-1/p/7…

absolute 是相对哪个元素定位的

元素定位在 css 算是基础中的基础了,网上有很多介绍的文章,但我觉得 mdn 的讲解就已经非常清晰 position - CSS(层叠样式表) | MDN

position 属性取值有 relative, absolute, fixed 或 sticky,元素设置了其中之一的就是定位元素。(换句话说,除static以外的任何东西)。

目前定位类型有四类:

  • 相对定位元素(relatively positioned element)是计算后位置属性为 relative 的元素。
  • 绝对定位元素(absolutely positioned element)是计算后位置属性为 absolute 或 fixed 的元素。
  • 粘性定位元素(stickily positioned element)是计算后位置属性为 sticky 的元素。用于滑动中固定某一元素,这个目前有些兼容性问题。

相对定位

position: relative; 元素按照文档流的布局放置元素,它的用处是可以在不改变布局方式的前提下调整元素位置,使用 top bottom left right

绝对定位

position: absolute; 绝对定位的元素脱离了文档流,不会占据文档流的空间,感觉就像在文档流的上一层。

绝对定位的元素可以使用 top bottom left right 调整布局位置,在没有设置这几个值的时候,绝对定位元素显示还是保持在当前的位置。如果设置了值,那么这个元素就需要找到一个锚点,因为已经脱离文档流,所以需要找到一个参考点,这参考点就是 最近的非 static 祖先元素 ,可以是 relative, absolute, fixed,一直往上到 body 元素。

所以常常会采用 relative + absolute 的组合布局方式,当然也可以利用绝对定位元素在当前位置显示的特性结合 margin 来使用。

绝对定位还有个用处,就是避免触发回流,因为脱离正常的文档流,因此对于频繁回流的元素可以采用绝对定位。

z-index

在说一个跟定位常一起使用的 z-index ,这个值表示创建一个新的显示层级,值大的在最上层。

多个绝对定位元素会按照后一个覆盖前一个的显示方式,而且绝对定位元素会覆盖文档流中的元素,那么只有在元素位置不当便调整顺序的时候才只用,正常情况下不建议设置值,毕竟多使用一个元素,就容易出现诡异的问题。

DPR

先看看几个概念

像素

是图像显示的基本单位,类似于米是长度的一个单位一样。

1像素是显示的最小区域。

物理像素

设备的物理像素,每个设备的物理像素都是厂家固定好的,

css像素

这个主要用于我们编码用的,约定好的在显示层上的单位,screen.width 可获取到逻辑编码中的窗口最大像素。

在看看 DPR

在 iphone 没有搞事之前,物理像素和逻辑像素是相等的,但如今高清屏已经快成标配,可显示的像素点越多越清晰,导致设备上每英寸可显示的像素点(PPI)越来越多,这样一来,屏幕的大小没变,css的逻辑像素没变,可物理像素却变多了,一个逻辑像素要对于多个物理像素,这两者的比例就是 DPR

DPR = 物理像素/css逻辑像素

可通过 window.devicePixelRatio 获取设备的 DPR

参考文档: www.cnblogs.com/xiaohuochai…

1px 问题了解么?有什么解决方案?

在高清屏中 DPR 可能会是 2 或者 3 ,那么原先 1px 像素的线在高清屏下就占了2个或者3个物理像素,导致线看着比较粗。

解决:

  1. 使用伪类,设置 border 1px scale(0.5)
  2. 设置 meta initial-scale 根据DPR设置初始值
  3. 伪类 + transform: scaleY(0.5);
/* 伪类 + transform: scaleY(0.5); */
.px1 {
    position: relative;
}

.px1:before {
    content: " ";
    position: absolute;
    left: 0;
    top: 0;
    width: 200%;
    border: 1px solid black;
    color: black;
    height: 200%;
    transform-origin: left top;
    transform: scale(0.5);
}

link 和 @import 的区别

看到这个问题我没反应过来,import 不是js里的东西吗?回来查了资料才明白 css 还可以这么玩。

@import 根据字面意思就知道是用于导入其他样式文件的,两者的区别如下:

  1. 从属关系区别

    link:是 html 提供的标签,不仅可以加载css样式表,还可以定义 RSS、rel 连接属性等。

    @import:是 css 提供的语法规则,用于导入样式表。

  2. 加载顺序区别

    link:文件是同时加载。

    @import 引入的 CSS 将在页面加载完毕后被加载。

  3. 兼容性问题

    link 不存在兼容性问题;@import 可能会有兼容性问题

display:none与visibility:hidden的区别?

效果都是隐藏元素

display:none 在文档布局中不在分配空间(节点),值变化会导致回流和重绘

visibility:hidden 保留渲染树中的节点,占用空间,会导致重绘

inline-block block 的区别

这两个分别是:行内块级元素和块级元素,顺带介绍下行内元素

块级元素

块级元素的特点:元素总是在新的一行开始,盒模型的属性均可以控制,div p ul ol ... 等元素默认就是块级元素,也可以通过 display: block; 设置为块级元素。

行内元素

行内元素的特点:和其他元素在同一行,元素不可以设置高度和宽度,取决于内容的宽高度,默认的行内元素有 span a lable input img ...,也可通过 display: inline; 设置为行内元素。

行内块级元素

名字看上去就是上面两者的结合,同时具备了两个的特性。通过 display: inline-block; 设置。

但是两个相邻的 inline-block 元素中间有空格就会出现间隙,解决办法可以粗暴的移除空格和换行,还有设置字体大小为 0 , 因空格也是字符,所以可给父级设置 font-size:0、letter-spacing:-3px

rem em vh vw 的区别

这几个单位常用于自适应布局

rem em

rem : css3 新增,相对于根节点的字体大小的一个单位,eg: 1rem * font-size:20px = 20px

在开发前先制定好一个基准,比如说以 375 宽的设计稿作为规范,设定这个宽度下的字体大小为 375/10 = 37.5 ,那设计稿下 60px 的宽对应的 rem 就是:60px = (60/37.5)rem

若使用css预处理,可以写一个转换函数

@function px2rem($px) {
    @return ($px/37.5) + rem;
}

em : 与rem类似,但是相对于父级元素的字体大小。

vw vh

相对于视口宽高的百分比值

vw : 1vw 等于视口宽度的1%
vh : 1vh 等于视口高度的1%
vmin : 选取 vw 和 vh 中最小的那个
vmax : 选取 vw 和 vh 中最大的那个

//iPhone 6尺寸作为设计稿基准
$vm_base: 375; 
@function vw($px) {
    @return ($px / $vm_base) * 100vw;
}

单行、多行文本居中

单行:

  1. 设置 line-heightheight 相同
  2. flex 布局,设置交叉轴对齐方式

多行:

  1. flex 布局 display: flex;align-items: center;
  2. table 布局 ,外层使用 display: table; 内层使用 vertical-align: middle;display: table-cell; table-cell 可以将元素表现与单元格 td 类似,在对单元格设置居中,不过会破坏其他属性,比如浮动、margin 等
.text{
    background-color: sandybrown;
    width: 200px;
    height: 300px;
    display: table;
}
.cell{
    vertical-align: middle;
}
<div class="text">
    <div class="cell">
        今天天气很好,好想出去玩.今天天气很好,好想出去玩.今天天气很好,好想出去玩.今天天气很好,好想出去玩.今天天气很好,好想出去玩.
    </div>
</div>
  1. 设置外层 line-height 等于外层高度,文本一行的高度就等于容器的高度,内层使用 display: inline-block;vertical-align: middle;line-height: 17px; 内层设定为行内块级元素,设置行内元素的对齐方式是 middle,在对元素重新设定行高
.text {
    background-color: sandybrown;
    width: 200px;
    height: 300px;
    line-height: 300px;
}
.cell {
    display: inline-block;
    vertical-align: middle;
    line-height: 20px;
}
<div class="text">
    <div class="cell">
        今天天气很好,好想出去玩.今天天气很好,好想出去玩.今天天气很好,好想出去玩.今天天气很好,好想出去玩.今天天气很好,好想出去玩.
    </div>
</div>

css 选择器和优先级

id选择器(#myid)、类选择器(.myclassname)、标签选择器(div, h1, p)、相邻选择器(h1 + p)、子选择器(ul > li)、后代选择器(li a)、通配符选择器(*)、属性选择器(a[rel="external"])、伪类选择器(a:hover, li:nth-child),简单介绍下面几个:

a > b :子类选择器,只有直接的子类才生效
a + b:毗邻选择器,只有毗邻的下一个元素才生效
a ~ b :后续选择器,a元素之后的所有同级的b元素
[attribute] :属性选择器,含有这个属性的元素才生效
:first-of-type : 选择器匹配元素其父级是特定类型的第一个子元素

选择器权重

优先级排序: !important > 行内样式 > ID > 类、伪类、属性 > 标签名 > 通配符 > 继承

权重值如下,每个都是相差一个量级

  1. 元素和伪元素选择器: 1
  2. class选择符: 10
  3. id选择符:100
  4. 内联样式:1000

英文换行

  • word-break: break-all 对字符起作用,断开单词,下个字母自动到下一行。主要解决了长串英文的问题。
  • word-wrap:break-word 只对英文起作用,以单词作为换行依据

哪些属性可以继承

元素外观相关的属性可以继承,比如字体相关的属性、文本系列的属性。布局相关的属性不可以继承,具体属性名就不列举了。

flex 常见有属性

问这种属性名称的真是尴尬,平常都是自动补全的,哪记得住呀...

容器上的属性

flex-direction : 主轴方向
flex-wrap : 换行的方式
flex-flow :上面两个的简写
justify-content : 主轴的对其方式
align-items : 交叉轴的对齐方式
align-content : 多根主轴的对齐方式

元素上的属性

order : 排序值,数值越小越靠前
flex-grow : 项目放大的比例,默认为 0 不放大
flex-shrink : 项目缩小的比例,默认 1
flex-basis : 属性定义了在分配多余空间之前,项目占据的主轴空间,如果元素定义了宽,那么宽度将无效 默认 auto
flex :以上三个的简称

小结

css 相关的问的相对比较少些,一般会以一个具体场景作为前提展开问。

觉得有帮助的小伙伴,求求点个赞呀~~

最后还是要在给大家推荐我吐血整理的 面试总结:javascript 面试点汇总 强烈大家看看这篇,面试中 js 是大头。

推荐文章

50道CSS基础面试题(附答案)