如何根據用戶偏好在 Drupal 8(或 9)中在深色和淺色模式之間切換
已發表: 2020-09-15讓您的用戶可以根據自己的喜好自由定制他們的界面,這有多棒? 雖然許多用戶喜歡淺色界面(淺色背景和深色文字),但一些用戶選擇深色界面(深色背景和淺色文字)。 較暗的界面被認為是很酷和時尚的,而有些人還認為它可以減輕眼睛的壓力,尤其是對於在屏幕前花費大量時間的開發人員。 我相信為您的用戶提供一個選項在可訪問性和用戶體驗方面是一個巨大的勝利。 有幾種方法可以實現這一點。 在本文中,我們將討論如何在深色/淺色網頁設計模式之間切換,並在 Drupal 8 或 Drupal 9 中實現這一點。

我們將專注於兩種方法來實現這一點 -
1. 僅使用 CSS。
2.實現CSS & JS切換開關
僅使用 CSS
要在任何僅使用 CSS 的網站上實現暗模式,必須牢記一些系統要求。 其中一項重要要求是系統範圍的暗模式。 如果用戶更喜歡在他的 PC 上使用深色模式,那麼該用戶將獲得一個網站,該網站顯示帶有淺色文本的深色背景。 首選顏色方案(媒體查詢)用於識別用戶是否已請求系統使用淺色或深色主題。
執行:
1. 聲明 CSS 變量。
2. 在需要的地方使用變量。
結果:
注意:要在一些不受支持的設備上模擬結果,只需按 F12 進入 DevTool。 接下來,按CTRL+SHIFT+P,然後搜索prefers-color-scheme: dark 並按回車鍵。
實現 CSS 和 JS 切換開關
如果我們採用這種方法,那麼我們就不需要擔心系統要求。 只需編寫幾行 CSS 和 JS,您就應該準備好了。 一旦我們初始化了變量,我們就可以在我們的樣式表中引用這些變量。 這將是在深色和淺色模式之間切換的 HTML 結構。

並且某些 CSS 行應該會導致此切換。

最後一部分是添加一些 JavaScript 來將它們聯繫在一起。
● 存儲用戶偏好以備將來訪問
● 在加載網站時檢查保存的用戶偏好(如果有)
而已! 查看下面的完整演示。
或單擊此處查看演示。
在 Drupal 8(或 Drupal 9)中實現暗/亮切換
要開始創建自定義 Drupal 8 主題,請參閱此處的精彩文章。 現在讓我們開始創建一個主題來展示如何在 Drupal 8 或 Drupal 9 中使用深色主題/淺色主題。
文件結構將如下所示:

現在,使用以下代碼更新page.html.twig 中的標題部分。
<header aria-label="Site header" role="banner"> <div class="container"> <div class="header"> {{ page.branding }} {{ page.navigation }} <div class="switch-wrapper"> <label class="switch" for="checkbox"> <input type="checkbox"/> <div class="slider round"></div> </label> </div> </div> </div> </header> HTML 結構的其餘部分將取決於您的設計或要求。
一旦您完成了 HTML 結構,就可以通過在 CSS 中設置元素樣式來使它們看起來更漂亮。
首先,您必須創建所有默認變量,這些變量將負責亮/暗模式下的顏色。
style.css :root { --color-background: #f0f0f0; --color-header: rgb(14, 33, 141); --color-header-text: #aecafa; --color-text: #2c0000; --color-card-bg: #fff; --color-link: rgb(255, 0, 0); } /* Variable decleration for dark mode */ [data-theme="dark"] { --color-background: #1a1a1a; --color-header: #aecafa; --color-header-text: 0e218d; --color-text: #d3d3d3; --color-card-bg: #435561; --color-link: #24ce24; }現在您已經完成了變量的定義,是時候向 Header 部分添加樣式以獲得所需的結果了。
style.css .header { display: flex; justify-content: space-between; align-items: center; padding: 10px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; background-color: var(--color-header); } .header a { color: var(--color-header-text); text-decoration: none; font-weight: bold; } .region-navigation { display: flex; justify-content: center; } ul.menu { display: flex; justify-content: center; } ul.menu li { margin-right: 30px; } .switch-wrapper { display: flex; align-items: center; } .switch { display: inline-block; height: 34px; position: relative; width: 60px; } .switch input { display: none; } .slider { background-color: white; bottom: 0; cursor: pointer; left: 0; position: absolute; right: 0; top: 0; transition: 0.4s; } .slider:before { background-color: rgb(255, 196, 0); bottom: 4px; content: url("../assets/sunny-day.svg"); height: 26px; left: 4px; position: absolute; transition: 0.4s; width: 26px; } input:checked + .slider { background-color: rgb(36, 36, 36); } input:checked + .slider:before { transform: translateX(26px); content: url("../assets/night.svg"); background-color: rgb(59, 116, 223); } .slider.round { border-radius: 34px; } .slider.round:before { border-radius: 50%; }style.css .header { display: flex; justify-content: space-between; align-items: center; padding: 10px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; background-color: var(--color-header); } .header a { color: var(--color-header-text); text-decoration: none; font-weight: bold; } .region-navigation { display: flex; justify-content: center; } ul.menu { display: flex; justify-content: center; } ul.menu li { margin-right: 30px; } .switch-wrapper { display: flex; align-items: center; } .switch { display: inline-block; height: 34px; position: relative; width: 60px; } .switch input { display: none; } .slider { background-color: white; bottom: 0; cursor: pointer; left: 0; position: absolute; right: 0; top: 0; transition: 0.4s; } .slider:before { background-color: rgb(255, 196, 0); bottom: 4px; content: url("../assets/sunny-day.svg"); height: 26px; left: 4px; position: absolute; transition: 0.4s; width: 26px; } input:checked + .slider { background-color: rgb(36, 36, 36); } input:checked + .slider:before { transform: translateX(26px); content: url("../assets/night.svg"); background-color: rgb(59, 116, 223); } .slider.round { border-radius: 34px; } .slider.round:before { border-radius: 50%; }
請注意,樣式可能會根據您的要求而有所不同。 完成所有樣式後,現在是在 Jquery 代碼中編寫一些功能的時候了。 Jquery 代碼看起來像這樣(在我們的例子中是 script.js)

script.js (($, Drupal) => { Drupal.behaviors.mainMenu = { attach(context) { const toggleSwitch = document.querySelector( '.switch input[type="checkbox"]' ); const currentTheme = localStorage.getItem("theme"); if (currentTheme) { document.documentElement.setAttribute("data-theme", currentTheme); if (currentTheme === "dark") { toggleSwitch.checked = true; } } function switchTheme(e) { if (e.target.checked) { document.documentElement.setAttribute("data-theme", "dark"); localStorage.setItem("theme", "dark"); } else { document.documentElement.setAttribute("data-theme", "light"); localStorage.setItem("theme", "light"); } } toggleSwitch.addEventListener("change", switchTheme, false); }, }; })(jQuery, Drupal);script.js (($, Drupal) => { Drupal.behaviors.mainMenu = { attach(context) { const toggleSwitch = document.querySelector( '.switch input[type="checkbox"]' ); const currentTheme = localStorage.getItem("theme"); if (currentTheme) { document.documentElement.setAttribute("data-theme", currentTheme); if (currentTheme === "dark") { toggleSwitch.checked = true; } } function switchTheme(e) { if (e.target.checked) { document.documentElement.setAttribute("data-theme", "dark"); localStorage.setItem("theme", "dark"); } else { document.documentElement.setAttribute("data-theme", "light"); localStorage.setItem("theme", "light"); } } toggleSwitch.addEventListener("change", switchTheme, false); }, }; })(jQuery, Drupal);
並且不要忘記將您的 JS 和 CSS 文件包含在您的 theme_name.libraries.yml 文件中。
global-styling: version: 1.x css: theme: css/style.css: {} js: js/script.js: {} dependencies: - core/jquery - core/drupalglobal-styling: version: 1.x css: theme: css/style.css: {} js: js/script.js: {} dependencies: - core/jquery - core/drupal
現在清除站點緩存以查看結果。 你的最終結果應該是這樣的:

