原先这个网站的代码高亮主题是默认暗色的,但是考虑到网站本身已经支持了跟随系统主题自动切换,所以为了保持统一,准备将代码高亮主题跟系统主题自动同步。

一开始我想的还是传统的方式,比如通过添加类,或是在css中添加media查询来实现。后来让AI去实现这个功能时,发现了一个更简单的方式,直接在<link />标签中添加media属性,利用prefers-color-scheme媒体查询在不同的系统主题下加载不同的样式。

<link rel="stylesheet" href="https://unpkg.com/prismjs@1.29.0/themes/prism.css" media="(prefers-color-scheme: light)">
<link rel="stylesheet" href="https://unpkg.com/prismjs@1.29.0/themes/prism-okaidia.css" media="(prefers-color-scheme: dark)">

分析了下这个方案,发现了一些有趣的细节。

  • 当页面为亮色主题时,会同时下载prism.cssprism-okaidia.css,但是没有命中的media(暗色主题)不会参与渲染(也就不会阻塞渲染)。

  • 虽然两个主题文件都会下载,但是它们的优先级不一样,比如当页面为亮色主题时,prism.cssprism-okaidia.css的优先级高。

  • 如果此时切换为系统或浏览器的主题为暗色,则prism-okaidia.css会命中media,就直接渲染了。

  • 如果是刷新页面(比如当前系统主题为暗色),两个主题文件会重新下载,但是由于浏览器的缓存机制,所以一般情况下不会重新请求。此时,prism-okaidia.css的优先级就比prism.css高了。 alt text