Contents

Refactoring UI: Những Nguyên Tắc Thiết Kế Giao Diện Cho Developer

Contents

Là lập trình viên, mỗi lần phải đưa ra quyết định thiết kế — chọn màu button, căn khoảng cách, chọn font chữ — đều là một bài toán không có đáp án rõ ràng. Cuốn sách Refactoring UI của Adam Wathan và Steve Schoger được viết chính xác cho người như vậy.

Nguồn tham khảo
Tất cả nội dung và hình ảnh trong bài viết đều được tổng hợp từ cuốn sách Refactoring UI của Adam Wathan và Steve Schoger.

Chương 1 — Starting from scratch: Khởi đầu đúng hướng

Bắt đầu từ feature, không phải layout

Khi bắt tay vào thiết kế một ứng dụng, phản xạ tự nhiên là nghĩ đến bố cục tổng thể: “Có nên có top nav không? Sidebar bên trái hay bên phải?” Đây là một cái bẫy — chúng ta đang nghĩ về phần vỏ bên ngoài thay vì tính năng thực sự.

Một ứng dụng thực chất chỉ là tập hợp của các feature. Thay vì bắt đầu ở layout, hãy chọn một feature cụ thể và thiết kế các phần tử cốt lõi của nó trước. Ví dụ với ứng dụng đặt vé máy bay, feature đầu tiên là “tìm kiếm chuyến bay” — giao diện chỉ cần field điểm đi, điểm đến, ngày đi và nút Search.

Chi tiết đến sau

Đừng sa lầy vào icon, shadow, typeface ngay từ đầu. Một mẹo hay là phác thảo trên giấy bằng bút Sharpie — loại bút nét to khiến việc vẽ chi tiết nhỏ là điều không thể.

Phác thảo UI bằng bút Sharpie
Phác thảo bằng bút Sharpie giúp tránh sa đà vào chi tiết sớm

Thiết kế grayscale trước khi phối màu

Ban đầu chỉ thiết kế với đen và trắng (grayscale) — điều này buộc chúng ta phải chú trọng vào khoảng cách, tương phản và kích thước. Kết quả là một giao diện có tính phân cấp tốt, và màu sắc chỉ là lớp trang trí thêm vào sau.

Chọn cá tính cho thiết kế

Mỗi site cần có đặc điểm nhận dạng riêng. Ngân hàng hướng tới sự bảo mật và chuyên nghiệp; startup thì vui nhộn và tươi mới. Cá tính này thể hiện qua:

  • Font: serif cho sang trọng cổ điển, rounded sans-serif cho vui nhộn, neutral sans-serif cho đơn giản
  • Màu sắc: xanh dương gợi an toàn thân thiện, vàng kim gợi đắt đỏ tinh vi, hồng gợi vui nhộn nhẹ nhàng
  • Border radius: 3-4px hầu như không ảnh hưởng, lớn tạo năng động, không có tạo trang trọng

Chương 2 — Limit your choices: Hệ thống hóa mọi quyết định

Khi có quá nhiều lựa chọn — opacity 10% hay 15%? margin-bottom 18px hay 20px? — việc quyết định trở nên cực kỳ mệt mỏi. Giải pháp là xây dựng hệ thống ngay từ đầu thay vì chọn từ thư viện vô tận.

Định nghĩa trước:

  • Font size scale: 8-10 cỡ chữ cố định
  • Color palette: 8-10 màu cho mỗi nhóm (grays, primary, accent)
  • Spacing system: bảng khoảng cách dựa theo base 16px
  • Border radius, font weight, shadow levels
Color palette cố định
Color palette cố định — không cần mở color picker mỗi lần thiết kế
Font size scale
Font size scale cố định — thiết kế nhanh hơn và nhất quán hơn

Khi lựa chọn từ một tập hạn chế, công việc trở nên dễ dàng hơn: chọn giá trị trung tâm, so sánh với 2 giá trị kề bên, chọn cái nào “cảm giác” đúng nhất rồi dừng lại.


Chương 3 — Visual Hierarchy: Phân cấp thị giác là tất cả

Không phải mọi phần tử đều bình đẳng

Nếu mọi phần tử trong giao diện đều cùng “ấn tượng” như nhau, thiết kế sẽ trở thành một bức tường nội dung — không truyền đạt được thông điệp gì. Visual Hierarchy là cách tạo ra liên hệ giữa các phần tử để người dùng biết đâu là quan trọng.

Không có phân cấp
Không có phân cấp thị giác — mọi thứ nặng như nhau
Đã có phân cấp
Đã có phân cấp — mắt người biết nhìn vào đâu, dù font và màu không thay đổi

Font size không phải là vũ khí duy nhất

Nếu có 4-5 cấp độ thông tin, chúng ta sẽ cần 4-5 kích cỡ chữ — điều này bất hợp lý. Một site không nên dùng quá 3 font size. Thay vào đó, kết hợp màu sắcfont weight:

  • Sử dụng 2-3 màu: màu tối cho nội dung chính, xám cho nội dung phụ, xám nhạt hơn cho cấp 3
  • Sử dụng 2 font weight: 400-500 cho text thường, 600-700 cho nội dung cần nhấn mạnh
Phân cấp bằng màu và font weight
Kết hợp màu và font weight để phân cấp thông tin hiệu quả

Tránh dùng font weight dưới 400 cho các đoạn text nhỏ — chúng trông rất khó đọc.

Đừng dùng text xám trên nền có màu

Text xám trên nền có màu
Text xám trên nền có màu — tương phản kém, khó đọc

Thay vào đó, hãy chọn màu text gần với tông màu của nền — cùng hue nhưng thay đổi saturation và lightness cho phù hợp:

Text cùng tông màu
Text cùng tông màu với nền — tương phản tự nhiên

Nhấn mạnh bằng cách làm mờ xung quanh

Đôi khi không thể làm item nổi bật hơn dù đã cố gắng. Trong tình huống đó, thay vì cố nhấn mạnh item chính, hãy làm mờ các item xung quanh:

Active nav item khó phân biệt
Active nav item không nổi bật dù đã được style
De-emphasize để làm nổi active
Làm mờ các item không hoạt động — active item nổi lên tự nhiên

Kỹ thuật này cũng áp dụng được cho layout lớn hơn: sidebar đang cạnh tranh sự chú ý với nội dung chính? Bỏ background của sidebar đi, để nội dung hiển thị thẳng lên background.

Sidebar không có background
Sidebar không có background — nội dung chính nổi lên tự nhiên

Khi nào cần label, khi nào không

Hiển thị dữ liệu theo kiểu label: value là cái bẫy phổ biến — format này không có phân cấp, mọi thứ đều trông như nhau.

Trong nhiều trường hợp không cần label vì nội dung đã tự nói lên: abc@mail.com hiển nhiên là email, 01923-12312 là số điện thoại. Ngữ cảnh có thể thay thế label.

Giao diện không cần label
Ngữ cảnh thay thế label — giao diện gọn hơn, có phân cấp hơn

Khi cần kết hợp label và value, ưu tiên làm nổi value: thay vì “In stock: 12”, hãy nói “12 in stock”:

Value được nhấn mạnh
Value được đặt trước — người đọc nắm thông tin quan trọng ngay lập tức

Khi thực sự cần label (như trong dashboard nhiều dữ liệu), hãy de-emphasize label và làm nổi value:

Label de-emphasized
Label nhạt đi, value nổi lên — phân cấp rõ ràng hơn

Cân bằng weight và contrast

Font bold nổi bật hơn regular vì chiếm nhiều diện tích hơn. Khi kết hợp text và icon, icon thường nổi bật hơn — nhưng không thể chỉnh weight của icon. Giải pháp: dùng màu nhạt hơn cho icon:

Icon nhạt hơn text
Icon nhạt màu hơn text — cân bằng tốt hơn dù icon nặng hơn về mặt thị giác

Ngược lại, với border mỏng màu nhạt, có thể tăng width của border thay vì làm tối màu để giữ nguyên màu sắc mà vẫn tạo được sự phân cách:

Tăng width border
Tăng width border thay vì màu tối — giữ được tính nhẹ nhàng

Phân cấp các action

Trong mỗi trang thường có 1 primary action, 2-3 secondary, và một số tertiary. Thiết kế theo ngữ nghĩa mà bỏ qua phân cấp sẽ tạo ra giao diện hỗn loạn:

  • Primary: background tương phản cao, solid
  • Secondary: outline hoặc màu tương phản thấp
  • Tertiary: style như link, không có background
Phân cấp action
Các action được phân cấp rõ — người dùng biết hành động nào ưu tiên

Destructive action (xóa, hủy) không mặc nhiên là primary. Chỉ khi đi kèm với bước xác nhận thì nó mới nên là primary:

Destructive action phân cấp
Destructive action không phải lúc nào cũng cần đỏ và nổi bật

Chương 4 — Layout và Spacing: Bố cục và khoảng trắng

Đừng ép element lấp đầy toàn màn hình

Màn hình rộng không có nghĩa phải dùng hết. Nếu element chỉ cần 600px, hãy chỉ dùng 600px và tạo khoảng không gian xung quanh:

Element không cần full width
Navigation full-width không có nghĩa các element khác cũng vậy
Khoảng cách phù hợp
Cho element không gian vừa đủ — không nhiều hơn, không ít hơn

Khi cần responsive, bắt đầu từ mobile (400px) rồi tăng dần canvas. Với layout có sidebar, đặt sidebar fixed width và để MainContent thay đổi — tránh dùng % vì sidebar sẽ bị vỡ khi màn hình quá hẹp:

Sidebar fixed width
Sidebar fixed width, MainContent fluid — responsive tốt hơn

Sizing tương đối không tự động scale

Khi body text 18px và title 45px (tỉ lệ 2.5x) trên desktop, nếu áp dụng cứng tỉ lệ đó cho mobile (body 14px → title 35px), title sẽ quá lớn so với màn hình nhỏ. Thực tế title 24px sẽ phù hợp hơn nhiều — tỉ lệ thực là 1.7x:

Title quá lớn trên mobile
Title 35px trên mobile theo tỉ lệ cố định — quá lớn
Title phù hợp trên mobile
Title 24px — tỉ lệ nhỏ hơn nhưng cảm giác phù hợp hơn cho màn hình nhỏ

Bắt đầu với quá nhiều khoảng trắng

Khi thiết kế có cảm giác chật chội, thói quen là thêm margin — nhưng thường chỉ thêm được ít nên không cải thiện nhiều. Cách tốt hơn: bắt đầu với rất nhiều khoảng trắng, sau đó thu hẹp dần cho đến khi cảm thấy ổn.

Nhiều khoảng trắng
Bắt đầu với nhiều khoảng trắng — hơi nhiều thực ra rất gần với vừa đủ

Hệ thống spacing thay vì căn từng pixel

Xây dựng hệ thống spacing dựa trên base 16px. Các kích cỡ nhỏ gần nhau, kích cỡ lớn cách xa nhau dần:

Hệ thống spacing
Hệ thống spacing — thiết kế nhanh hơn và nhất quán hơn

Khoảng cách phải làm rõ mối liên hệ

Khi khoảng cách giữa label và input bằng nhau theo mọi hướng, người dùng không biết label nào thuộc về input nào:

Khoảng cách không rõ ràng
Khoảng cách đều nhau — không có sự liên kết rõ ràng
Khoảng cách rõ ràng
Khoảng cách phía dưới input lớn hơn — label gắn chặt với input của nó
Quy tắc Proximity
Khoảng cách xung quanh một group elements luôn phải lớn hơn khoảng cách bên trong group đó.

Chương 5 — Typography: Thiết kế chữ viết

Hệ thống font size

Quá nhiều font size trong một thiết kế khiến giao diện thiếu nhất quán. Không nên dùng modular scale (golden ratio…) vì thường cho kết quả phân số và thiếu các kích cỡ trung gian. Cách thực tế nhất là tự tạo bằng tay 8-10 kích cỡ phù hợp:

Hệ thống font size
Hệ thống font size — chọn từ tập cố định thay vì tuỳ hứng

Tránh dùng đơn vị em cho font size

Đơn vị em là tương đối — phụ thuộc vào font size của element cha. Khi có nested elements, giá trị em sẽ cascade và tạo ra kết quả không mong muốn:

Vấn đề với đơn vị em
Cascading với đơn vị em — phần tử con có font size 20px dù được khai báo 1em

Hãy dùng px hoặc rem để bảo toàn thiết kế.

Chiều rộng dòng lý tưởng: 45-75 ký tự

Khi styling paragraph, lỗi phổ biến là kéo text ra full width của container — dòng dài khó đọc. Chiều rộng lý tưởng là 45-75 ký tự, tương đương 20-35em:

Dòng văn bản quá dài
Dòng quá dài — mắt mệt mỏi khi theo dõi từ đầu sang cuối

Line-height và font size tỉ lệ nghịch

  • Text nhỏ: cần line-height cao (1.5-2.0) để mắt dễ tìm dòng tiếp theo
  • Heading lớn: chỉ cần line-height thấp (1.0-1.25)
Line-height cho text nhỏ
Text nhỏ cần line-height rộng để dễ đọc
Line-height cho heading
Text lớn chỉ cần line-height ngắn — line-height 1.0 là đủ

Căn baseline khi kết hợp nhiều font size

Khi kết hợp nhiều cỡ chữ trong một dòng, căn giữa (vertical center) trông vụng về. Căn theo baseline — đường kẻ ngang làm chân đế của ký tự — tự nhiên hơn nhiều:

Căn baseline
Căn baseline — nhiều font size cùng dòng nhưng vẫn liên kết tự nhiên

Căn lề text đúng ngữ cảnh

  • Center align: phù hợp với headline ngắn, text block độc lập — không dùng cho đoạn văn dài hơn 2-3 dòng
  • Right align: dành riêng cho dữ liệu số trong bảng để dễ so sánh
  • Left align: mặc định cho mọi nội dung văn bản
Căn phải cho số liệu
Căn phải cho số liệu — so sánh giữa các hàng dễ dàng hơn nhiều

Tăng letter-spacing cho all-caps

Với text chỉ toàn chữ hoa, các ký tự có cùng chiều cao nên letter-spacing mặc định khiến việc đọc khó hơn. Hãy tăng letter-spacing để phân biệt giữa các ký tự:

All-caps khó đọc
All-caps với letter-spacing mặc định — khó đọc
All-caps dễ đọc
All-caps với letter-spacing tăng — dễ đọc hơn nhiều

Chương 6 — Working with Color: Làm chủ màu sắc

Chuyển sang HSL thay vì hex

Hex code (#3d5af1) không trực quan. HSL hiển thị màu theo cách mắt người cảm nhận:

  • Hue: vị trí trên bánh xe màu (0° = đỏ, 120° = xanh lá, 240° = xanh dương)
  • Saturation: mức độ sống động (0% = xám, 100% = sống động)
  • Lightness: mức độ sáng tối (0% = đen, 50% = màu thuần, 100% = trắng)

Cần nhiều màu hơn bạn nghĩ

Bảng màu thực dụng cần ít nhất 3 loại:

Grays — dùng cho text, background, panel. Cần 8-10 sắc độ:

Bảng màu gray
Bảng màu gray đầy đủ — từ background sáng đến text tối

Primary color(s) — màu nhận diện thương hiệu, cần 5-10 sắc độ (ultra-light cho background alert, darker cho text):

Primary color palette
Primary color với nhiều sắc độ — đủ dùng cho mọi ngữ cảnh

Accent colors — màu trạng thái: đỏ cho xóa/hủy, vàng cho warning, xanh lá cho thành công. Mỗi accent cũng cần 5-10 sắc độ.

Xây dựng palette màu đúng cách

Hãy tạo 9 shades từ 100 đến 900:

  1. Chọn màu base (phù hợp làm button background)
  2. Chọn shade tối nhất (dùng cho text) và sáng nhất (dùng cho background)
  3. Điền các shade trung gian sao cho chúng dung hòa với 2 biên
9 shades palette
9 shades từ 100-900 — đủ dùng mà không bị giới hạn

Giữ saturation khi điều chỉnh lightness

Trong HSL, khi lightness tiến về 0% hoặc 100%, saturation mất dần ảnh hưởng. Để các sắc độ lighter/darker vẫn giữ được màu sống động, hãy tăng saturation khi lightness ra xa 50%:

Tăng saturation
Tăng saturation khi lightness ra xa 50% — màu giữ được độ sống động

Thay đổi độ sáng bằng cách xoay hue

Chỉ thay đổi lightness sẽ khiến màu trở nên trắng hoặc đen hơn, làm mất cường độ màu. Thay vào đó, xoay hue:

  • Để làm sáng: xoay hue về phía 60°, 180°, hoặc 300°
  • Để làm tối: xoay hue về phía 0°, 120°, hoặc 240°
Xoay hue để thay đổi độ sáng
Kết hợp xoay hue và đổi lightness — màu vẫn sống động ở cả sắc độ tối và sáng

Đừng xoay hue quá 20-30° nếu không muốn có màu hoàn toàn khác.

Gray cũng có thể có màu

True grey có saturation 0% — không có màu thực sự. Trong thực tế, grey có thể “ấm” hơn bằng cách thêm một chút vàng/cam, hoặc “mát” hơn bằng cách thêm một chút xanh dương:

Cool grey
Grey với chút blue saturation — cảm giác mát và hiện đại hơn

Đừng chỉ dựa vào màu sắc

Với người dùng có thị giác màu kém, giao diện phụ thuộc hoàn toàn vào màu sẽ không truyền đạt được thông tin. Hãy thêm các yếu tố phụ như mũi tên lên/xuống cho trend, icon để phân biệt trạng thái:

Hỗ trợ người dùng mù màu
Thêm mũi tên để hỗ trợ người dùng mù màu phân biệt trend

Chương 7 — Creating Depth: Tạo chiều sâu

Giả lập nguồn sáng từ trên xuống

Ánh sáng luôn đến từ phía trên. Để tạo hiệu ứng “nổi” hay “chìm”, hãy mô phỏng nguyên tắc này:

  • Raised elements (nổi): cạnh trên sáng hơn, có bóng nhỏ phía dưới
  • Inset elements (chìm): inset shadow từ trên, bottom border sáng nhạt
Raised button
Button raised — ánh sáng từ trên, bóng đổ xuống dưới
Inset input
Input inset — ánh sáng phía dưới, bóng đổ vào trong từ trên

Dùng shadow để biểu thị khoảng cách trục Z

Shadow nhỏ + blur nhẹ = element chỉ cao hơn bề mặt một chút. Shadow lớn + blur mạnh = element gần người dùng hơn. Hãy xây dựng sẵn 5 mức shadow từ nhỏ đến lớn:

Hệ thống shadow
Hệ thống shadow từ nhỏ đến lớn — tương ứng với khoảng cách trục Z

Shadow cũng phản ánh tương tác — item đang drag có shadow lớn hơn, button khi nhấn giảm shadow:

Shadow khi nhấn button
Shadow giảm khi button được nhấn — phản ánh tương tác vật lý

Shadow có thể có 2 tầng

Trong thực tế, shadows thường có 2 phần:

  • Tầng 1: lớn hơn, blur lớn hơn — mô phỏng shadow từ nguồn sáng trực tiếp
  • Tầng 2: nhỏ hơn, tối hơn, blur nhỏ hơn — shadow phía dưới object
Shadow 2 tầng
Shadow 2 tầng — tự nhiên và chiều sâu hơn so với shadow đơn

Tạo chiều sâu bằng cách xếp chồng element

Di chuyển card để nằm ở vùng chuyển giao giữa 2 background khác nhau — tạo cảm giác “đa tầng”:

Card overlap background
Card overlap 2 background — tạo cảm giác đa tầng tự nhiên

Chương 8 — Finishing Touches: Đánh bóng thiết kế

Tận dụng tối đa những gì đang có

Trước khi thêm element mới, hãy khai thác những gì đã có:

  • Thay bullet list bằng icon phù hợp ngữ cảnh (khóa cho bảo mật, check cho tính năng…)
  • Tạo quote block với font size lớn hơn và màu khác để làm điểm nhấn
  • Style custom checkbox, radio button với màu nhận diện thay vì màu browser mặc định
Quote được style
Quote được style nổi bật — cùng nội dung nhưng tạo ấn tượng tốt hơn

Dùng accent border thêm màu sắc

Thêm colored accent border vào các phần tử để tạo điểm nhấn mà không thay đổi nhiều thiết kế — border-top của card, border-bottom của active nav item, cạnh trái của alert message:

Accent border trên card
Accent border-top trên card — thêm màu sắc mà không tốn thêm không gian

Hạn chế dùng border — có 3 lựa chọn tốt hơn

Border tạo ra sự phân mảnh và thu hút sự chú ý không cần thiết. Thay vào đó:

  1. Box-shadow nhẹ — phân cách tinh tế
  2. Hai background color khác nhau — element cạnh nhau có nền xám nhạt và trắng
  3. Thêm khoảng cách — khoảng trắng đủ lớn tự tạo ra ranh giới
Hai background color để phân cách
Hai background color khác nhau — phân cách rõ mà không cần border

Thiết kế empty states

Empty state là tương tác đầu tiên của người dùng với một feature mới — đây là cơ hội tạo ấn tượng tốt. Đừng để màn hình trống rỗng, hãy thêm illustration và call-to-action rõ ràng:

Empty state tốt
Empty state với illustration và call-to-action — khuyến khích người dùng bắt đầu

Thoát ra khỏi khuôn mẫu

Hầu như chúng ta đều có định kiến về cách một component phải trông như thế nào. Dropdown phải là danh sách thẳng? Radio button phải là vòng tròn nhàm chán? Hãy thử phá vỡ quy ước:

Dropdown phong phú
Dropdown multi-column với icon — phong phú hơn mà vẫn dễ dùng
Selectable card thay radio button
Selectable card thay cho radio button — trực quan và hấp dẫn hơn

Leveling up — Cách trau dồi thêm

Khi bắt gặp một thiết kế đẹp, hãy tự hỏi: “Designer đã thực hiện điều gì mà mình có thể sẽ không bao giờ làm?” Ví dụ: thêm background color cho date-picker, đặt button bên trong text input, dùng 2 màu chữ cho headline.

Cách tốt nhất để chú ý đến chi tiết là xây dựng lại thiết kế đó từ đầu — khi nhận ra sự khác biệt, chúng ta sẽ khám phá ra những tricks như giảm line-height cho heading, tăng letter-spacing cho uppercase, kết hợp nhiều box-shadow.

Rebuild thiết kế
Rebuild một thiết kế đẹp từ đầu — cách học hiệu quả nhất