也及夜間模式樣式

来源:https://www.cnblogs.com/mylibs/archive/2022/12/20/dark-mode-css.html
-Advertisement-
Play Games

“像白天不懂夜的黑,像永恆燃燒的太陽,不懂那月亮的盈缺。” —— 黃桂蘭 0x00 大綱 0x01 前言 夜間模式(Dark Mode),也被稱為黑暗模式或深色模式,是一種高對比度,或者反色模式的顯示模式,這種模式現在越來越流行,因為和傳統的白底黑字相比,這種黑底白字的模式通常被認為可以緩解眼疲勞, ...


“像白天不懂夜的黑,像永恆燃燒的太陽,不懂那月亮的盈缺。” —— 黃桂蘭

0x00 大綱

目錄

0x01 前言

夜間模式(Dark Mode),也被稱為黑暗模式或深色模式,是一種高對比度,或者反色模式的顯示模式,這種模式現在越來越流行,因為和傳統的白底黑字相比,這種黑底白字的模式通常被認為可以緩解眼疲勞,更易於閱讀。通過降低屏幕整體的亮度和使用暗色系的顏色,從而減小對眼睛的刺激。需要註意的是,夜間模式雖然能緩解視覺疲勞但並不能保護你的視力——該近視的還是會近視,該失眠的還是會失眠。

無論是 APP 還是網頁,它們的實現原理都是相同的,本質上都是顏色和樣式的替換,也就是主題的替換。下麵主要以網頁的夜間模式為例進行討論。

通常一個網頁的上的元素都有各自的顏色,例如文字的顏色,背景色,按鈕和邊框的顏色都有自己的單元設計,共同組合構成了一個整體的主題(配色方案)。一個網站可以包含相當多的 CSS, CSS 文件中的許多值都是重覆數據,更改這些顏色可能很困難且容易出錯,因為它(大概率)會分散在多個 CSS 文件中,並且可能不接受查找和替換。這將會變成開發人員的一個沉重負擔,即使是 Ctrl+C,Ctrl+V 。

0x02 CSS 自定義屬性

好在 CSS 規範裡面有自定義屬性(custom properties)的存在,它包含的值可以在整個文檔中重覆使用。通過自定義屬性與var()函數的結合,可以達到一次更改,處處生效的效果。

通常的最佳實踐是定義在根偽類:root下,這樣就可以在 HTML 文檔的任何地方訪問到它了。聲明一個自定義屬性,屬性名需要以兩個減號(--)開始,屬性值則可以是任何有效的 CSS 值。

0x03 主題定義

首先以 CSS 自定義屬性的方式定義一套主題顏色作為我們的起點。

<!DOCTYPE html>
<html mode="light">
<head>
    <meta charset="utf-8">
    <style>
        :root[mode="light"] {
            --bg-color: #ffffff;
            --text-color: #596172;
            --border-color: #efafc7;
        }
        div {
            background-color: var(--bg-color);
            color: var(--text-color);
            border: 4px solid var(--border-color);
            width: 200px;
            height: 200px;
        }
    </style>
</head>
<body>
    <div>Light or Dark.</div>
</body>
</html>

運行之後,應該得到這樣的效果:

主題-正常

註意

如果你沒有看到主題顏色生效,很可能是因為你的瀏覽器不支持 CSS 自定義屬性,請更換現代瀏覽器或者點擊這裡查看更多關於相容性的信息。

0x04 夜間模式

我們在上面的主題基礎上,增加一套夜間模式的樣式定義,同時增加一個按鈕,用來切換我們的主題樣式:

<!DOCTYPE html>
<html mode="light">
<head>
    <meta charset="utf-8">
    <style>
        :root[mode="light"] {
            --bg-color: #ffffff;
            --text-color: #596172;
            --border-color: #efafc7;
        }
        :root[mode="dark"] {
            --bg-color: #202020;
            --text-color: #d8d8d8;
            --border-color: #d15900;
        }
        div {
            background-color: var(--bg-color);
            color: var(--text-color);
            border: 4px solid var(--border-color);
            width: 200px;
            height: 200px;
        }
    </style>
    <script>
        function sw() {
            var map = {'dark': 'light', 'light': 'dark'};
            var current = document.querySelector('html').getAttribute('mode');
            document.querySelector('html').setAttribute('mode', map[current]);
        }
    </script>
</head>
<body>
    <div>Light Mode for Light.</div>
    <button onclick="sw()">切換</button>
</body>
</html>

點擊按鈕,應該能看到切換後的效果:

主題-夜間

這隻是一個簡單的示例,事實上,你可以細化和定義任何你想要的顏色,甚至是 SVG 等矢量圖元的顏色。

0x05 圖片的處理

一張白底黑字的圖片,在晚上看起來,就像是在直視一盞臺燈。通過 CSS 自定義屬性,我們已經完成了對各種頁面元素顏色的控制和改變,但是對於顏色既定的圖片(自帶背景色的圖片)來說,似乎就不怎麼行得通了。既然預處理行不通,就要求助於後處理了,沒錯,說的就是濾鏡(filter)。好在,濾鏡也是可以通過 CSS 自定義屬性定義的。

<!DOCTYPE html>
<html mode="dark">
<head>
    <meta charset="utf-8">
    <style>
        div[mode="light"] {
            --img-filter: brightness(1.0);
        }
        div[mode="dark"] {
            --img-filter: brightness(.7);
        }
        img {
            filter: var(--img-filter);
        }
    </style>
</head>
<body>
    <div style="display: inline-block;" mode="light">
        <img src="sun.jpg">
    </div>
    <div style="display: inline-block;" mode="dark">
        <img src="sun.jpg">
    </div>
</body>
</html>

運行後的效果如下,左邊是原圖,對應我們的正常模式,右邊是濾鏡處理後的圖片,對應我們的夜間模式:

主題-圖片

可以看到圖片的整體亮度被降低,亮部不再顯得那麼刺眼,暗部則變得更暗。我們達到所需要的效果,但同時需要註意,它降低的是圖片中所有顏色分量的亮度,因此,如果濾鏡參數調得太低,將會導致原圖中部分細節的丟失或者使其上面的文字變得難易閱讀(這裡要吐槽下知乎的夜間模式)。個人建議的設置是保留70%~90%的亮度水平。

0x06 最後的拼圖

我們在上文處理了夜間模式的文字和圖片等文檔元素,但這樣真的完美了嗎?事實上並不。在圖片的處理中我們提到,可以通過降低圖片的整體亮度來進行柔化處理,使其在夜間顯得沒那麼刺眼。這種處理暗含一個條件就是,原始圖片的前景和背景本身是相對融洽的。

考慮有這樣一張圖片,它的內容是黑色的,背景是透明的。當它在背景色為白色的頁面上顯示,似乎效果很好。但當我們切換到夜間模式,此時頁面背景色變為黑色系,這張圖片顯然已經難以看清,極端情況下,當頁面的背景色和圖片的前景色相同時,這張圖片就像憑空消失了一樣。譬如下圖的二維碼:

transparent-img

解決這個問題的方法有很多,但我暫時沒有想到一個通用且完美的辦法:

  • 設置兩套不同的圖片(成本巨大)
  • 不使用透明的圖片(某些情況下不現實)
  • 特殊問題特殊處理,給透明圖片賦予與全局背景色不同的背景顏色(適用於透明圖片不多的情況)

在探索這個問題的途中,倒是發現了另一種有趣的處理方法:

<!DOCTYPE html>
<html mode="dark">
<head>
    <meta charset="utf-8">
    <style>
        div[mode="light"] {
            --bg-color: #ffffff;
            --img-filter: brightness(1.0);
        }
        div[mode="dark"] {
            --bg-color: #090909;
            --img-filter: brightness(.7);
        }
        div {
            background-color: var(--bg-color);
        }
        img {
            filter: var(--img-filter);
        }
        .special {
            filter: var(--img-filter) invert(1);
        }
    </style>
</head>
<body>
    <div style="display: inline-block;" mode="light">
        <img src="qr.png">
    </div>
    <div style="display: inline-block;" mode="dark">
        <img src="qr.png">
    </div>
    <div style="display: inline-block;" mode="dark">
        <img src="qr.png" class="special">
    </div>
</body>
</html>

這個方法適用於黑白圖片或者內容與顏色無強關聯的圖片,運行上面的代碼,我們會得到這樣的效果:

inverted-img

最右邊的圖片使用了完全翻轉濾鏡,也就是將黑的變白了,白的變黑了。這樣在白色背景下,我們看到的是正常的二維碼,在黑色背景下,看到的是反轉後的二維碼,並且還不會影響掃碼。

0x07 小結

我們通過 CSS 自定義屬性和濾鏡等特性完成了對夜間模式樣式的處理和優化,但是仍要註意在特定的場景下,會有混色的問題出現。如果混色的問題,最好的辦法還是特殊問題特殊處理,根據實際情況修改源圖或者使用翻轉濾鏡。暫時沒有完美的解決方案,期待隨著技術的發展,後續的 CSS 新特性能帶來新的工具和驚喜。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 查看當做操作目錄位置 > pwd2. 查看(當前)目錄裡邊的文件內容 > ls //list > ls -l 或ll //顯示文件的詳細信息 > ls -al //all顯示文件的詳細信息(包括隱藏文件) > ls -a //顯示目錄全部文件名字(包括隱藏文件) > ls [-al] 目錄 / ...
  • “數據湖”、“湖倉一體”及“流批一體”等概念,是近年來大數據領域熱度最高的辭彙,在各大互聯網公司掀起了一波波的熱潮,各家公司紛紛推出了自己的技術方案,其中作為全鏈路數字化技術與服務提供商的袋鼠雲,在探索數據湖架構的早期,就調研並選用了Iceberg作為基礎框架,在落地過程中深度使用了Iceberg並 ...
  • 摘要:openGemini的設計和優化都是根據時序數據特點而來,在面對海量運維監控數據處理需求時,openGemini顯然更加有針對性。 IT運維誕生於最早的信息化時代。在信息化時代,企業的信息化系統,主要為了滿足企業內部管理的需求。通常是集中、可控和固化的煙囪式架構。傳統IT運維,以人力運維為主, ...
  • 說說幾種薅免費伺服器羊毛的方法吧 經過我多年的薅羊毛經驗,總結得知,編程只需要: Terminal + VPS主機 + 網路 為了達到這些目的,肯定需要Vim搭建IDE,安裝環境等等操作 當時記得使用的是ChromeOS的筆記本,所有的應用都是在Chrome瀏覽器當中的,續航時間長,又輕薄屬實快得飛 ...
  • 主要闡述InnoDB存儲引擎(MySQL5以後的預設引擎)。 資料庫中最基本的組成結構是數據表,視覺上的表和其對應的磁碟結構如下: 此圖參考了廈門大學課堂:MySQL原理 。但是視頻中一些更多細節沒有涉及,比如Leaf node segment和Non-leaf node segment其實就是葉子 ...
  • 在先前舉辦的華為開發者大會2022(HDC)上,華為通過3D數字溪村展示了自有3D引擎“HMS Core 3D Engine”(以下簡稱3D Engine)的強大能力。作為一款高性能、高畫質、高擴展性的3D引擎,3D Engine不僅能通過實時光追、水體渲染、體積雲霧、多維GPU粒子系統等技術還原真 ...
  • 好家伙,本篇為《JS高級程式設計》第八章“對象、類與面向對象編程”學習筆記 1.關於對象 ECMA-262將對象定義為一組屬性的無序集合。嚴格來說,這意味著對象就是一組沒有特定順序的值。 對象的每個屬性或方法都由一個名稱來標識,這個名稱映射到一個值。正因為如此(以及其他還未討論的原因),可以把 EC ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 不想看繁瑣步驟的,可以直接去github下載項目,如果可以順便來個star哈哈 本項目使用vue-cli創建,但不影響使用,主要繪製都已封裝成類 1、使用geoJson繪製3d地圖 1.1 創建場景相關 // 創建webGL渲染器 thi ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...