原来有个页面需求,就是在 iOS 上打开后,自动适应亮或者暗主题模式。因为不是前端选手,所以当时就按下不表,直至这两天又想起来。然后想到正好可以问一下被人传的神乎其神的 Cursor。于是有了下面的记录。
Q:在一个 iOS app 中,要实现生成一个本地 HTML 页面,使用 WebView 显示出来。据我所知,手机目前都有明亮、暗黑两种模式,为了保证用户体验,HTML 页面应该能自动检测当前处于那种模式,并将适当的适应性 CSS 应用到页面元素上(如页面背景以及文字的颜色),可以帮助写一个简单的示例页面吗?
A:当然可以。以下是一个简单的示例 HTML 页面,它能够自动适应系统的明亮/暗黑模式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>自适应主题示例</title> <style> /* 默认样式(明亮模式) */ :root { color-scheme: light dark; } body { margin: 0; padding: 16px; background-color: #ffffff; color: #000000; } .card { padding: 16px; margin: 16px 0; border-radius: 8px; background-color: #f0f0f0; border: 1px solid #e0e0e0; } /* 暗黑模式样式 */ @media (prefers-color-scheme: dark) { body { background-color: #000000; color: #ffffff; } .card { background-color: #1c1c1e; border-color: #2c2c2e; } a { color: #0a84ff; } } </style> </head> <body> <h1>自适应主题示例</h1> <div class="card"> <h2>示例卡片</h2> <p>这是一个示例卡片,用于展示明暗模式的自动切换效果。</p> <p>这里是一个 <a href="#">链接</a> 示例。</p> </div> <div class="card"> <h2>另一个卡片</h2> <p>当系统切换到暗黑模式时,页面会自动调整颜色方案。</p> </div> </body> </html> |
- 使用
color-scheme: light dark
告诉浏览器支持明暗两种模式。 - 使用
@media (prefers-color-scheme: dark)
媒体查询来检测系统的暗黑模式。 - 为明暗两种模式分别定义了不同的:
- 背景色
- 文字颜色
- 卡片背景色和边框颜色
- 链接颜色
- 使用了一些基本的样式来美化页面:
- 卡片式布局
- 圆角边框
- 适当的内外边距
当用户的系统在明暗模式之间切换时,页面会自动调整配色方案,无需刷新页面。
1 2 3 4 5 |
if let htmlPath = Bundle.main.path(forResource: "example", ofType: "html") { let url = URL(fileURLWithPath: htmlPath) let request = URLRequest(url: url) webView.load(request) } |
您可以根据需要调整颜色、字体大小等样式,使其更好地匹配您的应用设计。
Q:明白了。我之前一直以为是要用 JavaScript 自行动态调整,没想到是用响应式样式,谢谢你!
A:是的!使用 CSS 的 @media (prefers-color-scheme)
媒体查询是一个更优雅的解决方案。它不仅代码更简洁,而且响应更快,因为:
- 不需要运行 JavaScript 代码来检测和切换主题
- 系统切换主题时会自动响应,不需要监听事件
- 即使禁用了 JavaScript,主题切换依然可以工作
- 页面加载时就能直接应用正确的主题,不会出现闪烁
不过,如果您确实需要在 JavaScript 中检测当前主题(比如需要根据主题做一些其他处理),也可以使用:
1 2 3 4 5 6 7 8 9 10 11 12 |
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { // 当前是暗黑模式 } // 监听主题变化 window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => { if (event.matches) { // 切换到暗黑模式 } else { // 切换到明亮模式 } }); |
但在大多数情况下,仅使用 CSS 媒体查询就足够了!