<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Tailwind輕松實(shí)現(xiàn)夜間模式,能跟隨系統(tǒng)又能手動(dòng)控制!

          共 15057字,需瀏覽 31分鐘

           ·

          2024-06-21 09:02


              

          大廠(chǎng)技術(shù)  高級(jí)前端  Node進(jìn)階

          點(diǎn)擊上方 程序員成長(zhǎng)指北,關(guān)注公眾號(hào)

          回復(fù)1,加入高級(jí)Node交流群

          作者:evanryuu
          原文:https://juejin.cn/post/7312727134297210914

          通過(guò)本文,你將會(huì)收獲到:

          1. 如何讓vscode不會(huì)再對(duì) @tailwind , @apply 之類(lèi)的屬性報(bào)錯(cuò)
          2. 如何讓你的應(yīng)用既能跟隨系統(tǒng)設(shè)置,又能手動(dòng)設(shè)置夜間模式

          如果本文對(duì)你有所幫助,希望你能動(dòng)動(dòng)小手點(diǎn)個(gè)免費(fèi)的贊,這會(huì)讓我更有動(dòng)力進(jìn)行寫(xiě)作,謝謝你!

          VSCode配置:

          這一步可以讓你的 @apply@tailwind 之類(lèi)的 @ 屬性都不會(huì)報(bào)錯(cuò),并有提示

          image.png
          image.png
          1. 在項(xiàng)目根目錄下新建 .vscode 文件夾
          2. 配置settings.json
              {
                "css.customData": [".vscode/tailwind.json"]
              }
          1. 配置tailwind.json
              {
                "version"1.1,
                "atDirectives": [
                  {
                    "name""@tailwind",
                    "description""Use the `@tailwind` directive to insert Tailwind's `base`, `components`, `utilities` and `screens` styles into your CSS.",
                    "references": [
                      {
                        "name""Tailwind Documentation",
                        "url""https://tailwindcss.com/docs/functions-and-directives#tailwind"
                      }
                    ]
                  },
                  {
                    "name""@apply",
                    "description""Use the `@apply` directive to inline any existing utility classes into your own custom CSS. This is useful when you find a common utility pattern in your HTML that you’d like to extract to a new component.",
                    "references": [
                      {
                        "name""Tailwind Documentation",
                        "url""https://tailwindcss.com/docs/functions-and-directives#apply"
                      }
                    ]
                  },
                  {
                    "name""@responsive",
                    "description""You can generate responsive variants of your own classes by wrapping their definitions in the `@responsive` directive:\n```css\n@responsive {\n  .alert {\n    background-color: #E53E3E;\n  }\n}\n```\n",
                    "references": [
                      {
                        "name""Tailwind Documentation",
                        "url""https://tailwindcss.com/docs/functions-and-directives#responsive"
                      }
                    ]
                  },
                  {
                    "name""@screen",
                    "description""The `@screen` directive allows you to create media queries that reference your breakpoints by **name** instead of duplicating their values in your own CSS:\n```css\n@screen sm {\n  /* ... */\n}\n```\n…gets transformed into this:\n```css\n@media (min-width: 640px) {\n  /* ... */\n}\n```\n",
                    "references": [
                      {
                        "name""Tailwind Documentation",
                        "url""https://tailwindcss.com/docs/functions-and-directives#screen"
                      }
                    ]
                  },
                  {
                    "name""@variants",
                    "description""Generate `hover`, `focus`, `active` and other **variants** of your own utilities by wrapping their definitions in the `@variants` directive:\n```css\n@variants hover, focus {\n   .btn-brand {\n    background-color: #3182CE;\n  }\n}\n```\n",
                    "references": [
                      {
                        "name""Tailwind Documentation",
                        "url""https://tailwindcss.com/docs/functions-and-directives#variants"
                      }
                    ]
                  }
                ]
              }

          來(lái)源:github.com/tailwindlab…[1]

          思路

          方案1: 僅使用dark: 切換夜間模式

          我們?cè)?tailwind 中可以很輕松地靠類(lèi)名去實(shí)現(xiàn)切換:

          <div class="bg-white dark:bg-black">...</div>

          但是我們并不希望每個(gè)地方都要我們?nèi)?xiě),因?yàn)槿绻覀円O(shè)置n個(gè)屬性,就要寫(xiě)2n個(gè)類(lèi)名

          <div class="bg-white dark:bg-black" />

          所以會(huì)超出預(yù)想的長(zhǎng)。

          另外的問(wèn)題是,如果我們將來(lái)希望去實(shí)現(xiàn)主題色的話(huà),我們還要 bg-white dark:bg-black some-theme:bg-navy (假設(shè)有 some-theme: 這個(gè)東西),就更多了。

          那有什么方法可以幫我們解決這個(gè)問(wèn)題呢?

          方案2: 利用 @apply 自定義類(lèi)名實(shí)現(xiàn)切換

          換一個(gè)思路,如果我們能有一個(gè) bg-theme 這樣的類(lèi)名,自動(dòng)幫我們做這件事,是不是就解決了呢?

          我們利用 @apply 的話(huà)就可以很簡(jiǎn)單地寫(xiě)出來(lái)下面的原子CSS:

          .bg-theme {
          @apply bg-white dark:bg-black;
          }

          哈!問(wèn)題解決了…嗎?

          要知道這樣寫(xiě)出來(lái)的類(lèi)名在vscode是沒(méi)有提示的,因?yàn)閠ailwind并不會(huì)自動(dòng)去找css文件然后掃描里面的看起來(lái)像原子CSS的類(lèi)名的,vscode 的tailwind插件是通過(guò) tailwind.config. 文件工作的,只有在 tailwind.config. 里面有定義的東西才會(huì)有提示。

          那我們可以這樣嗎?

              // tailwind.config.js
              module.exports = {
                ...
                theme: {
                  extend: {
                    colors: {
                      theme'white dark:black'
                    }
                  }
                }
                ...
              }

          很遺憾,dark:畢竟是類(lèi)名而不是顏色值,因此tailwind并不支持這樣的寫(xiě)法。

          但是!Tailwind是支持CSS變量的。比如你可以寫(xiě)成

              // tailwind.config.js
              ...
                    colors: {
                      theme'var(--theme-color)'
                    }
              ...

          有了這個(gè)功能,這里就可以引入第三個(gè)方案

          方案3:媒體查詢(xún) + CSS變量

          我們知道如果用戶(hù)的系統(tǒng)設(shè)置為深色模式的話(huà),我們是可以通過(guò)媒體查詢(xún)屬性 prefers-color-shceme: dark讀取到的,因此我們就能以此為根據(jù)寫(xiě)出日間/夜間模式兩套變量

          :root {
            --theme-color: white;
          }

          @media (prefers-color-scheme: dark) {
            :root {
              --theme-color: black;
            }
          }
              // tailwind.config.js
                      colors: {
                        theme'var(--theme-color)',
                      },

          這樣寫(xiě)出來(lái)的tailwind配置,不僅可以直接給bg / text / … 等等屬性使用,更重要的是,vscode這會(huì)兒有提示了!

          Kapture 2023-12-16 at 18.57.21.gif

          這是一件非常棒的事情!并且,當(dāng)我們使用css變量之后,我們要切換主題也很方便。

          :root {
            --blue-400#4489f6;
            --blue-500#0070f3;
          }

          @media (prefers-color-scheme: dark) {
            :root {
              --blue-400#2d79f0;
              --blue-500#063784;
            }
          }
              // tailwind.config.js
                      colors: {
                        theme'var(--theme-color)',
                        blue: {
                          400'var(--blue-400)',
                          500'var(--blue-500)',
                        }
                      },

          當(dāng)然,你也可以不修改顏色,而是更改類(lèi)名對(duì)應(yīng)的色值

              :root {
                --theme-blue#4489f6;
              }

              @media (prefers-color-scheme: dark) {
                :root {
                  --theme-blue#0070f3;  
                }
              }
              // tailwind.config.js
                      colors: {
                        theme'var(--theme-color)',
                        'theme-blue''var(--theme-blue)'
                      },

          你還可以設(shè)置同名的屬性名分別給文本和背景

          // tailwind.config.js
                  textColor: {
                    'theme''var(--theme-color-invert)'
                  },
                  backgroundColor: {
                    'theme''var(--theme-color)',
                  },

          這個(gè)方案最大的缺點(diǎn)就是,本來(lái)只需要一個(gè)tailwind.config 的文件,現(xiàn)在還需要多個(gè) css 文件(main.css / theme-light.css / theme-dark.css / …

          即使我們可以使用一個(gè)入口main.css引入其余的css,這也會(huì)導(dǎo)致項(xiàng)目中需要多一行 import 'my-tailwind.css' 之類(lèi)的文件,所以我個(gè)人認(rèn)為仍然是有優(yōu)化空間的。

          方案4: 類(lèi)名 + 媒體查詢(xún) + css變量

          實(shí)際上,通過(guò)前面的流程,我們已經(jīng)可以比較完美地支持系統(tǒng)的深色模式了,但是有的時(shí)候我們的用戶(hù)可能只希望在我們的網(wǎng)站上開(kāi)啟深色模式,所以我們要提供給用戶(hù)手動(dòng)切換的能力。

          這個(gè)時(shí)候dark就要以類(lèi)名的形式添加在html上,而不是單純使用媒體查詢(xún)了,那我們可以大概思考一下我們的需求:

          1. 剛進(jìn)入頁(yè)面時(shí)的夜間模式要以用戶(hù)的設(shè)置為準(zhǔn)
          2. 用戶(hù)可以手動(dòng)切換日間/夜間模式
          3. 用戶(hù)手動(dòng)切換之后,仍然可以跟隨系統(tǒng)進(jìn)行變化

          由此,我們可以寫(xiě)一個(gè)hook useDark 做下面的事情:

          1. 獲取當(dāng)前系統(tǒng)的dark mode是否開(kāi)啟,設(shè)為 systemDark,做useState默認(rèn)值
          2. const [dark, setDark] = useState<boolean>(systemDark)
          3. const toggleDark = () => setDark(!dark) ,用來(lái)手動(dòng)切換日間/夜間模式
          4. 監(jiān)聽(tīng) mediaQuery ,讓 dark 跟隨用戶(hù)系統(tǒng)設(shè)定變化而變化
          5. 聲明并暴露 dark變量 以及 toggleDark 方法

          最后我們的成果如下:

          useDark 可以參考這里[2]

          使用state導(dǎo)致的問(wèn)題

          如果有兩個(gè)組件A和B同時(shí)使用useDark的話(huà),那么就可能會(huì)有bug。因?yàn)榇藭r(shí)dark是組件內(nèi)部的state,這就導(dǎo)致了組件A點(diǎn)擊之后,只有組件A自己的dark變化了,組件B的dark是不會(huì)跟著變的。

          如何解決這個(gè)問(wèn)題,各位自由發(fā)揮就好了??localStorage,全局狀態(tài)管理,或者別的什么方法,都可以。

          方案對(duì)比

          至此,我們來(lái)對(duì)比下上述的幾個(gè)方法

          方案對(duì)比 僅使用 dark: 選擇器 @apply 自定義類(lèi)名 媒體查詢(xún)+css變量 類(lèi)名+監(jiān)聽(tīng)媒體查詢(xún)+css變量
          配置簡(jiǎn)單 ?????? ???? ???? ??
          開(kāi)發(fā)友好 ?? ?? ?????? ??????
          主題拓展 ?? ?? ???? ??????
          適配性(系統(tǒng) / 用戶(hù)設(shè)置) ???? ???? ???? ??????

          思考:如何實(shí)現(xiàn) useTheme?

          我們現(xiàn)在是基于類(lèi)名實(shí)現(xiàn)深色模式的,那我們其實(shí)也很容易切換主題。比如

          :root {
            --theme-color: white;
          }

          .dark {
            --theme-color: black;
          }

          .violet {
            --theme-color: violet;
          }

          只要我們對(duì)useDark稍作改動(dòng),就可以變?yōu)閡seTheme了!至于如何實(shí)現(xiàn),大家也可以自己嘗試。

          總結(jié)

          建議使用類(lèi)名+監(jiān)聽(tīng)媒體查詢(xún)+css變量的形式,除了剛開(kāi)始的配置較為復(fù)雜,其余時(shí)候都很爽快。無(wú)論是開(kāi)發(fā)使用的方便程度還是主題的拓展性。

          由于我們項(xiàng)目中接入了 next-themes ,所以也省去了自己開(kāi)發(fā) useDark ,畢竟它自帶了 useTheme 的鉤子。最后的解決方案就是

          1. base.css 配置色值、字號(hào)等變量
          2. theme-.css 配置各個(gè)主題下的設(shè)計(jì)類(lèi)名
          3. main.css 引入
          4. tailwind.config. 配置別名

          如果你覺(jué)得本文有錯(cuò)誤,也歡迎你在評(píng)論區(qū)指出,我們可以友好討論??

          參考資料
          [1]

          https://github.com/tailwindlabs/tailwindcss/discussions/5258#discussioncomment-1979394: https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Ftailwindlabs%2Ftailwindcss%2Fdiscussions%2F5258%23discussioncomment-1979394

          [2]

          https://github.com/evanryuu/tw-dark-usecase/blob/main/src/hooks/useDark.ts: https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fevanryuu%2Ftw-dark-usecase%2Fblob%2Fmain%2Fsrc%2Fhooks%2FuseDark.ts

          Node 社群

             


          我組建了一個(gè)氛圍特別好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你對(duì)Node.js學(xué)習(xí)感興趣的話(huà)(后續(xù)有計(jì)劃也可以),我們可以一起進(jìn)行Node.js相關(guān)的交流、學(xué)習(xí)、共建。下方加 考拉 好友回復(fù)「Node」即可。

             “分享、點(diǎn)贊在看” 支持一下

          瀏覽 125
          1點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  围产精品久久久久久久粉嫩 | 插40岁女人视频 | 日韩三级小说 | 亚洲一区二区av 亚洲一区欧美一区 | 五月天激情综合网 |