Hướng dẫn làm giao diện Dark mode cho website từ A-Z

Gần đây lướt Facebook thấy nhiều bạn hỏi về vấn đề làm sao tạo được giao diện Dark Mode cho website, để khi người ta vào website thì có thể tuỳ chỉnh nền tối hay là sáng. Nên hôm nay tranh thủ viết một bài về cách làm giao diện Dark mode cho website từ a-z cho các bạn luôn.

Việc đầu tiên chúng ta cần làm đó chính là tạo một giao diện, ở đây mình tạo một giao diện đơn giản với HTML và CSS lần lượt như sau:

<div class="wrapper">
   <div class="box">
      <div class="image">
         <img src="https://bit.ly/3bT21Ik" alt="">
      </div>
      <div class="content">
         <h2 class="title">CSS is Awesome</h2>
         <p>Let's get started</p>
      </div>
   </div>
   <div class="theme-switch-wrapper">
      <label class="theme-switch" for="checkbox">
         <input type="checkbox" id="checkbox" />
         <div class="slider round"></div>
      </label>
   </div>
</div>
@import url("https://fonts.googleapis.com/css?family=Lora:400,400i,700");
 .wrapper {
     font-family: "Lora";
     background-color: white;
     width: 800px;
     height: 100vh;
     position: relative;
     margin: 0 auto;
}
 .box {
     height: 100%;
     width: 100%;
     display: flex;
}
 .image, .content {
     width: 50%;
}
 .content {
     padding: 20px;
     display: flex;
     align-items: center;
     justify-content: center;
     flex-direction: column;
     background-color: #fafafa;
}
 .title {
     font-weight: bold;
     font-size: 40px;
     margin-bottom: 10px;
}
 .title + p {
     font-size: 20px;
}
 .image img {
     display: block;
     width: 100%;
     height: 100%;
     object-fit: cover;
}
 .theme-switch-wrapper {
     display: flex;
     align-items: center;
     position: absolute;
     top: 10px;
     right: 10px;
     z-index: 1000;
}
 .theme-switch {
     display: inline-block;
     height: 34px;
     position: relative;
     width: 60px;
}
 .theme-switch input {
     display:none;
}
 .slider {
     background-color: #999;
     bottom: 0;
     cursor: pointer;
     left: 0;
     position: absolute;
     right: 0;
     top: 0;
     transition: .4s;
}
 .slider:before {
     background-color: white;
     bottom: 4px;
     content: "";
     height: 26px;
     left: 4px;
     position: absolute;
     transition: .4s;
     width: 26px;
}
 input:checked + .slider {
     background-color: #eee;
}
 input:checked + .slider:before {
     transform: translateX(26px);
}
 .slider.round {
     border-radius: 34px;
}
 .slider.round:before {
     border-radius: 50%;
}

Ta sẽ có giao diện lúc này như sau. Các bạn để ý nút Toggle nhé để sau này chúng ta dùng Javascript để viết sự kiện khi nhấn vào thay đổi màu sắc cho website đó. Còn các mũi tên xanh dương mình chỉ là để chúng ta CSS cho chúng bằng cách dùng biến trong CSS dưới đây.

Mấu chốt để làm được giao diện đổi màu đó chính là sử dụng biến trong CSS, mình có viết về nó rồi. Các bạn có thể xem lại tại đây nha. Khi sử dụng biến chúng ta sẽ tạo ra 2 lựa chọn về màu sắc, mặc định là các mã màu ban đầu từ thằng :root và  thứ 2 là từ thằng [data-theme="dark"] mà chúng ta sẽ chuyển qua. Cũng là các biến từ :root thôi tuy nhiên ở Dark Theme các bạn sẽ đổi các biến đó thành các mã màu khác mà các bạn thích, ở đây mình đổi trắng thành đen và đen thành trắng.

:root {
  --white: white;
  --black: black;
  --gray: #fafafa;
}
[data-theme="dark"] {
  --white: black;
  --black: white;
  --gray: black;
}

Sau đó ta áp dụng chúng vào các class mà chúng ta đã khai báo ban đầu như thế này

.wrapper {
     ...
     background-color: var(--white);
}
 .content {
     ...
     background-color: var(--gray);
}
 .title {
     color: var(--black);
     ...
}
 .title + p {
     color: var(--black);
     ...
}

Việc tiếp theo cần làm đó là viết một đoạn Javascript để bắt sự kiện khi nhấn vào nút Toggle để nó chuyển các mã màu sang màu tối ở [data-theme="dark"] mà chúng ta đã tạo ở trên. Mình có Javascript như sau

const toggleSwitch = document.querySelector('.theme-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);

Mình sẽ giải thích Javascript một chút cho các bạn hiểu nhé. Đầu tiên mình khai báo 1 biến là toggleSwitch truy xuất tới DOM là Toggle, và một biến là currentTheme để truy xuất tới một localStorage có tên là theme.

Sau đó mình kiểm tra xem có localStorage nào tên là theme không, nếu có thì mình thiết lập cho thẻ html (root) có thuộc tính data-themecurrentTheme, đồng thời mình kiểm tra xem theme hiện tại có phải là dark không, nếu phải thì mình sẽ thiết lập cho Toggle đó checkedtrue, tức là đã nhấn vào.

Tiếp theo mình viết một hàm có tên là switchTheme để khi nhấn vào Toggle thì sẽ gọi hàm này. Hàm này kiểm tra 2 điều kiện, nếu Toggle được nhấn vào thì sẽ thiết lập theme là dark đồng thời tạo localStorage theme là dark luôn, ngược lại thì thiết lập theme là light.

Và cuối cùng là sự kiện change của Toggle, nghĩa là khi các bạn nhấn vào nó sẽ gọi hàm switchTheme viết ở trên để xử lý. Lúc này chúng ta sẽ có kết quả như mong đợi

Chúc các bạn một ngày tốt lành, và đừng quên tham khảo Codepen dưới đây nhé

See the Pen
DarkMode Tutorial
by EvonDev (@evondev)
on CodePen.

Bài viết có tham khảo từ Dev.to

.

Subscribe
Notify of
guest

12 Comments
Inline Feedbacks
View all comments
Quang Thái
Quang Thái

Cảm ơn anh cái em đang chưa làm được , rất hay và dễ hiểu nữa

nghia le
nghia le

cho em hoi ạ,
nếu làm trên wp thì chèn vào file nào ạ..

Sói ăn chay
Sói ăn chay

Blog đẹp, trình bày dễ hiểu. Không liên quan nhưng chủ blog xài mã nguồn nào vậy?

Hùng
Hùng

e thay change bằng click đc ko a?

Lê Quân
Lê Quân

Sao anh không đặt –text-color hay –bg-color mà lại dùng –white + –black? Một anh senior làm với e bảo đặt vậy không thực tế, sẽ phải sửa khi giá trị không còn chỉ là đen và trắng? Thanks a nhé.

Luong Ba
Luong Ba

Hay Quá anh

Toancr SEO
Toancr SEO

blog đẹp quá pro