自适应布局中的 rem 是什么原理?

rem(root em)是css中一种相对长度单位,其核心原理是相对于跟元素(html)的字体大小进行缩放。

核心原理

rem的基准是根元素HTML的font-size属性:

1
2
3
html{
font-size:16px;
}

动态计算

所有使用rem的元素尺寸都会根据字体大小动态计算:

1
2
3
.demo{
width:10rem; // 160px
}

自适应关键

通过JS或媒体查询动态修改根字体大小,页面所有rem单位元素都会等比例缩放:

1
2
3
//根据视口宽度动态设置根元素字体大小
document.documentElement.style.fontSize =
window.innerWidth /100 + 'px'

工作流程

1. 设计稿基准

假设设计稿宽度750px,约定1rem = 设计稿100px

2. 设计根字体

1
2
3
// 视口宽度375px的设备上:
const rootFontSize = window.innerWidth / 7.5; // 375/7.5=50px
document.documentElement.style.fontSize = rootFontSize + 'px';

3. 元素尺寸转换

1
2
3
4
/* 设计稿中200px宽的元素 */
.element {
width: 2rem; /* 2 × 50px = 100px(375px屏上等比缩放) */
}

4. 不同屏幕效果

设备宽度 跟字体大小 元素实际宽度
375px 50px 2X50=100px

对比其他单位

单位 基准 自适应能力 缺点
rem 根元素字体大小 🌟🌟🌟🌟🌟 需要动态计算根字体
em 父元素字体大小 🌟🌟 嵌套层级影响计算
px 固定像素 无法自适应
vw 视口宽度的1% 🌟🌟🌟🌟 小屏幕显示内容可能过小
% 父元素尺寸的百分比 🌟🌟🌟 依赖父级容器

对于CSS中盒模型的理解

盒模型是CSS布局中的核心概念,它描述了HTML元素在页面所占空间结构。每个元素都被视作一个矩形盒子。这个盒子包含以下四个部分:

  1. 内容区(content):
    • 最内层区域,包含元素的实际内容(如文本、图片等)。
    • 大小由widthheight属性控制。
  2. 内边距(padding):
    • 位于内容区和边框之间的透明区域。
    • 控制内容与边框之间的距离。
    • 大小由padding及其相关属性(padding-leftpadding-rightpadding-toppadding-bottom)控制。
  3. 边框(border):
    • 包裹内容和内边距的
    • 可以设置颜色,粗细,样式。
    • 大小由border相关属性控制
  4. 外边距(margin):
    • 位于边框之外的透明区域。
    • 控制当前元素与其他元素之间的距离。
    • 大小由margin相关属性控制。

关键点:

  • 总高度/宽度计算:
    • 总宽度 = width + 左(paddingmarginborder)+ 右(paddingmarginborder
    • 总高度 = height + 上(paddingmarginborder)+ 下(paddingmarginborder
  • box
  • box-sizing属性:这个属性决定了widthheight属性具体定义的是哪一部分的尺寸。这里是理解盒模型的关键差异点:
    • content-box:默认(标准)盒模型:
      • widthheight只定义内容区的尺寸。
      • 元素的总宽度/高度需要加上paddingbordermargin
    • border-box常用(IE怪异/现代推荐)盒模型:
      • widthheight定义了 内容区 + 内边距 + 边框 的总尺寸。
      • 元素的总宽度/高度 = width/height + margin。 padding 和 border 的宽度被包含在设定的 width/height 值内。
      • 这使得布局计算更直观,是现在最常用的设置(通常用 * { box-sizing: border-box; } 全局设置)。
  • 外边距折叠(Margin Collapsing): 垂直方向上相邻的两个块级元素的外边距有时会合并(折叠)成一个外边距,其大小等于两个外边距中的较大者。

总结:
盒模型是理解元素尺寸、间距和布局的基础。掌握内容区、内边距、边框、外边距的定义,以及 box-sizing 属性(尤其是 border-box)对元素最终尺寸的影响,对于精确控制页面布局至关重要。外边距折叠是另一个需要注意的特性,特别是在垂直布局时。

什么是变量提升?varletconst有什么区别?

  • var:声明被提升到顶部,初始值为undefined.
    1
    2
    console.log(e) //undefined
    var e = 1;
  • letconst存在暂时性死区,在声明前访问会报错。
    1
    2
    console.log(e) // RefrenceError
    let e = 10;

如何确定this指向

  1. 普通函数:this指向调用者。
  2. 箭头函数:this继承外部作用域。
  3. 显示绑定:callapplybind
    1
    2
    3
    const obj = { name: "Alice" };
    function greet() { console.log(this.name); }
    greet.call(obj); // "Alice"

解释事件循环、宏任务与微任务。

  • 调用栈:同步代码执行。
  • 任务队列:
    • 宏任务:setTimeoutsetintervalI/O
    • 微任务:Promise.thenMutationObserverqueueMicrotask
    • 执行顺序:同步代码 → 微任务队列清空 → 宏任务。

Promise 如何解决回调地狱?async/await 的作用?

  • Promise链式调用
    1
    2
    3
    4
    fetch(url)
    .then(res => res.json())
    .then(data => console.log(data))
    .catch(err => console.error(err));
  • async/await以同步的方式写异步代码。
    1
    2
    3
    4
    5
    6
    7
    8
    async function getData(){
    try {
    const res = await fetch(url);
    const data = await res.json();
    } catch (err) {
    console.error(err);
    }
    }

列举常用的 ES6 特性。

  • let/const、箭头函数、解构赋值。
  • 模板字符串、默认参数、Rest/Spread 运算符。
  • 模块化(import/export)、类(class)、Map/Set。

防抖和截流区别是什么?如何实现?

  • 防抖:连续触发时,只执行最后一次。
    1
    2
    3
    4
    5
    6
    7
    function debounce(fn, delay) {
    let timer;
    return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
    };
    }
  • 节流:固定时间间隔执行一次(如滚动事件)。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function throttle(fn, interval) {
    let lastTime = 0;
    return (...args) => {
    const now = Date.now();
    if (now - lastTime >= interval) {
    fn(...args);
    lastTime = now;
    }
    };
    }

如何解决跨域问题

  1. CORS:服务器设置响应头(Access-Control-Allow-Origin)。
  2. JSONP:通过 <script> 标签跨域(仅 GET 请求)。
  3. 代理服务器:前端请求同域代理,代理转发请求。
  4. WebSocket:不受同源策略限制。