Responsive giao diện cực đỉnh với Container Queries

Bài viết được sự cho phép của tác giả Trần Anh Tuấn

Đối với Frontend Developer thì việc tối ưu giao diện Responsive là điều hiển nhiên rồi. Và chúng ta thông thường từ trước đến giờ là dùng Media Queries để làm việc đó. Đối với font-size thì mình đã giới thiệu cho các bạn cách làm ở bài viết sử dụng hàm clamp trong CSS rồi.

Vậy thì còn cách nào khác để làm Responsive cho giao diện mà không hoặc ít dùng tới Media Queries không ? Tất nhiên là có rồi, và mình rất háo hức giới thiệu cho các bạn ngay sau đây Container Queries.

Đầu tiên chúng ta phải hiểu rằng khi sử dụng MQ (Media queries) thì chúng ta sẽ dựa vào Viewport của màn hình sẽ có các breakpoints như 1024, 1280, 768…. Tuy nhiên khi sử dụng CQ (Container Queries) thì sẽ dựa vào độ rộng của Container. Container là gì thì mình sẽ ví dụ cho các bạn sau đây

Responsive-giao-dien-voi-Container Queries

Giao diện ở trên là Sidebar ở phía bên trái, còn bên phải là Main, trong Main chứa Card với cấu trúc HTML và CSS như sau:

<div class="wrapper">
      <div class="sidebar"></div>
      <div class="main">
        <div class="card">
          <div class="card-image">
            <img
              src="https://images.unsplash.com/"
              alt=""
            />
          </div>
          <div class="card-conten
            <p class="card-city">New York</p>
            <h3 class="card-title">
              New York City’s air pollution among the world’s worst as Canada wildfire smoke shrouds Northeast
            </h3>
          </div>
        </div>
      </div>
    </div>
.wrapper {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  grid-gap: 20px;
  height: 100vh;
}
.sidebar {
  border-right: 1px solid #eee;
}
.main {
  padding: 20px;
}
.card {
  display: flex;
  gap: 20px;
}
.card-image {
  overflow: hidden;
  width: 100%;
  flex: 0 0 200px;
}
.card-image img {
  border-radius: 12px;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.card-content {
  padding: 20px 0;
  flex: 1;
}
.card-city {
  font-size: 14px;
  margin-bottom: 10px;
  color: #333;
}
.card-title {
  font-size: 18px;
  font-weight: bold;
  line-height: 1.5;
}

  Cách responsive text hiệu quả với hàm clamp cực hay ho

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

Khi ở màn hình tầm < 900px thì giao diện sẽ hiển thị như sau

Responsive-giao-dien-voi-Container Queries

Các bạn sẽ thấy một vấn đề là .card giao diện hiển thị như vầy nó không ổn một chút nào cả. Vì có thể kết quả mà chúng ta muốn là như dưới đây. Nếu vậy thì có thể chúng ta sẽ dùng MQ cho màn hình < 900px thay đổi flex-direction: column là xong xuôi.

/* Media queries */
@media screen and (max-width: 900px) {
  .card {
    flex-direction: column;
  }
}
Responsive-giao-dien-voi-Container Queries

Tuy nhiên chúng ta sẽ gặp một vấn đề nữa là khi màn hình < 800px thì Sidebar đã bị ẩn cho nên thằng Main sẽ tràn ra chiếm hết diện tích và lúc này thằng .card nó bị như dưới thì lại xấu quá, đáng lẽ nó nên nằm ngang như ở màn hình máy tính thì có lẽ sẽ đẹp hơn.

/* Media queries */
@media screen and (max-width: 800px) {
  .sidebar {
    display: none;
  }
  .wrapper {
    display: block;
  }
  .card {
    flex-direction: row;
  }
}
Responsive-giao-dien-voi-Container Queries

Để giải quyết nó thì chúng ta lại phải code thêm MQ cho một màn hình < 800px cho nó flex-direction: row lại, rồi khi màn hình < 480px thì lại thiết lập flex-direction: column lại nữa. Đọc thôi là thấy code rất chi là nhiều và rối rồi đó

@media screen and (max-width: 480px) {
  .card {
    flex-direction: column;
  }
}
Responsive-giao-dien-voi-Container Queries

Dùng MQ phức tạp quá, nhưng không sao, Container Queries đến để giải cứu vấn đề này. Để sử dụng CQ, thì chúng ta sẽ code vào phần tử bao ngoài chứa phần tử bên trong mà chúng ta muốn xử lý giao diện. Đối với cấu trúc HTML ở trên thì thằng chúng ta muốn xử lý giao diện là .card, và phần tử bao ngoài của nó(trong trường hợp này) là .main

Tham khảo việc làm CSS Hồ Chí Minh hấp dẫn trên TopDev

DÀNH CHO BẠN:

Mình có khoá học HTML CSS từ cơ bản tới nâng cao cho người mới, nếu bạn quan tâm thì bạn có thể học thử miễn phí bằng việc nhấn vào đây nha.

Lưu ý: Phần tử sử dụng Container Queries không nhất thiết phải là thằng gần nhất, tùy thuộc vào logic của giao diện.

/* container queries */
.main {
  container-name: card;
  container-type: inline-size;
}
@container card (max-width: 500px) {
  .card {
    flex-direction: column;
  }
}

Như các bạn thấy đoạn code ở trên thì để sử dụng CQ, ở class .main mình sử dụng đoạn container-name: card và container-type: inline-size. Container name là không bắt buộc, tuy nhiên mình khuyến khích các bạn đặt tên cho dễ nhận biết nhé

Để sử dụng thì các bạn viết như này, nhớ thay ContainerName thành tên nào tùy vào logic của các bạn nha.

.some-class{
  container-name: ContainerName;
  container-type: inline-size;
}
@container ContainerName (min or max width, h
  // code
}

Các bạn có thể xem trực tiếp kết quả của ví dụ từ nãy đến giờ dưới này hoặc nhấn vào đây để xem toàn trang nhé.

Lưu ý: Phần tử sử dụng Container Queries thì không áp dụng @container vào chính nó được, mà chỉ áp dụng vào phần tử con của nó như mình đã làm ví dụ ở trên. Một ví dụ sai ở dưới đây cho các bạn biết mà tránh.

.main {
  container-name: card;
  container-type: inline-size;
}
@container card (max-width: 500px) {
  .main {
    flex-direction: column;
  }
}

Hi vọng thông qua kiến thức mới này sẽ giúp các bạn sẽ có thêm cách về việc xử lý giao diện Responsive một cách xịn xò hơn. Ngoài ra các bạn có thể nhấn vào đây để tham khảo thêm nhiều giao diện có sử dụng Container Queries cực xịn xò của tác giả IShadeed. Cuối cùng mấu chốt để hiểu và làm tốt đó chính là thực hành nhiều vào các bạn nhé.

Bài viết gốc được đăng tải tại evondev.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev