前端开发卡壳了,这些CSS与浏览器的神操作能破局吗?

2,893字
12–18 分钟
in

最近前端圈子里又冒出来一堆让人眼前一亮的骚操作,从视频状态跨页面无损传承,到给媒体查询起外号,再到浏览器内核那些不为人知的小秘密,看完直呼好家伙。这些东西要是能玩明白,开发效率不得原地起飞?

目录

视频状态跨页

在网页间穿梭的时候,最烦人的就是视频播放到一半,啪一下切个页面,进度直接归零。这不,有老铁研究出利用CSS视图转场配合浏览器事件,让视频状态在不同页面间丝滑流转。

捕获播放瞬间

想要实现这波操作,得先摸清两个关键事件:pageswappagerevealpageswap在页面切换前触发,是保存当前视频状态的黄金时间点;pagereveal在新页面加载前触发,刚好用来恢复之前的状态。

具体咋整呢?监听pageswap事件,把视频当前播放时间、是否静音、播放速率这些数据扒拉出来,塞进sessionStorage里。这玩意儿得存成JSON字符串,不然浏览器不认。

window.addEventListener('pageswap', () => {
  const video = document.querySelector('video');
  const videoState = {
    currentTime: video.currentTime,
    muted: video.muted,
    playbackRate: video.playbackRate,
    paused: video.paused
  };
  sessionStorage.setItem('videoState', JSON.stringify(videoState));
});

这里有个小坑,pageswap触发的时候页面还没完全卸载,这时候拿到的DOM元素还是热乎的,麻溜儿存起来就完事。

还原播放现场

新页面登场之前,pagereveal事件会悄悄冒头。这时候赶紧从sessionStorage里把存好的状态掏出来,解析成JavaScript对象,然后一股脑怼到新页面的视频元素上。

window.addEventListener('pagereveal', () => {
  const savedState = sessionStorage.getItem('videoState');
  if (savedState) {
    const video = document.querySelector('video');
    const state = JSON.parse(savedState);
    video.currentTime = state.currentTime;
    video.muted = state.muted;
    video.playbackRate = state.playbackRate;
    if (!state.paused) {
      video.play();
    }
  }
});

这招不仅对视频管用,音频和iframe也能照葫芦画瓢。不过得留个心眼,视频恢复播放的时候可能会有那么一丢丢音频卡顿,毕竟这是在演戏给浏览器看,技术上算是造假,但效果已经够爽歪歪了。

媒体查询命名

CSS媒体查询写多了就容易乱套,满屏的(max-width: 768px)看得脑壳疼。有大佬灵机一动,用CSS层叠层给这些媒体查询起了个名儿,代码瞬间清爽多了。

层叠层命名法

先把所有媒体查询扔到一个叫@layer的层里,然后给这个层起个响亮的名号。比如搞个responsive层,里面专门放各种断点。

@layer responsive {
  @media (width < 768px) {
    .container {
      padding: 1rem;
    }
  }

  @media (width >= 768px) {
    .container {
      padding: 2rem;
    }
  }
}

这样一来,调用的时候直接指名道姓,告诉浏览器“爷要用responsive层里的样式”。虽然这招比不上原生支持的@custom-media那么溜,但胜在兼容性贼好,现在就能用。

兜底方案

@custom-media这玩意儿目前还在Firefox Nightly里试验,想在生产环境用还得等一等。在这之前,层叠层命名法就是最靓的仔。要是哪天浏览器全面支持了自定义媒体查询,直接替换掉就完事,改造成本低得感人。

布局工作原理

浏览器到底咋把一堆标签代码变成花花绿绿的页面,这里头门道可深了。从拿到IP地址到最终像素绘制,中间经过了一整套流水线作业。

解析渲染流水线

浏览器拿到HTML代码后,第一件事就是解析成DOM树,同时解析CSS生成样式规则。这俩玩意儿合并成渲染树,然后计算每个元素的位置和大小,也就是布局阶段。最后一步才是绘制,把像素怼到屏幕上。

这个过程中有几个关键角色:DOM树记录结构,CSSOM树记录样式,渲染树只保留可见元素,布局树记录几何信息。任何一个环节卡壳,页面都得转圈圈。

布局系统三件套

CSS布局的核心是盒子模型、定位方案和堆叠上下文。盒子模型决定元素占多大地方,定位方案决定元素站哪儿,堆叠上下文决定谁压着谁。

核心概念作用常见场景
盒子模型定义尺寸与边距普通文档流
定位方案控制元素位置浮动、绝对定位
堆叠上下文管理层叠顺序z-index、transform

网格布局和弹性盒是新时代的布局神器。网格解决二维排列,弹性盒解决一维对齐。这俩配合使用,能搞定99%的页面布局需求,剩下那1%等CSS砌体布局出来再说。

模态框页面抉择

弹窗和页面之间选哪个,这事儿经常让前端小伙伴纠结得头秃。是搞个模态框怼脸上,还是新建页面完事,得看具体情况。

决策框架

按交互复杂度来分,简单确认信息用alertdialog就够了;需要用户填写一堆表单的,乖乖开个新页面;介于两者之间的,可以用模态框。

popover和兴趣调用器这些新特性让模态框玩法更多样,但同时也让选择变得更复杂。有个简单粗暴的判断标准:如果用户需要频繁切换上下文,用模态框;如果是个独立完整的功能,开新页面。

交互类型推荐方案适用场景
轻提示tooltip简短说明
确认操作dialog删除确认
复杂表单新页面用户注册
展示详情modal图片大图

实操避坑

用模态框的时候,焦点管理是个烫手山芋。打开模态框的时候,焦点得自动跳到框里;关闭的时候,焦点得回到原来的位置。这俩要是没处理好,键盘用户直接原地爆炸。

inert属性是个好东西,能给模态框外的元素加个屏障,让它们无法被交互。配合焦点管理一起用,体验直接拉满。

文本缩放适配

操作系统里调了字体大小,网页居然纹丝不动,这事儿搁谁身上都得懵。现在Chrome Canary开始试验一个meta标签,能让网页乖乖听系统的话。

新标签配置

在HTML的<head>里塞一行代码,浏览器就会根据系统设置的文本缩放比例自动调整页面字体。

<meta name="text-scale" content="scale">

就这么简单粗暴。不过得注意,这玩意儿目前还在试验阶段,别急着往生产环境怼。等各大浏览器都支持了,网页无障碍体验能上一个台阶。

测试与回退

想尝鲜可以装个Chrome Canary,在设置里把“Experimental Web Platform features”打开,然后在页面上试试系统字体缩放功能。万一浏览器不认这个标签,啥影响都没有,页面该咋样还咋样,完美回退。