CSS面试题【一】

102 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情

1、防止父元素高度坍塌的 4 种方案

问题重现:

  • 父元素的高度,都是由内部未浮动子元素的高度撑起的。
  • 如果子元素浮动起来,就不占用普通文档流的位置。父元素高度就会失去支撑,也称为高度坍塌

不好的解决方法

  • 给父元素设置固定高度

缺点:多数情况下,父元素高度由内容撑起,很难提前固定父元素的高度。

方案1:(经过测试,只能解决 float引起的坍塌问题,不能解决绝对定位的坍塌问题)

为父元素设置 overflow: hidden 属性。

原理:CSS 中 overflow: hidden 属性会强制要求父元素必须包裹住所有内部浮动的元素,以及所有元素的 margin 范围

缺点:如果刚好父元素有些超范围的子元素内容需要显示(比如,个别 position 定位的子菜单项),不想隐藏,就会发生冲突。

方案2:

在父元素内的结尾追加一个空子元素(块级元素),并设置空子元素清除浮动影响(clear: both)。

原理:利用 clear: both 属性和父元素必须包含非浮动的元素两个原理

缺点:无端多出一个无意义的但不见的空元素,影响选择器和查找元素

方案3:

设置父元素也浮动。

原理:浮动属性也会强制父元素扩大到包含所有浮动的内部元素。

缺点:会产生新的浮动影响。比如,父元素浮动,导致父元素之后平级的页脚div上移,被父元素挡住了。

方案4:(最好做法)

为父元素末尾伪元素设置 clear: both

在元素开头的结尾各有一个伪元素:::before::after

优点:既不会影响显示隐藏,又不会影响查找元素,又不会产生新的浮动问题。

.parent::after{ content: ""; display: block; clear: both; height: 0; } // 有些游览器display有默认高度

2、BFC

  • 什么是BFC(Block formatting context)
  • 直译为 “块级格式化上下文”
  • 它是网页中一个 独立的渲染区域(也称为 formatting context)
  • 这个渲染区域只有块级(Block)元素才能参与
  • 它规定了内部的块级元素如何布局
  • BFC渲染区域内部如何布局,与区域外部毫不相干
  • 外部元素也不会影响BFC渲染区域内的元素

简单来说:BFC就是页面上的一个隔离的独立渲染区域

区域里面的子元素不会影响到外面的元素。

外面的元素也不会影响到区域里面的子元素。

css两种渲染区域:块级元素渲染区域和行级元素渲染区域。

  • BFC(Block formatting context)
    • 块级渲染区域:所有 display 属性为 block, list-item,table 的元素,会生成块级元素渲染区域。
    • 块级元素渲染区域内以 BFC 方式渲染。
  • IFC(inline formatting context)
    • 行级元素渲染区域:display属性为 inline,inline-block,inline-table 的元素,会生成行级元素渲染区域。
    • 行级元素渲染区域以 IFC 方式渲染

BFC的布局规则

  • 属于同一个BFC的两个相邻块元素在垂直方向上的 margin 会发生重叠/合并。但水平方向的 margin 不会
  • 左侧 BFC 渲染区域的 margin,必须与右侧 BFC 渲染区域的 margin 相衔接,不能出现重叠。

4种情况下会形成BFC渲染区域

  • float 的值不是 none
  • position 的值不是 static 或者 relative
  • display 的值是 inline-block、table-cell、flex、table-caption 或者 inline-flex
  • overflow 的值不是 visible

BFC解决问题

问题1:垂直方向上,两个元素上下 margin 相遇时,两元素间的总间距并不等于两个 margin 的和。而是等于最大的 margin。(小的会被大的吞并)

解决:

  • 用一个外围块元素包裹下方元素
  • 父元素设置样式 ::before{ content: ""; display: table; height: 0; }

原理:新的外层元素,变成一个BFC方式的渲染区域,就必须包裹内部子元素及子元素的 margin。而且,内部元素不能超出范围影响外部,外部元素也不能进入 BFC 范围内,影响内部

**问题2:**垂直方向的margin溢出。子元素设置 margin-top,会超出父元素上边的范围,变成父元素的 margin-top,而实际上,子元素与父元素之间,依然是没有margin-top的。

解决方法:5种

  • 设置父元素 overflow: hidden
    • bfc的方式
  • 为父元素添加上边框,颜色设置为透明(transparent)
    • 原理:这里不是bfc。而是因为边框本身可以阻隔 margin 溢出
    • 缺点:会增大父元素的实际大小,导致布局错乱
  • 用父元素的 padding-top 代替第一个子元素的 margin-top
  • 在父元素内第一个子元素之前添加一个空的 <table></table>
    • 原理:table的display属性默认相当于 table,所以形成小的 bfc 渲染区域。
    • 优点:空 table 元素没有大小,不占用父元素空间
    • 缺点:增加了一个看不见的空元素,干扰查找元素
  • 伪类:父元素::before{ content: ""; display: table; }

问题3:左侧定宽,右侧自适应

第一步:左侧定宽元素左浮动:.left{ float: left; width: 200px }

第二步:右侧元素不用右浮动,而是 .right{ overflow: hidden; }

原理:右边元素 overflow: hidden 后,形成 BFC 渲染区域。左边的 float 元素就不能进入右边范围了。