css interview

435 阅读10分钟

CSS

what ? rem 和 vw,dpr

  • rem: 相对于根元素来做计算的字体大小单位
  • vw 相对于视窗的宽度: 1vw 为window.innerWidth 的 1%
  • 设备像素比device pixel ratio简称dpr,即物理像素和设备独立像素的比值

rem不支持ie8:解决方案:p {font-size:14px; font-size:.875rem;}

介绍一下css盒模型

css 中,盒模型分为 content、padding、border、margin四部分,又有两种盒模型,通过 box-sizing 切换:

当设置为 content-box 时,属于标准盒模型,在设置宽度和高度时,只包含 content,不包含 padding 和 border; 而设为 border-box 时,属于 IE 盒模型,设置宽度和高度时,包含 content、padding 和 border。

选择器怎么解析的

样式系统从关键选择器开始,向左依次查找规则选择器的祖先元素,如果出现未匹配的情况会放弃规则,否则会左移直至匹配完成。因此在写样式时,应尽量选择 ID 选择器或 class 选择器作为关键选择器,并且减少样式的层级,降低消耗。

选择器优先级

  • @important 权重最高,important会覆盖important
  • 行内样式权重为 1000
  • ID 选择器权重为 0100
  • 类选择器,伪类选择器,属性选择器权重为 0010
  • 元素选择器和伪元素选择器权重为 0001
  • 通配符 > 继承 > 浏览器默认

伪类和伪元素的区别

  • 其中伪类用单冒号表示,当元素处于某种状态时,为该元素添加样式,如 a 标签的 hover;
  • 伪元素用双冒号表示,为了兼容老浏览器,有时候也会用单冒号表示,作用是==创建不在文本流中的元素==,并为其添加样式,如 ::before,在指定元素前添加元素。

使用过 flex 布局吗

  • flex 布局就是弹性盒布局是一种替代浮动布局的方案。在 flex 布局中有两大概念:容器和轴。
  • 其中,轴分为主轴和与主轴垂直的交叉轴,可通过 flex-direction 来切换
  • 然后就是容器,采用弹性盒的区域就是容器,将容器的 display 设为 flex,内部的元素就成为一个个项目,整体形成 flex 布局,容器可通过 justify-content 控制项目在主轴的排列方式,通过 align-items 控制项目在交叉轴的排列方式,还有 flex-wrap 控制项目的换行方式。针对项目,可以通过 flex-grow 来控制自身放大比例, flex-shrink 控制缩小比例,order 控制项目排列顺序

讲一下 BFC

BFC 指的是格式化上下文,当一个元素形成 BFC 后,其内部元素的布局不会影响外部元素,外部元素的布局不会影响内部元素。可以用来清除浮动和解决 margin 重叠等问题。一般根元素、浮动元素、绝对定位元素、行内块元素、表格类元素、还有 overflow 不为 visible 的元素都会创建 BFC。

说一下清除浮动

浮动元素会引起父元素高度塌陷,影响布局,主要通过两种方式解决:

将父元素设置为 BFC,一般使用 overflow: hidden,缺点是元素溢出会裁切; 使用 clear 属性,该属性会避免元素受到到浮动元素的影响,可通过以下方式设置:

  • 添加空元素,缺点是增加无语义标签
//单伪元素
.clearfix::after {
  content: '';
  display: table; // clear 属性在块级元素下才能起作用
  clear: both;
}
.clearfix {
  *zoom: 1; // IE6+ 兼容
}
//双伪元素
.clearfix::before,
.clearfix::after {
  content: '';
  display: table;
}
.clearfix::after {
  clear: both;
}
.clearfix {
  *zoom: 1;
}

为什么用到 zoom

zoom 属性是 IE 独有的属性,用来设置或检索对象的缩放比例。设置该元素会触发 haslayout 属性,该属性为 true 时,该元素负责对象自己以及子元素进行尺寸计算和定位,这时元素就会扩大和缩小,高度重新计算,解决了高度塌陷问题。

用到哪些定位

  1. 相对定位,将元素的 position 设为 relative,元素相对于自身 content box 定位,仍占据原来位置空间;
  2. 绝对定位,将元素的 position 设为 absolute,元素相对于第一个 position 不为 static 的祖先元素的 padding box 定位,元素不占据原来位置空间;
  3. 固定定位,将元素的 position 设为 fixed,元素相对于浏览器窗口顶部定位,不占据原来位置空间。

margin 重叠怎么解决

  • 相邻兄弟元素 margin-bottom 和 margin-top 重叠。可以将其中一个设为 BFC
  • 父子元素 margin-top 重叠。可以给父元素添加 border-top|padding-top 来分隔父子元素,也可将父元素设为 BFC;
  • 父元素高度 auto,父子元素 margin-bottom 重叠,在第二种情况的解决方案上,还可以给父元素设置 height、min-height、max-height;
  • 无内容元素自身 margin-top 与 margin-bottom 重叠。可以给元素设置 border|padding|height

li 跟 li 之间为什么有空隙,怎么解决

li 是行内元素,浏览器会将行内元素间的 回车|空格|制表符 渲染为空格,所以会出现无法选中的空隙。解决方案:

写在同一行,由于不美观,不使用; 左浮动,但 swiper 不能应用; margin 负值,最后一个元素会多出负 margin,不适合大规模使用; 将父元素 font-size 设为 0,但需要将 li 的font-szie 重新设置,且 safari 依然出现空白 设置负 word-spacing | letter-spacing,再将 li 内的字符间距 | 文本间距设为默认,目前比较完美。

用 css 画三角形

  • 原理是利用边框的等分原理
.triangle {
  width: 0;
  height: 0;
  border-width: 100px;
  border-style: solid;
  border-color: tomato transparent transparent transparent;
}

连接点击后 hover 失效

  • a 标签的四种伪元素有着前后规则,其中 hover 需要放在 visited 后,所以将两者调换位置就可以。

实现单行和多行文本溢出添加省略号

//单行:
p {
  overflow: hideen;
  text-overflow: ellipsis;
  white-space: nowrap;
}
 //多行溢出:
p {
  position: relative;
  overflow: hidden;
  /* height/line-height 为行数 */
  height: 3em;
  line-height: 1.5rem;
}
p::after {
  content: '...';
  position: absolute;
  bottom: 0;
  right: 0;
  background-color: #fff;
}

元素隐藏有哪些方式,有什么不同

方案占据空间绑定监听事件
overflow: hidden
display: none
visibility: hidden
opacity:0
定位将元素移到可视区域,相对定位,绝对定位
z-index 负值
transform: scale(0, 0)

为什么要重置样式,为什么不用通配符重置

现代浏览器自身设置了样式,为了在浏览器上呈现一样的样式,需要将样式进行重置。

使用通配符重置的确简单,但是会覆盖掉一些浏览器自身有价值的样式,并且使用通配符是需要将所有标签都遍历一遍,当网站较大,标签较多是,这样写大大加剧了网站的运行负载。

怎么让 chrome 显示 12px 以下的字体

在 chrome 下默认会将 12px 及以下的字体渲染为 12px,解决方案为:

  • 采用自身属性:-webkit-text-size-adjust: none,在高版本 chrome 下无效
  • 采用缩放属性:-webkit-transform: scale(0.5),并将元素设为块级元素
  • 使用图片,既不影响兼容也不影响美观

TODO:实现两栏布局

<div class="container">
  <div class="left">left</div>
  <div class="right">right</div>
</div>

浮动加BFC

.container {
  overflow: hidden;
  *zoom: 1;
}
.left {
  float: left;
  margin-right: 20px;
}
.right {
  overflow: hidden;
  *zoom: 1;
}

flex

  • 实现:flex: 1 有占满剩余空间的特性
.container {
  display: flex;
}
.right {
  margin-left: 20px;
  flex: 1;
}

圣杯布局

  • 特点:中间部分写在前面,优先加载
  • 实现:
  • center 宽度设为 100%,实现自适应
  • center,left,right 都浮动,left,right 添加负值,让三个位于同一行
  • 父容器 container 添加左右内边距,为两侧留出空间
  • left,right 设置相对定位,移到两边
<div class="container">
  <div class="center fl">center</div>
  <div class="left fl">left</div>
  <div class="right fl">right</div>
</div>
.container {
  padding: 0 200px; // 为两侧提供空间
}
.fl {
  float: left
}
.center {
  width: 100%; // 占据 container 全部宽度
  height: 800px;
  background-color: cyan;
}
.left,
.right
{
  position: relative;
  width: 220px;
  height: 400px;
}
.left {
  margin-left: -100%; // 负值将left回到和center一行
  left: -220px; // 负值将left移到一边
  background-color: pink;
}
.right {
  margin-left: -220px;
  right: -200px;
  background-color: brown;
}

  • 缺点:
  • left 相对定位仍然会占据 center 空间,如果 center 宽度小于 left,left 会掉到下一行
  • 其中一列内容过长,其他两列的背景不会自动填充

双飞翼布局

  • 特点:相比于圣杯布局,多了一层结构 实现:
<div class="container">
  <div class="center fl">
    <div class="content"></div>
  </div>
  <div class="left fl">
  <div class="right fl"></div>
</div>
.container {
  min-width: 660px; // 最小宽度包装中间内容能够显示出来,两倍left宽+right宽
}
.fl {
  float: left;
}
.center {
  width: 100%;
  height500px;
  background-color: cyan;
}
.content {
  margin: 0 220px; // 创建外边距,给leftright空间
}
.left,
.right {
  width: 220px;
  height: 400px;
}
.left {
  margin-left: -100%;
  background-color: pink;
}
.right {
  margin-right: -220px;
  background-color: brown;
}

两种布局比较

相同点都是实现将重要部分先渲染的效果,不同点在于双飞翼布局解决了圣杯布局左侧可能会掉下来的问题,但多了一层 dom 节点。

实现多列等高布局

  • 特点:子元素在父元素中高度相等的布局方式,实现方案如下:
正padding与负margin相冲
  • 实现: 将圣杯布局的基础上,给子元素增加大数值的正 padding-bottom 和负 margin-bottom,在父元素上设置溢出裁切
.center,
.left,
.right {
  padding-bottom: 9999px;
  margin-bottom: -9999px;
}
.container {
  overflow: hidden;
}

  • 优点:
  • 解决圣杯布局其中一列内容过长,其他两列的背景不会自动填充的问题
  • 结构简单,兼容性强
  • 缺点:溢出部分会被裁切

利用背景图片

  • 实现:用图片在垂直方向上平铺
  • 优点:方法简单,兼容性强
  • 缺点:不适合流体布局

利用border

  • 实现:左侧添加宽度等于右侧的边框,右侧添加值等于左侧宽度的 margin-left

有了解过哪些种类图片

种类体积特点场景
BMP较大无损普通图片
GIF较小支持动画和透明动态图片
JPEG比GIF大丰富色彩相片
PNG-8比GIF小不支持动画,可透明非动态图片
PNG-24极小压缩非动态图片
SVG较大缩放不失真Logo、Icon
WebP极小兼容性差普通图片
base64较大字符串编码不发http请求

样式优化有哪些

1.加载性能:

  • css 压缩,减少体积
  • 减少使用 @import,它导入的样式需要页面加载完毕后才加载,推荐使用 link
  1. 选择器性能
  • 不使用通配符选择器,消耗性能
  • 选好关键选择器,减少层级
  • ID 作为关键选择器,不需要在左边添加额外的层级
  • 用类选择器代替元素选择器
  1. 渲染性能:
  • 减少使用 浮动、定位
  • 去除控规则
  • 使用雪碧图减少请求次数
  • 继承属性不要重复指定
  • 选择器嵌套不要超过三层
  1. 样式抽离
  • 将相同属性的样式抽离,整合到同一个 class 中,提高维护性
  • 样式与结构分离,采用外部引入

说一下回流和重绘

回流:对 DOM 结构的修改从而引发 DOM 几何尺寸变化的时候,会发生回流的过程。

过程:由于DOM的结构发生了改变,所以需要从生成DOM这一步开始,重新经过样式计算、生成布局树、建立图层树、再到生成绘制
列表以及之后的显示器显示这整一个渲染过程走一遍,开销是非常大的。

重绘:当 DOM 的修改导致了样式的变化,并且没有影响几何属性的时候,会导致重绘。

过程:由于没有导致 DOM 几何属性的变化,因此元素的位置信息不需要更新,所以当发生重绘的时候,会跳过生存布局树和建立图层树
的阶段,直接到生成绘制列表,然后继续进行分块、生成位图等后面一系列操作。