2020 rồi, đến Facebook còn có Dark Mode thì không có lý do gì bạn không thêm một chút dark vào trang web của mình để tăng trải nghiệm người dùng lên một chút
Càng tốt hơn nếu bạn là một dev React thì có thể áp dụng vài bước đơn giản dưới đây, thời gian bỏ ra là không quá nhiều nhưng hiệu quả có lẽ sẽ khá tốt đấy. Nếu bạn hiểu ý tưởng này thì có thể chuyển đổi nó về cho project Vuejs hoặc JQuery chẳng hạn .
CSS
Hãy bắt đầu một bước đơn giản với CSS trước, các bạn cần xác định Dark Mode cần làm được những gì, với mình thì chỉ cần nó chuyển các thành phần màu trắng sáng của trang web về màu tối ví dụ như background chẳng hạn và ngược lại các nội dung tối thành màu sáng sủa hơn để nổi bật hơn trên nền tối, ví dụ như: text, icon, border,… tùy vào cảm quan của bạn thôi
Và để làm được điều đó thì tôi sẽ tạo ra 2 file CSS với tương ứng với 2 theme là dark và light
dark.css
1 2 3 4 5 | <span class="token selector">html[data-theme="dark"]</span> <span class="token punctuation">{</span> <span class="token property">--color</span><span class="token punctuation">:</span> <span class="token function">rgb</span><span class="token punctuation">(</span>250, 250, 250<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">--background-color</span><span class="token punctuation">:</span> <span class="token function">rgb</span><span class="token punctuation">(</span>5, 5, 5<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
light.css
1 2 3 4 5 | <span class="token selector">html[data-theme="light"]</span> <span class="token punctuation">{</span> <span class="token property">--color</span><span class="token punctuation">:</span> <span class="token function">rgb</span><span class="token punctuation">(</span>5, 5, 5<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">--background-color</span><span class="token punctuation">:</span> <span class="token function">rgb</span><span class="token punctuation">(</span>250, 250, 250<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Ở đây tôi sử dụng 2 biến là –color và –background-color, cho bạn nào chưa biết thì cách khai báo có 2 dấu gạch ngang ở đầu tiên trong CSS được coi là khai báo biến, và biến số này các bạn có thể sử dụng để style ở trong toàn bộ trang web.
Và như đã thấy thì tôi sẽ sử dụng 2 biến này để quy định cho background và các dòng text trong toàn bộ trang web, nếu theme là dark thì set background màu tối một chút, text sẽ là màu trắng sáng và ngược lại
App.css
1 2 3 4 5 6 7 8 9 10 11 | <span class="token selector">.App-header</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span><span class="token function">var</span><span class="token punctuation">(</span>--background-color<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">min-height</span><span class="token punctuation">:</span> 100vh<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span> <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span> <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">justify-content</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token function">calc</span><span class="token punctuation">(</span>10px + 2vmin<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span><span class="token function">var</span><span class="token punctuation">(</span>--color<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Thêm chiếc Component
Nào đoạn CSS chỉ có thế kia thôi, quá ez rồi. Giờ đến phần xử lý chính, các bạn tạo thêm một component tên ToggleDarkMode, chúng ta sẽ thêm một chút code vào index.js
như sau:
ToggleDarkMode/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token keyword">const</span> <span class="token function-variable function">DarkModeToggle</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">[</span>isDark<span class="token punctuation">,</span> setIsDark<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span>localStorage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token string">"theme"</span><span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token string">"dark"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">useEffect</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> document <span class="token punctuation">.</span><span class="token function">getElementsByTagName</span><span class="token punctuation">(</span><span class="token string">"HTML"</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">"data-theme"</span><span class="token punctuation">,</span> localStorage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token string">"theme"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span>input type<span class="token operator">=</span><span class="token string">"checkbox"</span> defaultChecked<span class="token operator">=</span><span class="token punctuation">{</span>isDark<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Ở đây tôi sử dụng localStorage để lưu lại trạng thái của theme ngay trên trình duyệt của người dùng, mỗi lần tải lại trang web tôi sẽ kiểm tra trạng thái này để xem có phải người này đã bật dark mode hay không và đồng thời gán trạng thái này vào attribute data-theme.
Bạn nào không nhớ thì có thể lật lên xem phần CSS, attribute này sẽ được dùng làm selector để xác định xem chúng ta sẽ dùng style dark hay là light
Và tôi có một cái checkbox be bé sẽ được đặt trạng thái checked nếu người dùng đang sử dụng theme dark, bây giờ chúng ta sẽ thêm code xử lý để dùng checkbox này làm công tắc bật tắt dark mode đây
ToggleDarkMode/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <span class="token keyword">const</span> <span class="token function-variable function">toggleThemeChange</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>isDark<span class="token punctuation">)</span> <span class="token punctuation">{</span> localStorage<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span><span class="token string">"theme"</span><span class="token punctuation">,</span> <span class="token string">"light"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> document <span class="token punctuation">.</span><span class="token function">getElementsByTagName</span><span class="token punctuation">(</span><span class="token string">"HTML"</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">"data-theme"</span><span class="token punctuation">,</span> <span class="token string">"light"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setIsDark</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> localStorage<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span><span class="token string">"theme"</span><span class="token punctuation">,</span> <span class="token string">"dark"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> document <span class="token punctuation">.</span><span class="token function">getElementsByTagName</span><span class="token punctuation">(</span><span class="token string">"HTML"</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">"data-theme"</span><span class="token punctuation">,</span> <span class="token string">"dark"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setIsDark</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//...</span> <span class="token operator"><</span>input type<span class="token operator">=</span><span class="token string">"checkbox"</span> defaultChecked<span class="token operator">=</span><span class="token punctuation">{</span>isDark<span class="token punctuation">}</span> onChange<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">toggleThemeChange</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> |
Phần này thì quá dễ rồi, thêm một sự kiện onChange và trong sự kiện này chúng ta sẽ kiểm tra theme hiện tại đang là gì, nếu nó là light thì ta sẽ đổi nó về dark, và ngược lại
Và cuối cùng là thành quả:
Khá là đơn giản đúng không, nhưng hiệu quả bất ngờ. Các bạn có thể xác định thêm các thành phần màu khác tùy ý, chơi 7 màu RGB luôn cũng được
Cám ơn đã theo dõi bài viết!