阅读 1834
【面试准备】CSS篇

【面试准备】CSS篇

CSS 面试篇中所涉及的有布局、浮动、定位、布局、小程序和部分优化问题

MIND

css mind

基础

介绍一下css盒模型

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

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

选择器怎么解析的

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

选择器优先级

  • @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重叠主要有四种情况:

  • 相邻兄弟元素 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),并将元素设为块级元素
  • 使用图片,既不影响兼容也不影响美观

布局

实现两栏布局

特点:两侧自适应

<div class="container">
  <div class="left">left</div>
  <div class="right">right</div>
</div>
复制代码

浮动加BFC

实现:BFC 或 ZOOM:1 清除 right 浮动,right 不会重叠

.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 节点

两种布局比较

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

实现多列等高布局

特点:子元素在父元素中高度相等的布局方式,实现方案如下:

正padding与负margin相冲

实现: 将圣杯布局的基础上,给子元素增加大数值的正 padding-bottom 和负 margin-bottom,在父元素上设置溢出裁切。

.center,
.left,
.right {
  padding-bottom: 9999px;
  margin-bottom: -9999px;
}
.container {
  overflow: hidden;
}
复制代码

优点:

  • 解决圣杯布局其中一列内容过长,其他两列的背景不会自动填充的问题
  • 结构简单,兼容性强

缺点:溢出部分会被裁切

利用背景图片

实现:用图片在垂直方向上平铺

优点:方法简单,兼容性强

缺点:不适合流体布局

利用border

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

移动端

移动端固定定位失效怎么处理

在移动端下,固定定位是根据移动端设置的 viewport 顶点定位的,默认 viewport 为 layoutviewport,它的宽度大于移动端屏幕的宽度,页面会出现滚动条,当出现滚动的时候,会出现固定失效的情况,可以通过将 viewport 设为 idealviewport

<meta name="viewport" content="width=device-width,initial-scale=1.0,
   maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"/>
复制代码

设备像素、css像素、设备独立像素、dpr、ppi 有了解过吗

  • 设备像素指的是设备的物理像素,一般等于屏幕的分辨率,且不可变;
  • css 像素是相对像素,大小取决于屏幕的缩放和 dpr 的大小。
  • 设备独立像素与 css 像素是等价的。
  • dpr 是像素比,一般设备的 dpr 是 1,苹果推出的 retina 屏幕的 dpr 为 2
  • ppi 是每英寸的物理像素的密度,当前手机 ppi 最高可达到 1000 以上

移动端布局

媒体查询

  • 原理:根据页面的特定宽度来定义特殊的 css 规则;
@media (max-width: 768px) {
  /* css */
}
复制代码
  • 优点:根据不同宽度能够独特定制
  • 缺点:需要多套方案,比较繁琐

rem 布局

  • 原理:rem 是一个相对于根元素 fontSize 大小的相对单位
html {
font-size: 14px;
}
p {
  padding-top: .5rem;
}
复制代码
  • 优点:兼容性好,代码简介
  • 缺点:在奇葩 dpr 设备上表现不好;iframe 引用会出问题

vw + vh

  • 原理:设定 viewport 的大小
<meta name="viewport" content="width=750">
复制代码
  • 优点:和 rem 一样,且不用转换 rem
  • 缺点:效果没 rem 好,图片相对模糊,无法使用 @media 进行断点

移动端 1px 怎么实现

在高清屏下,dpr > 1,需要实现 1px,就需要实现 0.5px 或者 0.33px等等

1. border
  • 原理:通过 dpr 获取宽度大小
border: 0.5px solid #000;
复制代码
  • 优点:简单,无副作用
  • 缺点:dpr 在 3 以上无法显示,安卓不太支持
2. border-image
  • 原理:图片不存在 dpr 影响问题
border: 1px solid transparent;
border-image: url('./../../image/96.jpg') 2 repeat;
复制代码
  • 优点:无副作用
  • 缺点:变换颜色需要重新设置图片;圆角会模糊
3. 媒体查询配合伪元素
  • 原理:伪元素设置绝对定位,和父元素左上角对齐,宽度 100%,height 1px,然后媒体查询设置 Y 方向缩小
.one-px {
  position: relative;
  &::after {
    position: absolute;
    content: '';
    display: block;
    background: #000;
    left: 0;
    top: 0;
    width: 100%;
    height: 1px;
  }
}
@media screen and (-webkit-min-device-pixel-ratio: 2){
  .one-px::after{
    transform:scaleY(0.5);
  }
}
@media screen and (-webkit-min-device-pixel-ratio: 3){
  .one-px::after{
    transform:scaleY(0.33333);
  }
}
复制代码
  • 优点:兼容性好
  • 缺点:伪元素可能影响后期的清除浮动
4. viewport + rem + js
  • 原理:通过 js 获取 dpr 来动态设置 viewport
var viewport = document.querySelector("meta[name=viewport]");
  //下面是根据设备像素设置viewport
  if (window.devicePixelRatio == 1) {
    viewport.setAttribute('content', 'width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no');
  }
  if (window.devicePixelRatio == 2) {
    viewport.setAttribute('content', 'width=device-width,initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no');
  }
  if (window.devicePixelRatio == 3) {
    viewport.setAttribute('content', 'width=device-width,initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no');
  }
  var docEl = document.documentElement;
  var fontsize = 10 * (docEl.clientWidth / 320) + 'px';
  docEl.style.fontSize = fontsize;
复制代码
  • 优点:兼容性好,使用方便
  • 缺点:适合新项目,不适合老项目

优化

有了解过哪些种类图片

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

选择合适的图片,能够降低浏览器渲染压力

样式优化有哪些

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