css面试题汇总 (持续更新)

nicepainkiller 2020-05-27

前言:这篇随笔是为了准备后面的面试而整理的,网上各种面试题太多了,但是我感觉很多太偏了,而且实际开发过程中并不会遇到,因此这里我整理一些比较常用的,或者是相对比较重要的知识点,每个知识点都会由浅入深,把相关的都放在一起,便于自己复习,感兴趣的朋友也可以一起学习收藏。

(此篇非100%原创,因为收集一些代码示例的时候,我会直接截图,因为只是整理复习)

一,CSS Box相关

(基本都会问这题,必考)

1,怎么理解CSS里盒子(Box)的概念?

盒子(Box) 是 CSS 布局的对象和基本单位,一个页面就是由N个盒子组合而成的,我们通过设置display以及元素类型来决定这个box的类型。

2,解释一下盒模型?有哪些类型?

一个基本的盒模型,包括content(width/height),padding,border,margin

目前有两种盒子模型,IE盒模型和W3C标准盒模型,两者的区别是,W3C标准盒模型,宽高是只有内容content,没有padding和border的,像这样:

css面试题汇总 (持续更新)

而IE盒模型,宽高不光有content,还包含了padding和border,像这样:

css面试题汇总 (持续更新)

3,如何设置两者?

box-sizing: content-box;  // W3C标准盒模型(默认情况下)

box-sizing: border-box;  // IE盒模型

(这个也比较好记,标准的就是只有内容,就是content,而IE就是有border的)

4,如何获取盒子的宽高?

我们用得最多的就是dom.offsetWidth/offsetHeight,这个包含了width/height,padding和border,是项目中最常用的,兼容性也最好,记住这个就行了

(为什么我用dom.style.width/height,获取到的是空,因为这个style.width只能获取到行内样式,对于style标签中的和link外链的样式都无法获取到,所以还是用offsetWidth好点)

5,盒子(Box)常见定位方案?

普通文档流、浮动流、绝对定位流

6,我们常说的BFC、IFC、GFC、FFC是什么?

刚刚上面讲了盒模型,讲了盒子的定位方案,那盒子内部是如何渲染排列的呢?答案就是Formatting context(格式化上下文)。

Formatting context(格式化上下文)是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。

而题中所提到的BFC、IFC、GFC和FFC都是属于Formatting context(格式化上下文),它们的全称是

【Block formatting context】(BFC)   块级格式化上下文

【Inline formatting context】(IFC)     内联格式化上下文

【Grid formatting context】(GFC)     网格布局格式化上下文

【Flex formatting context】(FFC)      自适应格式化上下文

这里重点先讲一下BFC

BFC的特性是什么?

  • 盒子从顶部开始垂直排列
  • 两个相邻的盒子之间的垂直距离由外边距(既margin)决定
  • 块级格式化上下文中相邻的盒子之间的垂直边距折叠
  • 每个盒子的左外边与容器的左边接触(从右到左的格式化则相反),即使存在浮动也是如此,除非盒子建立了新的块格式化上下文
  • 形成了BFC的区域不会与float box重叠
  • 计算BFC的高度时,浮动子元素也参与计算
如何创建BFC?
  • 根元素(html)或其他包含它的元素
  • 浮动元素
  • 绝对定位元素
  • 非块级盒子的块级容器(inline-blocks, table-cells, table-captions等)
  • overflow不为visiable的块级盒子

(这里我们不用死记硬背,我们重点看一下平时开发中BFC会遇到哪些问题,以及如何利用BFC去解决这些问题)

问题一:同一个BFC中相邻的盒子之间(垂直方向)的margin(上一个盒子的margin-bottom和下一个盒子的margin-top)重叠

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>防止margin重叠</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    p {
        color: #f55;
        background: yellow;
        width: 200px;
        line-height: 100px;
        text-align:center;
        margin: 30px;
    }
</style>
<body>
    <p>看看我的 margin是多少</p>
    <p>看看我的 margin是多少</p>
</body>
</html>

生成的效果是这样的:

css面试题汇总 (持续更新)

原因是margin重叠了。

那解决方案就是让它们不要在同一个BFC中就行了,改成这样:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>防止margin重叠</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    p {
        color: #f55;
        background: yellow;
        width: 200px;
        line-height: 100px;
        text-align:center;
        margin: 30px;
    }
    div{
        overflow: hidden;
    }
</style>
<body>
    <p>看看我的 margin是多少</p>
    <div>
        <p>看看我的 margin是多少</p>
    </div>
</body>
</html>

效果如图:

css面试题汇总 (持续更新)

成功了!

问题二:对于使用了float的盒子,如何避免左侧贴边重叠?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    body {
        width: 100%;
        position: relative;
    }
 
    .left {
        width: 100px;
        height: 150px;
        float: left;
        background: rgb(139, 214, 78);
        text-align: center;
        line-height: 150px;
        font-size: 20px;
    }
 
    .right {
        height: 300px;
        background: rgb(170, 54, 236);
        text-align: center;
        line-height: 300px;
        font-size: 40px;
    }
</style>
<body>
    <div class="left">LEFT</div>
    <div class="right">RIGHT</div>
</body>
</html>

效果如图:

css面试题汇总 (持续更新)

 因为第一个left元素用了float,所以脱离了普通文档流,而right元素因为在BFC内,自动贴到左侧,所以重叠了。

解决方案是,因为left元素本身形成了一个BFC,所以让right也形成BFC就行了:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    body {
        width: 100%;
        position: relative;
    }
 
    .left {
        width: 100px;
        height: 150px;
        float: left;
        background: rgb(139, 214, 78);
        text-align: center;
        line-height: 150px;
        font-size: 20px;
    }
 
    .right {
        overflow: hidden;
        height: 300px;
        background: rgb(170, 54, 236);
        text-align: center;
        line-height: 300px;
        font-size: 40px;
    }
</style>
<body>
    <div class="left">LEFT</div>
    <div class="right">RIGHT</div>
</body>
</html>

效果如图:

css面试题汇总 (持续更新)

解决了!

问题三:如何解决float元素无法撑起外层容器的高度问题?

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>清除浮动</title>
</head>
<style>
    .par {
        border: 5px solid rgb(91, 243, 30);
        width: 300px;
    }
    
    .child {
        border: 5px solid rgb(233, 250, 84);
        width:100px;
        height: 100px;
        float: left;
    }
</style>
<body>
    <div class="par">
        <div class="child"></div>
        <div class="child"></div>
    </div>
</body>
</html>

效果如图:

css面试题汇总 (持续更新)

因为内部两个子元素脱离了文档流,所以无法撑起。

解决方案是利用BFC特性的最后一条:

  • 计算BFC的高度时,浮动子元素也参与计算

因此将父元素设为BFC:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>清除浮动</title>
</head>
<style>
    .par {
        border: 5px solid rgb(91, 243, 30);
        width: 300px;
        overflow: hidden;
    }
    
    .child {
        border: 5px solid rgb(233, 250, 84);
        width:100px;
        height: 100px;
        float: left;
    }
</style>
<body>
    <div class="par">
        <div class="child"></div>
        <div class="child"></div>
    </div>
</body>
</html>

效果如图:

css面试题汇总 (持续更新)

成功了!

总结:

上面的几个案例,基本都是通过添加overflow: hidden; 属性来创建BFC,这个也是比较常见的方式。

(持续更新。。。)

相关推荐

aSuncat / 0评论 2020-08-18