Tầng thiết kế công trình

Cùng khám phá quy trình và các công cụ được dùng để tạo ra trải nghiệm theo phong cách lịch ngày lễ của Designcember.

Nhân dịp tháng 12 và nhiều lịch mà mọi người dùng để đếm ngược và ăn mừng, chúng tôi muốn giới thiệu nội dung trên web của cộng đồng và nhóm Chrome. Mỗi ngày, chúng tôi đều làm nổi bật một nội dung liên quan đến thiết kế và phát triển giao diện người dùng, tổng cộng có 31 nội dung nổi bật, trong đó có 26 trang web minh hoạ, công cụ, thông báo, podcast, video, bài viết và nghiên cứu điển hình mới.

Xem toàn bộ trải nghiệm tại designcember.web.app.

Trang web Designcember.

Tổng quan

Mục tiêu của chúng tôi là mang đến một trải nghiệm web dễ tiếp cận, độc đáo, hiện đại và thích ứng với ít byte nhất có thể. Chúng tôi muốn làm nổi bật các API thích ứng mới như truy vấn vùng chứa, đồng thời đưa ra một ví dụ đẹp về chế độ tối trong một trang web tập trung vào thiết kế và có nhiều thành phần. Để đạt được điều này, chúng tôi đã nén các tệp, cung cấp nhiều định dạng, sử dụng các công cụ xây dựng được tối ưu hoá để tạo trang web tĩnh, cung cấp một polyfill mới, v.v.

Bắt đầu bằng sự hóm hỉnh

Ý tưởng về trang web lịch Designcember là để giới thiệu tất cả những công việc mà chúng tôi muốn làm nổi bật trong suốt tháng 12, đồng thời hoạt động như một trang web minh hoạ. Chúng tôi quyết định xây dựng một toà nhà chung cư có khả năng thích ứng, có thể cao hơn và hẹp hơn, hoặc thấp hơn và rộng hơn, với các cửa sổ tự sắp xếp lại trong khung. Mỗi cửa sổ đại diện cho một ngày (và do đó, một nội dung). Chúng tôi đã hợp tác với hoạ sĩ minh hoạ Alice Lee để hiện thực hoá ý tưởng của mình.

Bản phác thảo cấu trúc trang Designcember.

Alice là một người truyền cảm hứng, cô ấy chia sẻ các quy trình và bản phác thảo thú vị ngay cả trong những ý tưởng ban đầu. Trong khi cô ấy làm việc về nghệ thuật, chúng tôi đã tìm hiểu về kiến trúc. Các cuộc thảo luận ban đầu xoay quanh bố cục tổng thể, toà nhà và các cửa sổ của toà nhà. Các cửa sổ sẽ điều chỉnh như thế nào cho phù hợp với một, hai hoặc ba cột khi có thêm không gian khung hiển thị? Chúng có thể co lại hoặc giãn ra bao xa? Kích thước tối đa của toà nhà là bao nhiêu? Các cửa sổ sẽ dịch chuyển bao nhiêu?

Dưới đây là bản xem trước của một nguyên mẫu thích ứng sử dụng grid-auto-flow: dense cho thấy cách thuật toán lưới có thể tự động đặt các cửa sổ. Chúng tôi nhanh chóng nhận ra rằng mặc dù các lưới tỷ lệ khung hình hoạt động hiệu quả trong việc giới thiệu tác phẩm nghệ thuật, nhưng chúng không cho phép các cửa sổ tăng và giảm kích thước vào không gian có sẵn không đồng nhất, cũng như không thể hiện được sức mạnh của các truy vấn vùng chứa.

Ảnh động cho thấy cách khung này phản hồi với nhiều kích thước màn hình.
Xem bản minh hoạ này trên CodePen.

Sau khi lưới chung tương đối ổn định và truyền tải được cảm giác về hướng cho khả năng phản hồi của toà nhà và các cửa sổ của nó, chúng tôi có thể tập trung vào một cửa sổ duy nhất. Một số cửa sổ được kéo giãn, thu nhỏ, nén, mở rộng và sắp xếp lại nhiều hơn các cửa sổ khác trong lưới.

Khung hình cho thấy cách các cửa sổ hiển thị ở nhiều điểm ngắt.

Mỗi cửa sổ sẽ cần xử lý một lượng nhất định các thay đổi kích thước. Dưới đây là một nguyên mẫu của cửa sổ minh hoạ khả năng phản hồi của cửa sổ đối với sự nhiễu loạn, cho thấy mức độ điều chỉnh mà chúng ta có thể mong đợi ở mỗi cửa sổ tương tác.

Ảnh động cửa sổ bằng bảng chỉ dẫn

Một số cửa sổ có ảnh động để tăng thêm mức độ tương tác cho trải nghiệm. Các ảnh động được vẽ bằng tay, từng khung hình một, trong Photoshop. Mỗi khung hình được xuất, chuyển thành một bảng kết hợp hình ảnh bằng trình tạo bảng kết hợp hình ảnh này, sau đó được tối ưu hoá bằng Squoosh. Sau đó, ảnh động CSS sẽ dùng background-position-xanimation-timing-function như trong ví dụ sau.

.una
  background: url("/day1/una_sprite.webp") 0% 0%;
  background-size: 400% auto;
}

.day:is(:hover, :focus-within) .una {
  animation: una-wave .5s steps(1) alternate infinite;
}

@keyframes una-wave {
  0%  { background-position-x: 0%; }
  25% { background-position-x: 300%; }
  50% { background-position-x: 200%; }
  75% { background-position-x: 100%; }
}

Ảnh động minh hoạ cửa sổ cho ngày đầu tiên.

Một số ảnh động, chẳng hạn như ống heo của ngày thứ 6, là ảnh động CSS theo bước. Chúng tôi đã đạt được hiệu ứng này bằng một kỹ thuật tương tự, sử dụng steps(), nhưng khác ở chỗ các khung hình chính là vị trí biến đổi CSS thay vì vị trí nền.

Tạo mặt nạ CSS

Một số cửa sổ có hình dạng độc đáo. Chúng tôi đã sử dụng mặt nạaspect-ratio để tạo một cửa sổ có thể mở rộng, có hình dạng độc đáo và thích ứng.

Để tạo một mặt nạ, chẳng hạn như mặt nạ này cho cửa sổ 8, bạn cần có một số kỹ năng cơ bản về Photoshop, cộng với một chút kiến thức về cách hoạt động của mặt nạ trên web. Hãy xem cửa sổ cho ngày thứ 8.

Khoảng thời gian cho ngày thứ tám.

Để trở thành một mặt nạ, hình dạng bên trong của loại cỏ ba lá phải được tách biệt thành hình dạng riêng và được tô màu trắng. Màu trắng cho biết CSS sẽ giữ lại nội dung nào và không giữ lại nội dung nào nằm ngoài màu trắng. Trong Photoshop, phần bên trong cửa sổ được chọn, làm mờ 1px (để loại bỏ các vấn đề về răng cưa), sau đó được tô màu trắng và xuất ở cùng chiều cao và chiều rộng với khung cửa sổ. Nhờ đó, khung và mặt nạ có thể được xếp lớp trực tiếp lên nhau, cho thấy nội dung bên trong khung như mong đợi.

Hình ảnh mặt nạ hình cỏ ba lá

Sau khi hoàn tất, nội dung của cửa sổ có thể được sửa đổi và sẽ luôn xuất hiện trong khung hình tuỳ chỉnh. Hình ảnh sau đây cho thấy phiên bản chế độ tối của cửa sổ, với một hiệu ứng chuyển màu nền khác và bộ lọc CSS phát sáng được áp dụng cho ánh sáng.

Cửa sổ cho ngày thứ 8 ở chế độ tối.

Tính năng che phủ cũng hỗ trợ các cửa sổ dựa trên truy vấn vùng chứa thích ứng. Trong cửa sổ thứ 9, có một nhân vật bị che khuất sau chiếc mặt nạ cho đến khi cửa sổ có kích thước hẹp hơn. Để đảm bảo người dùng không thể điều chỉnh hình ảnh ra khỏi khung hình, Alice đã hoàn thành toàn bộ nhân vật cho chúng tôi. Nhân vật được che trong cửa sổ, nhưng các loài thực vật thì không. Vì vậy, một thách thức khác mà chúng tôi phải đối mặt là xếp lớp các phần tử được che với các lớp không được che và đảm bảo rằng tất cả các phần tử đều được điều chỉnh tỷ lệ tốt với nhau.

Hình ảnh sau đây cho thấy giao diện của cửa sổ và nhân vật khi không có mặt nạ.

Hình ảnh cho cửa sổ thứ 9 không có mặt nạ.

Bóp méo tác phẩm nghệ thuật

Để duy trì độ trung thực của hình minh hoạ và đảm bảo màn hình có độ phân giải cao sẽ không mang lại trải nghiệm mờ cho người dùng, Alice đã làm việc với tỷ lệ pixel là 3x. Kế hoạch là sử dụng imgix và phân phát các hình ảnh cũng như định dạng được tối ưu hoá trên máy chủ của họ, nhưng chúng tôi nhận thấy rằng việc điều chỉnh thủ công bằng công cụ Squoosh có thể giúp chúng tôi tiết kiệm 50% trở lên.

Sử dụng Squoosh để nén hình ảnh.

Hình minh hoạ có những thách thức riêng về việc nén, đặc biệt là nét vẽ và phong cách cạnh thô trong suốt mà Alice đã sử dụng. Chúng tôi chọn Squoosh từng hình ảnh png được xuất 3 lần trong Photoshop thành một hình ảnh png, webp và avif nhỏ hơn. Mỗi loại tệp có khả năng nén đặc biệt riêng và tôi đã phải nén hơn 50 hình ảnh để tìm ra một số chế độ cài đặt tối ưu hoá phổ biến.

Squoosh CLI trở nên quan trọng khi có hơn 200 hình ảnh cần tối ưu hoá. Nếu làm tất cả những việc đó theo cách thủ công, bạn sẽ mất nhiều ngày. Sau khi có các chế độ cài đặt tối ưu hoá chung, chúng tôi cung cấp các chế độ này dưới dạng hướng dẫn dòng lệnh và xử lý hàng loạt toàn bộ thư mục hình ảnh PNG thành các phiên bản nén WebP và AVIF.

Sau đây là ví dụ về lệnh squoosh CLI AVIF được dùng:

npx @squoosh/cli --quant '{"enabled":true,"zx":0,"maxNumColors":256,"dither":1}' --avif '{"cqLevel":19,"cqAlphaLevel":17,"subsample":1,"tileColsLog2":0,"tileRowsLog2":0,"speed":6,"chromaDeltaQ":false,"sharpness":5,"denoiseLevel":0,"tune":0}' image-1.png image-2.png image-3.png

Sau khi kiểm tra tác phẩm nghệ thuật đã tối ưu hoá vào kho lưu trữ, chúng tôi có thể bắt đầu tải tác phẩm nghệ thuật đó từ HTML:

<picture>
  <source srcset="/day1/inner-frame.avif" type="image/avif">
  <source srcset="/day1/inner-frame.webp" type="image/webp">
  <img alt="" decoding="async" role="presentation" src="/day1/inner-frame.png">
</picture>

Việc viết mã nguồn hình ảnh lặp đi lặp lại, vì vậy chúng tôi đã tạo một thành phần Astro để nhúng hình ảnh bằng một dòng mã.

<Pic filename="day1/inner-frame" role="presentation" />

Người dùng trình đọc màn hình và bàn phím

Phần lớn trải nghiệm Designcember là thông qua các tác phẩm nghệ thuật và cửa sổ tương tác. Điều quan trọng đối với chúng tôi là người dùng bàn phím có thể sử dụng trang web và xem trước các cửa sổ, đồng thời người dùng trình đọc màn hình có được trải nghiệm được tường thuật thú vị.

Ví dụ: khi nhúng hình ảnh, chúng tôi đã dùng role="presentation" để đánh dấu hình ảnh là hình ảnh trình bày cho trình đọc màn hình. Chúng tôi nhận thấy trải nghiệm người dùng với từ 5 đến 12 phần mô tả alt rời rạc sẽ là một trải nghiệm kém. Vì vậy, chúng tôi đã đánh dấu hình ảnh là hình ảnh trình bày và cung cấp nội dung tường thuật tổng thể về cửa sổ. Việc di chuyển qua các cửa sổ trên trình đọc màn hình mang lại cảm giác dễ chịu, giúp truyền tải sự thú vị và vui nhộn mà trang web muốn chia sẻ.

Video sau đây minh hoạ trải nghiệm bàn phím. Các phím tab, enter, phím cách và phím thoát đều được dùng để điều phối tiêu điểm đến và đi từ cửa sổ bật lên và cửa sổ.

Trình đọc màn hình có các thuộc tính ARIA đặc biệt giúp nội dung trở nên rõ ràng. Ví dụ: các đường liên kết cho các ngày chỉ có nội dung "một" hoặc "hai", nhưng khi thêm một số ARIA, các đường liên kết này sẽ được thông báo là "Ngày một" và "Ngày hai". Hơn nữa, tất cả hình ảnh đều được tóm tắt trong một nhãn duy nhất để mỗi cửa sổ đều có nội dung mô tả.

Astro, trình tạo trang web dựa trên thành phần, tĩnh đầu tiên

Astro giúp nhóm dễ dàng làm việc cùng nhau trên trang web. Mô hình thành phần quen thuộc với cả nhà phát triển Angular và React, trong khi hệ thống kiểu tên lớp có phạm vi giúp mỗi nhà phát triển biết rằng công việc của họ trên một cửa sổ sẽ không xung đột với bất kỳ ai khác.

Số ngày dưới dạng thành phần

Mỗi ngày là một thành phần lấy trạng thái từ kho lưu trữ dữ liệu thời gian xây dựng. Điều này cho phép chúng tôi chạy logic mẫu trước khi HTML đến được trình duyệt. Logic này sẽ xác định xem ngày có hiển thị chú thích hay không, vì những ngày không hoạt động sẽ không có cửa sổ bật lên.

Các bản dựng được chạy mỗi giờ và kho lưu trữ dữ liệu thời gian xây dựng sẽ mở khoá một ngày mới khi máy chủ xây dựng đã qua nửa đêm. Những hệ thống nhỏ, tự cập nhật và tự duy trì này giúp trang web luôn được cập nhật.

Kiểu có phạm vi và Open Props

Astro phạm vi các kiểu được viết bên trong mô hình thành phần của nó, giúp việc phân phối khối lượng công việc giữa nhiều thành viên trong nhóm trở nên dễ dàng hơn, đồng thời giúp việc sử dụng Open Props trở nên thú vị. Các kiểu Open Props normalize.css rất hữu ích với giao diện thích ứng (sáng và tối), cũng như giúp sắp xếp nội dung như đoạn văn và tiêu đề.

Là những người dùng sớm Astro, chúng tôi gặp phải một số vấn đề với PostCSS. Ví dụ: chúng tôi không thể cập nhật lên phiên bản Astro mới nhất do có quá nhiều vấn đề về bản dựng. Bạn có thể dành nhiều thời gian hơn cho việc tối ưu hoá bản dựng và quy trình làm việc của nhà phát triển.

Vùng chứa linh hoạt

Một số cửa sổ sẽ tăng và giảm kích thước, duy trì tỷ lệ khung hình để giữ nguyên hình ảnh. Chúng tôi đã sử dụng một số cửa sổ khác để minh hoạ sức mạnh của cấu trúc dựa trên thành phần bằng các truy vấn vùng chứa. Các truy vấn vùng chứa có nghĩa là các cửa sổ có thể sở hữu thông tin tạo kiểu thích ứng riêng và điều chỉnh lại dựa trên kích thước của chính chúng. Một số cửa sổ chuyển từ hẹp sang rộng và cần điều chỉnh kích thước của nội dung nghe nhìn trong đó, cũng như vị trí của nội dung nghe nhìn đó.

Bản minh hoạ cách các cửa sổ thay đổi khi có nhiều không gian hơn.

Khi có thêm không gian cho một cửa sổ, chúng ta có thể điều chỉnh kích thước hoặc các phần tử con của cửa sổ cho phù hợp. Hoá ra, để đáp ứng các cửa sổ thích ứng, truy vấn vùng chứa không chỉ thú vị khi trình bày mà còn cần thiết và giúp đơn giản hoá đáng kể việc điều phối một số bố cục nhất định.

.day {
  container: inline-size;
}

.day > .pane {
  min-block-size: 250px;

  @container (min-width: 220px) {
    min-block-size: 300px;
  }

  @container (min-width: 260px) {
    min-block-size: 310px;
  }

  @container (min-width: 360px) {
    min-block-size: 450px;
  }
}

Phương pháp này khác với việc duy trì tỷ lệ khung hình. Chiến dịch này mang đến nhiều quyền kiểm soát và nhiều cơ hội hơn. Khi đạt đến một kích thước nhất định, nhiều trẻ em sẽ thay đổi tư thế để thích ứng với bố cục mới.

Các truy vấn vùng chứa cũng cho phép chúng tôi hỗ trợ tính năng ngăn chặn theo hướng khối (dọc), vì vậy, khi cửa sổ tăng chiều dài, chúng tôi có thể điều chỉnh kiểu của cửa sổ cho phù hợp. Điều này được thể hiện trong các truy vấn dựa trên chiều cao mà chúng tôi sử dụng độc lập, ngoài các truy vấn dựa trên chiều rộng:

.person {
  place-self: flex-end;
  margin-block: 25% 50%;
  margin-inline-start: -15%;
  z-index: var(--layer-1);

  @container (max-height: 350px) and (max-width: 425px) {
    place-self: center flex-end;
    inline-size: 50%;
    inset-block-end: -15%;
    margin-block-start: -2%;
    margin-block-end: -25%;
    z-index: var(--layer-2);
  }
}

Chúng tôi cũng sử dụng các truy vấn vùng chứa để hiện và ẩn chi tiết khi hình ảnh trở nên quá dày đặc ở kích thước nhỏ hơn và trống trải hơn ở kích thước rộng hơn. Cửa sổ 9 là một ví dụ điển hình về nơi điều này phát huy tác dụng:

Hỗ trợ nhiều trình duyệt

Để tạo ra trải nghiệm hiện đại và tuyệt vời trên nhiều trình duyệt, đặc biệt là đối với các API thử nghiệm như truy vấn vùng chứa, chúng ta cần một polyfill tuyệt vời. Chúng tôi đã gửi yêu cầu đến nhóm của mình và Surma đã dẫn đầu việc tạo một polyfill truy vấn vùng chứa mới. Polyfill dựa vào ResizeObserver, MutationObserverhàm:is() của CSS. Do đó, tất cả các trình duyệt hiện đại đều hỗ trợ polyfill, cụ thể là Chrome và Edge từ phiên bản 88, Firefox từ phiên bản 78 và Safari từ phiên bản 14. Việc sử dụng polyfill cho phép dùng bất kỳ cú pháp nào sau đây:

/* These are all equivalent */
@container (min-width: 200px) {
  /* ... */
}
@container (width >= 200px) {
  /* ... */
}
@container size(width >= 200px) {
  /* ... */
}

Chế độ tối

Phiên bản chế độ sáng và tối của trang web Designcember, đặt cạnh nhau.

Một điểm cuối cùng nhưng không kém phần quan trọng đối với trang web Designcember là giao diện tối đẹp mắt. Chúng tôi muốn cho thấy cách bạn có thể sử dụng chính nghệ thuật để chủ động tham gia tạo ra trải nghiệm tuyệt vời ở chế độ tối. Để làm việc này, chúng tôi đã điều chỉnh kiểu nền của từng cửa sổ theo phương thức lập trình và sử dụng nhiều CSS nhất có thể khi tạo hình ảnh cửa sổ. Hầu hết các nền đều là hiệu ứng chuyển màu CSS, nhờ đó, việc điều chỉnh các giá trị màu sẽ dễ dàng hơn. Sau đó, chúng tôi đặt hình ảnh lên trên những hình ảnh này.

Các điều thú vị ẩn giấu khác

Chút sắc màu cá nhân

Chúng tôi đã thêm một vài điểm nhấn cá nhân vào trang để trang web có thêm cá tính. Đầu tiên là dàn nhân vật, được lấy cảm hứng từ chính đội ngũ của chúng tôi. Chúng tôi cũng thêm một con trỏ theo phong cách cổ điển vào những ngày không hoạt động và thử nghiệm với kiểu biểu tượng trang web.

Các lựa chọn về kiểu con trỏ tuỳ chỉnh và biểu tượng trang web

Các điểm chạm chức năng

Một trong những điểm nhấn chức năng bổ sung là chức năng "Chuyển đến hôm nay", với một chú chim đậu trên đỉnh toà nhà. Khi nhấp hoặc nhấn phím Enter vào chú chim này, bạn sẽ được chuyển xuống ngày hiện tại của tháng trên trang, nhờ đó bạn có thể nhanh chóng xem các thông tin ra mắt mới nhất.

Trang web Designcember cũng có một biểu định kiểu in đặc biệt, nơi chúng tôi cung cấp một hình ảnh cụ thể phù hợp nhất với giấy có kích thước 8,5" x 11" để bạn có thể tự in lịch và tận hưởng không khí lễ hội quanh năm.

Bản in thiết kế lịch có kích thước như áp phích.
Una đang cầm một bản in lớn của lịch.

Nhìn chung, chúng tôi đã nỗ lực rất nhiều để tạo ra một trải nghiệm web hiện đại, vui nhộn và độc đáo nhằm tôn vinh hoạt động phát triển giao diện người dùng trong suốt tháng 12. Chúng tôi hy vọng bạn thích video này!

Các phần của lịch có chú thích và ghi chú trực quan