【前端面试复习】CSS

245 阅读9分钟

面试的时候 CSS 部分算是非常基础的知识,考察的也是我们日常开发时会用到的一些知识点,下面就简单的总结一下~~

CSS 盒模型

首先我们知道一个 div 由以下几部分组成(从外向内)

margin -> border -> padding -> content

即: 外边距 - 边框 - 内边距 - 内容

盒模型有两种:

  1. W3C 标准盒子模型 - 我们设置的宽高是 content 的宽高
  2. IE 盒子模型 - 设置的宽高是 content、padding、border 三部分合起来的宽高。

改变盒模型: 使用 box-sizing 设置 ( ie8+以及其他浏览器中盒模型默认值为 content-box )

box-sizing: content-box | border-box | inherit;
  • content-box - 标准盒模型
  • border-box - ie 盒子模型
  • inherit - 从父元素继承 box-sizing 属性的值

移动设备的 dpr

DPR(devicePixelRatio) 设备像素比,它是默认缩放为 100% 的情况下,设备像素和 CSS 像素的比值。

window.devicePixelRatio = 物理像素 / CSS像素

自适应布局

即响应式布局,而这种布局有什么特点呢?

  • 内容区域可伸缩
  • 内容区块可自由排布,当页面尺寸变动较大时,能够减少 / 增加排布的列数
  • 对于不同分辨率的屏幕,字体等也能同设计稿一样完美显示

Flex 布局

Flex 部分主要考察的的是 自适应布局以及一些属性的用法以及应用,之前我写过总结文章,这里就不多赘述啦~ 可以点击下面的链接去看。

🔗 Flex 布局

rem

在做移动端开发的时候各种奇怪的屏幕尺寸都有,所以前端需要对这些屏幕都做个自适应,所以传统的 px 单位就不太合适了。

这时就需要用到了 rem (和其他单位相比较的优缺点稍后讲):rem 是一个相对单位,1 rem 等于 html 元素上根字体设置的大小。我们只要设置 html 上 font-size 的大小,就可以改变 rem 所代表的大小。这样我们就有了一个可控的统一参考系。

所以我们有两个目的:

  1. rem 单位所代表的尺寸大小和屏幕宽度成正比,也就是设置 html 元素的 font-size 和屏幕宽度成正比
  2. rem 单位和 px 单位很容易进行换算,方便我们按照设计稿写 css

那么我们如何来计算 rem 呢?

这里有个公式:

rem = 元素的 px 单位值 / (设计稿页面宽度/10)
// 例如设计稿给出的页面宽度是 375px,那么 375/10 就是 html 页面的基准 font-size 值,即 37.5px
// 某 div 的宽度为 120px,换算成 rem 即为,120 / 37.5 = 3.2rem

webpack 打包集成 rem,使用 px2rem-loader

由于我们在开发时,如果在写样式文件时就写死 dom 的 rem,那么后期维护以及平时修改参数都比较麻烦,所以我们可以在打包项目时,使用 webpack 集成,自动将 px 转换成 rem,在样式文件中只需要写上设计稿上的具体 px 值就可以 px2rem

这里使用的是 px2rem-loader :

  1. 安装 px2rem-loader
  2. webpack config 修改如下
module.exports = {
  // ...
  module: {
    rules: [{
      test: /\.css$/,
      use: [{
        loader: 'style-loader'
      }, {
        loader: 'css-loader'
      }, {
        loader: 'px2rem-loader',
        options: {
          remUnit: 37.5 // 设计稿宽度/10
        }
      }]
    }]
  }
}

具体配置可戳官方 👉 px2rem-loader

px / rem / em / vh vw / 百分比 对比

名词定义优点缺点适用场景
px相对长度单位,相对于显示器屏幕分辨率显示设置字体大小及元素宽高等比较稳定和精确能适应浏览器缩放时产生的变化,因此一般不用于响应式网站固定网页宽高或无响应式要求的网页
em相对长度单位,相对于当前对象内文本的字体尺寸,如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸(一般为16px),所以 1em = 16px组件模块化计算复杂,计算不仅要考虑自身的大小,还要继承父元素的字体大小,父元素还可能继承其父元素大小等等。如果属性值根据元素的 font-size 获得,则使用 em,如padding\margin\line-height\width\height 等值(使字体大小变化时元素周围的间距会等比例缩放)
rem仍然是相对大小,但相对的只是 HTML 根元素可以做到避免字体大小逐层复合的连锁反应,计算简单,只需要设置根元素的字体大小即可使组件缺少模块化不可使用 em 的场景都可以使用 rem
vh vw视窗宽高度的百分比(1vw 代表视窗的宽度为 1%)直接设置可以取高度-适用于大框架拆分布局使用
百分比百分比是基于父元素的设置而言的,如果父元素为100px,那么子元素 100% 也就是100px-未设置 body 高度的情况下,无法正确获得可视区域的高度子元素相对父元素占据固定比例时

CSS 计算属性 - calc()

calc()是 CSS3 中新增的一个函数 (calculate) 。用于动态计算宽/高,我们可以使用 calc() 给元素的各个属性设置值 margin、border、padding、font-size 等,

要求:

  1. 使用 + - * / 进行四则运算;
  2. 可以使用 百分比、px、em、rem 等单位;
  3. 可以混合使用各种单位进行计算;
  4. 表达式中有 + 和 - 时,其前后必须要有空格,如 width: calc(12%+5em) 这种没有空格的写法是错误的;
  5. 表达式中有 * 和 / 时,其前后可以没有空格,但建议留有空格。

🌰:设置一个外边距为 10px,宽度相对父元素 100% 的元素:

width: calc(100% - (10 * 2)px);
margin: 10px;

移动端的 1px 问题

1px 的边框,在高清屏下,移动端的 1px 会很粗,直接表现就是不同的设备,有的设备的 1px 边框会很粗,有的是正常的。

问题起因

目前主流的屏幕 DPR=2 (iPhone 8),或者3 (iPhone 8 Plus)。

拿 2 倍屏来说,设备的物理像素要实现 1px,而 DPR = 2,所以 css 像素只能是 0.5px。一般设计稿是按照 750px来设计的,它上面的 1px 是以 750px 来参照的,而我们写 css 样式是以设备 375px 为参照的,所以我们应该写的0.5px就好了啊! 试过了就知道,iOS 8+ 系统支持,安卓系统不支持。

解决方式

有大佬写过比较全面的解决方式:

指路 1 👉

指路 2 👉

CSS 选择器及其优先级

种类:

  1. id选择器( #myid)
  2. 类选择器(.myclassname)
  3. 标签选择器(div, h1, p)
  4. 紧邻同胞选择器 h1 + p(选的是 h1 后紧跟的那个 p)
  5. 一般同胞选择器 h1 ~ p(选择所有跟在 h1 后的 p)
  6. 子选择器(ul > li)
  7. 后代选择器(li a)
  8. 通配符选择器( * )
  9. 属性选择器(a[rel = "external"])选择所有 rel 属性为 external 的 a 标签
  10. 伪类选择器(a:hover, li:nth-child)

优先级:

  1. 优先级就近原则,同权重情况下样式定义最近者为准;
  2. 载入样式以最后载入的定位为准。
  3. !important > 内联样式 > id > class > tag

CSS 伪元素 和 伪类

名词示例定义区别
伪元素::after
::before
::first-letter
::first-line
需要创建的通常不存在于文档中的元素伪元素用双冒号::表示
伪类:active
:hover
:last-child
用来选择那些不能够被普通选择器选择的文档之外的元素伪类用单冒号:表示

css 使元素不可见的方式

display = "none" 以及 HTML5新增的 hidden 属性

特点:

  1. 显隐切换时 dom 会从文档流中删除,从而引起问题 2。
  2. 切换显隐时会导致 reflow (回流) ,从而引起 repaint (重绘),当页面中 reflow 增多至一定程度时,会导致 cpu 使用率飙高。
  3. 隐藏后可以获取 dom,但无法进行交互。
  4. 其子孙元素即使重新设置display: block也无法显示
  5. 设置显隐切换时,可能会与 display: flex、display: grid 冲突。

visibility = "hidden"

特点:

  1. 显隐切换时 dom 依旧在文档流中,不会引起 reflow (回流)。
  2. visibility 属性可以被子元素继承 —— 父级元素设置了visibility: hidden,子元素仍可通过visibility: visible重新设置为可见。
  3. 隐藏后可获取 dom,但是无法响应 dom 事件

opacity = "0"

特点:

  1. 显隐切换时 dom 依旧在文档流中,不会引起 reflow (回流)。
  2. opacity 属性不可以被子元素继承 —— 父级元素设置了 opacity,那么子元素的最大透明度将无法超过父级,意味着,父级的 opacity 为 0.5,那么子级的 opacity 就算设置为1,其实际透明度也会是 0.5 * 1 = 0.5。若父级透明度为0,那么子级没有任何办法可以重新设置为可见。
  3. 隐藏后可获取 dom,可响应 dom 事件

设置 color = "transparent" 和 font-size = 0

特点:适用于纯文本的显示隐藏

css 的定位及区别

pisition定位方式说明
static-默认值,没有定位,元素出现在正常的流中(会忽略 top, bottom, left, right, z-index 声明)
absolute绝对定位不为元素预留空间,相对于最近的非 static 定位的祖先元素进行定位
fixed绝对定位不为元素预留空间,相对于浏览器窗口进行定位,元素的位置在屏幕滚动时不会改变
relative相对定位相对于其正常位置进行定位,该关键字下,元素先放置在未添加定位时的位置,
再在不改变页面布局的前提下调整元素位置,因此会在此元素未添加定位时所在位置留下空白
inherit-从父元素继承 position 属性的值

BFC

这个说的比较清楚 BFC