Nên sử dụng Mobile first hay là Desktop first khi làm Responsive

Chào các bạn, hôm nay chúng ta sẽ đến một chủ đề khá là hay đó là khi chúng ta code giao diện Responsive thì nên code theo hướng Mobile first hay là Desktop first ? Đây là 1 vấn đề mà có khá nhiều người thảo luận, có người bảo thì code Mobile first dễ hơn vì nó đang là xu hướng, có người thì bảo là Desktop first dễ hơn….

Ở bài viết này mình sẽ chia sẻ cho các bạn theo góc nhìn của mình để các bạn nắm rõ hơn về những cái này và biết áp dụng như thế nào cho hợp lý nhé. Chiến thôi

Mobile first

Nói theo nghĩa của nó thì chúng ta sẽ code một giao diện từ thiết bị nhỏ cho tới thiết bị to, từ mobile tới tablet rồi tới laptop và các màn hình lớn như Retina.

Tuy nhiên khi code Mobile first thì chúng ta nên có thiết kế mobile trước để chúng ta biết mà code như thế nào cho đúng, nếu không có giao diện mobile mà chỉ có desktop thôi mà chúng ta code mobile first thì sẽ khá là cực đó. Cho nên trường hợp mà chỉ có giao diện desktop thôi thì theo bản thân mình nghĩ lúc này code theo hướng Desktop first là 1 giải pháp tốt hơn.

Desktop first

Ngược lại với mobile first thì chúng ta sẽ code các giao diện từ lớn đến bé từ Retina cho tới laptop, rồi tới tablet và cuối cùng là các thiết bị mobile. Một điểm hay của Desktop first là nếu chỉ có giao diện desktop thì chúng ta vẫn code bình thường, và lúc này nếu các bạn tự hỏi vậy làm giao diện tablet mobile kiểu gì ?

Lúc này buộc các bạn phải có thêm kiến thức về UI UX, để làm cái gì ? Để tự có thể tuỳ biến sao đó cho những giao diện ở desktop xuống giao diện tablet, mobile cho phù hợp và đẹp là ổn(UI/UX). Vì đôi khi các bạn đi làm khách hàng chỉ cung cấp cho bạn 1 giao diện Desktop mà thôi và họ yêu cầu mobile các bạn phải tự căn chỉnh sao cho hợp lý. Vì thế tuỳ vào trường hợp ví dụ như trường hợp này thì lựa chọn Desktop first sẽ tốt hơn là Mobile first.

Nếu chỉ có 1 giao diện desktop mà yêu cầu code Mobile first thì khá là khó vì bạn phải tưởng tượng code giao diện điện thoại như nào cái đã để khi nó lên thiết bị lớn hơn thì giống với thiết kế hiện có là desktop. Theo quan điểm mình là thế, nếu bạn có ý tưởng nào hay hơn thì có thể bình luận nhé.

Như vậy là chúng ta đã đi qua khái niệm và vấn đề gặp phải, giờ mình sẽ nói đến best practice nhé, nghĩa là những ví dụ, trường hợp khi đi làm thực tế để áp dụng cho tốt nhen

Responsive menu

Đây là 1 ví dụ điển hình luôn, khi làm giao diện menu ở trên Desktop thì đơn giản là các bạn dàn hàng ngang thôi với cấu trúc ul li a nhỉ. Nhưng khi code xuống điện thoại thì thường chúng ta sẽ làm fixed menu rồi kết hợp với Javascript để nhấn vào nút toggle cho menu chạy ra chạy vào thì lúc này các bạn sẽ thấy 2 phong cách code của Mobile first và Desktop first sẽ như sau:

Mobile first

.nav {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow-y: auto;
  padding-top: 2rem;
}

.nav__toggle {
  position: absolute;
  right: 1rem;
  top: 1rem;
}

.nav__item {
  padding: 1rem;
  display: block;
}

.nav__item:not(:last-child) {
  border-bottom: 1px solid #fff;
}

/* Desktop styles */
@media (min-width: 1024px) {
  .nav {
    position: initial;
    width: initial;
    height: initial;
    overflow-y: initial;
    display: flex;
    align-items: center;
    padding-top: 0;
    background-color: blue;
  }

  .nav__toggle {
    display: none;
  }

  .nav__item:hover {
    color: blue;
    background-color: initial;
  }

  .nav__item:not(:last-child) {
    border-bottom: 0;
    border-left: 1px solid #fff;
  }
}

Lúc này các bạn sẽ thấy là khi code ở màn hình >= 1024 thì các bạn phải đè code rất là nhiều luôn. Chưa kể nhiều vấn đề khác như là ở màn hình 1024 mình muốn bỏ border-bottom của class nav__item thì code lại không chạy được là vì đoạn :not(:last-child) ban đầu nó có độ ưu tiên cao hơn

.nav__item:not(:last-child) {
  border-bottom: 1px solid #fff;
}
@media (min-width: 1024px) {
  .nav__item{
    border-bottom: 0; // not working
  }
}

Lúc này các bạn muốn nó hoạt động thì phải code làm sao để có độ ưu tiên cao hơn là được như dưới đây, mình đơn giản chỉ là copy đoạn code ban đầu và thiết lập CSS lại thôi là ổn.

.nav__item:not(:last-child) {
  border-bottom: 0;
}

Đó chính là Mobile first, vậy còn Desktop first thì code trông như nào nhỉ ? Cùng xem dưới đây nha

Desktop first

.nav {
  display: flex;
  align-items: center;
  background-color: blue;
}

.nav__toggle {
  position: absolute;
  right: 1rem;
  top: 1rem;
}

.nav__item {
  padding: 1rem;
  display: block;
}

.nav__item:hover {
  color: blue;
  background-color: initial;
}

.nav__item:not(:last-child) {
  border-bottom: 0;
  border-left: 1px solid #fff;
}

@media (max-width: 1023px) {
  .nav {
    display: block;
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow-y: auto;
    padding-top: 2rem;
  }

  .nav__toggle {
    display: block;
  }

  .nav__item:not(:last-child) {
    border-bottom: 1px solid #fff;
  }
}

Các bạn có thấy điều gì khác không ? Đó chính là các bạn đỡ hạn chế đè code hơn so với việc dùng Mobile first lúc nãy đó, và code trông nó có vẻ ngắn hơn và thoáng hơn. Tuy nhiên đây vẫn chưa là cách tốt nhất. Theo quan điểm của mình để hạn chế việc đè code lên nhau mình sẽ kết hợp cả 2 luôn. Khám phá tiếp theo dưới đây nha

Mix desktop first and mobile first

// base styles
.nav{}
.nav__toggle {
  position: absolute;
  right: 1rem;
  top: 1rem;
}
.nav__item {
  padding: 1rem;
  display: block;
}
// desktop styles
@media screen and (min-width: 1024px){
  .nav {
    display: flex;
    align-items: center;
    background-color: blue;
  }
  .nav__item:hover {
    color: blue;
    background-color: initial;
  }
  .nav__toggle {
    display: none;
  }

  .nav__item:not(:last-child) {
    border-bottom: 0;
    border-left: 1px solid #fff;
  }
}
// mobile styles
@media screen and (max-width: 1023px){
  .nav {
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow-y: auto;
    padding-top: 2rem;
  }
  .nav__item:not(:last-child) {
    border-bottom: 1px solid #fff;
  }

}

Khi mà mình kết hợp cả 2 luôn thì các bạn sẽ thấy không còn xung đột nữa và không cần phải lo vấn đề đè code nữa nhen. Và mình có chia ra làm 3 phần theo trường hợp mình đang nói đến là base styles là những styles chung áp dụng cho toàn bộ giao diện, min-width là áp dụng cho kiểu Mobile first và max-width là cho kiểu Desktop first nhen.

Một lưu ý nhỏ nữa là các bạn không được code trùng số khi dùng media query nhé ví dụ dưới đây tại break-point 1024 nó sẽ xung đột cả 2 đoạn code này cho nên sẽ dẫn đến trường hợp sai mà các bạn không mong muốn cho nên hãy cẩn thận.

@media screen and (max-width: 1024px) { // sai
  .nav{
    display: none;
  }
}
@media screen and (min-width: 1024px) {
  .nav{
    display: block;
  }
}

Theo mình cứ nhớ công thức là max-width = min-width – 1 vậy đúng sẽ là max-width: 1023px nhé các bạn.

@media screen and (max-width: 1023px) { // đúng
  .nav{
    display: none;
  }
}
@media screen and (min-width: 1024px) {
  .nav{
    display: block;
  }
}

Tạm kết

Trên đây là những chia sẻ mới của mình về việc sử dụng Media query sao cho hiệu quả, để các bạn nắm rõ khi nào nên dùng Mobile first, khi nào nên dùng Desktop first hay là dùng cả 2. Từ đó đúc kết được nhiều kinh nghiệm khi code hơn, tối ưu hơn, dễ dàng sửa hơn và tránh xung đột code nhất có thể nhen. Cám ơn bạn đã đọc và chúc các bạn 1 ngày tốt lành.

Bài viết có tham khảo các đoạn code từ blog Ishadeed

Subscribe
Notify of
guest

8 Comments
Inline Feedbacks
View all comments
Đỗ Sinh
Đỗ Sinh

Mình cũng đã làm theo bạn và nó sai :))

max-width = min-width – 1

Chẳng hạn max-width = 889 và min-width = 900; Khi kích thước màn hình là 889.56 thì nó sẽ thực hiện cả code trong 2 block max-width và min-width cùng lúc, lỗi tùm lum :))

Tới khi em để 2 số trùng nhau là 900 thì lại chạy ngon k có xung đột. Bác kiểm tra lại xem của bác có thế k chứ của em làm theo của bác nó lỗi á

Hùng Cute
Hùng Cute
Reply to  Đỗ Sinh

ok

anh
anh
Reply to  Đỗ Sinh

tốt nhất để trùng số và cái nào ưu tiên khi gặp đúng số đó thì viết phía dưới

Trần Danh
Trần Danh
Reply to  Đỗ Sinh

Do bạn để đơn vị là px khi repons mới bị lỗi như thế. Bạn nên chuyển từ px sang em là hết lỗi nha.

tt2003
tt2003

good