Mở đầu — vì sao bài này quan trọng
Bạn có bao giờ nhìn vào một giao diện và cảm thấy nó "sai sai" mà không chỉ ra được lý do chưa? Rất nhiều lần, thủ phạm chính là border radius — độ bo tròn của các góc. Một chiếc nút có góc bo 6px, cái card bên cạnh bo 10px, ô input bo 4px, và cái modal bao ngoài lại bo 16px. Từng thành phần nhìn riêng lẻ thì ổn, nhưng đặt cạnh nhau chúng tạo ra một cảm giác lộn xộn, thiếu chuyên nghiệp mà mắt thường khó gọi tên.
Border radius nghe có vẻ là chi tiết nhỏ nhặt, nhưng thực ra nó là một trong những "vân tay thị giác" quyết định tính cách của sản phẩm. Góc vuông sắc cạnh gợi cảm giác nghiêm túc, kỹ thuật, đáng tin (nghĩ đến các ngân hàng, phần mềm doanh nghiệp). Góc bo tròn mềm mại gợi sự thân thiện, gần gũi, hiện đại (nghĩ đến các app tiêu dùng, fintech dành cho người trẻ). Chọn sai — hoặc tệ hơn là chọn không nhất quán — bạn đang gửi đi những tín hiệu mâu thuẫn cho người dùng.
Trong bài này, chúng ta sẽ biến border radius từ một con số bạn "gõ đại" thành một hệ thống có kỷ luật. Bạn sẽ học cách xây một radius scale, hiểu nguyên tắc nested radius (bo lồng nhau), biết khi nào dùng radius.full, và tránh những lỗi kinh điển mà designer junior hay mắc. Đây là mảnh ghép tiếp nối tự nhiên sau khi bạn đã có spacing system, typography system và elevation — tất cả cùng nhau tạo nên nền tảng của một design system chỉn chu.
Khái niệm cốt lõi
Border radius là gì và nó "nói" điều gì
Border radius là bán kính của đường cong tại góc một hình chữ nhật, đo bằng pixel (hoặc rem/dp tùy nền tảng). Radius bằng 0 cho ra góc vuông tuyệt đối; radius càng lớn thì góc càng tròn. Khi radius bằng hoặc lớn hơn một nửa chiều cao của phần tử, bạn được một hình viên thuốc (pill) hoặc hình tròn hoàn hảo.
Điều quan trọng cần hiểu: radius không phải là quyết định thẩm mỹ ngẫu nhiên. Nó mang tính "brand". Một thương hiệu như VPBank hay Techcombank khi làm app thường chọn radius vừa phải (8–12px) để cân bằng giữa sự nghiêm túc của ngành tài chính và sự thân thiện cần có để giữ chân người dùng trẻ. Ngược lại, một app như Momo hay ZaloPay có xu hướng bo tròn nhiều hơn, mềm mại hơn, phù hợp với định vị "vui vẻ, tiện lợi, đại chúng".
Xây dựng một Radius Scale
Cũng như spacing hay typography, radius cần một scale — một tập hợp giá trị được đặt tên, có tính hệ thống, thay vì những con số tùy hứng. Đây là scale tiêu chuẩn mà bạn nên bắt đầu:
radius.none = 0 → góc vuông tuyệt đối
radius.sm = 4 → chi tiết nhỏ: tag, badge, checkbox
radius.md = 8 → mặc định: button, input, dropdown
radius.lg = 12 → card, panel, alert box
radius.xl = 16 → container lớn, section
radius.2xl = 24 → modal, bottom sheet, hero card
radius.full = 999 → pill button, avatar, toggle, chip tròn
Vì sao lại là những con số này? Chúng nhân đôi hoặc tăng theo bậc dễ nhớ (4, 8, 12, 16, 24), gắn liền với hệ 4/8 mà bạn đã quen từ spacing system. Điều này giúp radius "cộng hưởng" với các giá trị khác trong hệ thống. Con số 999 cho radius.full là một mẹo kỹ thuật: đặt một giá trị đủ lớn để CSS/Figma luôn bo tròn tối đa bất kể kích thước phần tử — nghĩa là một nút cao 40px sẽ thành pill, một avatar 64x64 sẽ thành hình tròn hoàn hảo, mà bạn không cần tính toán thủ công.
Semantic token vs. primitive token
Có hai tầng token bạn nên phân biệt. Tầng thứ nhất là primitive — những con số thô như radius.sm = 4. Tầng thứ hai là semantic — token mô tả mục đích sử dụng, ví dụ radius.button = radius.md hay radius.card = radius.lg. Khi bạn dùng token semantic, việc thay đổi toàn bộ độ bo của mọi button trong app chỉ cần sửa một dòng: trỏ radius.button từ md sang lg. Đây là sức mạnh thật sự của hệ thống — sự thay đổi có kiểm soát ở quy mô lớn.
Nested radius — quy tắc bị bỏ quên nhiều nhất
Đây là khái niệm mà 90% designer junior không biết, và nó tạo ra sự khác biệt giữa "trông ổn" và "trông xịn". Khi bạn đặt một phần tử bo tròn bên trong một phần tử bo tròn khác (ví dụ một nút nằm trong một card, cách viền card một khoảng padding), thì radius trong và radius ngoài phải có quan hệ toán học để hai đường cong "song song" với nhau.
Công thức là: radius ngoài = radius trong + padding.
Ví dụ: một card có padding 8px bao quanh một nút. Nếu nút có radius 8px, thì để đường cong của card ôm khớp với nút, card phải có radius = 8 + 8 = 16px. Nếu bạn để card cũng bo 8px như nút, đường cong ngoài sẽ "gấp" hơn đường cong trong, tạo ra khoảng cách không đều ở góc — mắt sẽ thấy cấn dù không hiểu tại sao. Apple áp dụng nguyên tắc này cực kỳ nghiêm ngặt trong iOS: các icon app, các widget lồng nhau đều tuân theo concentric radius (bo đồng tâm).
Tình huống thực tế
Ví dụ 1 — Tiki chuẩn hóa radius trên hàng trăm màn hình
Giả sử team design của một sàn thương mại điện tử lớn như Tiki tiến hành audit design system sau vài năm phát triển nóng. Kết quả kiểm kê khiến họ giật mình: trong codebase có tới 14 giá trị radius khác nhau đang được dùng — từ 3px, 5px, 6px, 7px, 10px cho đến 14px. Lý do là mỗi designer, mỗi giai đoạn lại "cảm tính" gõ một con số.
Team quyết định gom về một scale 7 bậc chuẩn (none, sm, md, lg, xl, 2xl, full). Họ ánh xạ (map) từng giá trị cũ về giá trị gần nhất trong scale mới: 3px và 5px gộp thành sm (4px); 6px và 7px gộp thành md (8px); 10px và 14px gộp thành lg (12px). Sau khi triển khai qua design tokens, không chỉ giao diện trở nên đồng nhất mà file CSS còn giảm dung lượng, và quan trọng nhất: một thay đổi thiết kế mới chỉ cần cập nhật token thay vì sửa tay hàng trăm chỗ.
Bài học: Số lượng giá trị radius trong hệ thống nên là số ít có kiểm soát (5–7 bậc là đủ cho hầu hết sản phẩm). Nhiều giá trị hơn không đồng nghĩa với linh hoạt hơn — nó chỉ đồng nghĩa với hỗn loạn.
Ví dụ 2 — Fintech chọn radius sai với định vị thương hiệu
Một startup fintech ở TP.HCM nhắm đến nhóm khách hàng doanh nghiệp vừa và nhỏ, định vị "đáng tin cậy, chuyên nghiệp". Nhưng khi build MVP, team dùng luôn thư viện component mặc định với radius rất lớn — button bo 20px thành pill, card bo 24px. Khi đem đi test với khách hàng mục tiêu (các chủ doanh nghiệp 35–50 tuổi), phản hồi lặp đi lặp lại là app "trông như game" hoặc "giống app cho học sinh", khiến họ ngần ngại giao dịch số tiền lớn.
Team đã giảm radius xuống mức trung tính: button và input về radius.sm (4px), card về radius.md (8px), bỏ hoàn toàn pill button cho các hành động quan trọng. Cảm nhận về độ tin cậy tăng rõ rệt trong vòng test tiếp theo. Con số nhỏ như vài pixel radius, nhưng tác động đến niềm tin — thứ tối quan trọng với một sản phẩm tài chính.
Bài học: Radius scale không phải one-size-fits-all. Trước khi chọn mức bo mặc định, hãy hỏi: sản phẩm này muốn "nói" điều gì? Nghiêm túc thì bo ít, thân thiện thì bo nhiều. Và luôn kiểm chứng với người dùng thật.
Ví dụ 3 — Lỗi nested radius trong một card sản phẩm
Một bạn designer junior trong team làm card sản phẩm cho app giao đồ ăn (kiểu ShopeeFood). Card có ảnh món ăn nằm phía trên, chiếm trọn chiều ngang. Card bo góc lg (12px) nhưng ảnh bên trong lại để radius 0 hoặc cũng bo 12px ở cả 4 góc. Kết quả: hoặc góc ảnh vuông chồi ra ngoài đường cong của card, hoặc ảnh bị "cắt" hai lớp bo không khớp ở đáy.
Cách xử lý đúng: ảnh phải bo lg (12px) ở hai góc trên (để khớp viền card) và bo 0 ở hai góc dưới (vì phần dưới ảnh giáp với nội dung text chứ không giáp viền card). Nhờ đó ảnh ôm khít vào card như một khối liền mạch.
Bài học: Radius của phần tử con phụ thuộc vào vị trí tương quan với phần tử cha. Không phải cứ bo là bo đều 4 góc — hãy nghĩ theo từng góc, dựa trên nó giáp với cái gì.
Hướng dẫn từng bước
Bước 1 — Định nghĩa radius scale. Trong Figma, tạo một tập biến (Variables) trong collection tên "Radius" hoặc gộp vào collection "Primitives". Thêm 7 biến: radius/none = 0, radius/sm = 4, radius/md = 8, radius/lg = 12, radius/xl = 16, radius/2xl = 24, radius/full = 999. Đặt kiểu number cho các biến này.
Bước 2 — Tạo tầng semantic (tùy chọn nhưng nên có). Thêm các biến semantic trỏ về primitive: radius/button → radius/md, radius/input → radius/md, radius/card → radius/lg, radius/modal → radius/2xl, radius/chip → radius/full. Đây là nơi bạn "khai báo ý định", giúp việc chỉnh sửa sau này chỉ đụng một chỗ.
Bước 3 — Gán radius bằng biến, không gõ số cứng. Khi thiết kế một component, thay vì gõ 8 vào ô Corner radius, hãy bấm vào biểu tượng biến và chọn token tương ứng. Điều này đảm bảo component "sống" theo hệ thống — sửa token là sửa toàn bộ.
Bước 4 — Áp dụng quy tắc nested radius. Với bất kỳ phần tử nào lồng trong phần tử bo tròn khác, tính: radius con = radius cha − padding. Nếu kết quả âm hoặc quá nhỏ, hãy giữ radius con là 0 hoặc cân nhắc lại padding.
Bước 5 — Xử lý bo từng góc. Với ảnh trong card, header của modal, hay các phần tử giáp cạnh, dùng tính năng bo từng góc riêng (top-left, top-right, bottom-left, bottom-right) thay vì bo cả 4 góc. Figma hỗ trợ điều này ngay trong panel Corner radius.
Bước 6 — Lập tài liệu và bàn giao. Trong trang documentation của design system, hiển thị bảng radius scale với hình minh họa từng bậc, kèm hướng dẫn dùng token nào cho loại component nào. Khi handoff cho developer, đảm bảo token radius được export sang code (ví dụ CSS variable --radius-md: 8px; hoặc token trong Tailwind config) để hai bên dùng chung một nguồn.
Lỗi thường gặp & mẹo
Lỗi 1 — Dùng quá nhiều giá trị radius. Nếu bạn thấy trong file có 3px, 5px, 6px, 9px, 11px... đó là dấu hiệu chưa có hệ thống. Gom về 5–7 bậc chuẩn.
Lỗi 2 — Bỏ qua nested radius. Đây là lỗi khiến các card, badge lồng nhau trông "cấn". Luôn nhớ công thức radius cha = radius con + padding.
Lỗi 3 — Bo radius.full cho phần tử có chiều cao thay đổi. Với button dùng radius.full, nếu text bên trong dài ra làm button cao lên bất ngờ, hình dạng vẫn giữ pill nhưng có thể trông lạ. radius.full phù hợp nhất cho phần tử kích thước cố định hoặc dạng chip/avatar.
Lỗi 4 — Trộn phong cách vuông và tròn không có lý do. Nếu button bo tròn nhiều mà input lại vuông sắc cạnh, giao diện thiếu nhất quán. Trừ khi đó là chủ đích thiết kế (ví dụ tạo tương phản có mục đích), hãy giữ cùng "gia đình" radius.
Mẹo 1 — Chọn radius theo mật độ. Component nhỏ (badge, tag) dùng radius nhỏ; container lớn (modal, section) dùng radius lớn. Radius nên tỉ lệ thuận với kích thước phần tử để cân bằng thị giác.
Mẹo 2 — Radius và elevation đi cùng nhau. Phần tử nổi cao (shadow lớn, như modal) thường bo nhiều hơn để mềm mại hóa cảm giác "trôi nổi". Đây là lý do bottom sheet và dialog hay dùng radius.2xl.
Mẹo 3 — Kiểm tra trên nhiều kích thước màn hình. Một radius trông đẹp trên desktop có thể quá lớn hoặc quá nhỏ trên mobile. Với sản phẩm responsive, hãy xem lại radius ở cả hai đầu.
Mẹo 4 — Đừng bo góc trên ảnh/icon đã có ý nghĩa hình học. Logo, icon vector thường không cần radius; áp radius lên chúng có thể phá hỏng thiết kế gốc.
Bài tập thực hành
Bài 1 — Xây radius scale. Tạo một file Figma mới, khai báo 7 biến radius theo scale chuẩn trong bài. Vẽ 7 ô vuông 120x120, mỗi ô áp một bậc radius, và dán nhãn tên token bên dưới. Đây là "bảng màu radius" của bạn.
Bài 2 — Thiết kế card có nested radius. Vẽ một product card (kiểu app giao đồ ăn): card bo lg, padding 12px, bên trong có một button bo md. Kiểm tra bằng công thức xem đường cong button có "song song" với đường cong card không. Sau đó thêm ảnh chiếm toàn chiều ngang phía trên, bo đúng 2 góc trên khớp với card, 2 góc dưới bằng 0.
Bài 3 — Đổi tính cách sản phẩm bằng radius. Lấy một màn hình bất kỳ bạn đã thiết kế. Tạo 2 phiên bản: một dùng radius nhỏ (sm/md cho mọi thứ) để tạo cảm giác nghiêm túc, một dùng radius lớn (lg/full) để tạo cảm giác thân thiện. Đặt cạnh nhau và tự nhận xét: mỗi phiên bản phù hợp với loại sản phẩm nào?
Bài 4 — Audit một app thật. Mở một app Việt Nam bạn hay dùng (Momo, VNeID, Tiki...). Chụp màn hình và thử đoán radius của button, card, input, avatar. Chúng có nhất quán không? Nếu bạn là designer của app đó, bạn sẽ chuẩn hóa thế nào?
Tóm tắt
Border radius không phải chi tiết trang trí ngẫu nhiên — nó là một phần của ngôn ngữ thị giác định hình tính cách sản phẩm. Những điểm cốt lõi cần nhớ:
- Xây một radius scale có kỷ luật gồm 5–7 bậc được đặt tên (none, sm, md, lg, xl, 2xl, full), gắn với hệ 4/8 để cộng hưởng với spacing system.
- Dùng token, đừng gõ số cứng. Tách primitive (con số) và semantic (mục đích) để chỉnh sửa ở quy mô lớn chỉ với một thay đổi.
- Nhớ quy tắc nested radius: radius cha = radius con + padding, để các phần tử lồng nhau ôm khít, không cấn góc.
- Chọn mức bo theo định vị thương hiệu: bo ít cho cảm giác nghiêm túc/đáng tin, bo nhiều cho cảm giác thân thiện/hiện đại — và luôn kiểm chứng với người dùng thật.
- Bo từng góc theo tương quan với phần tử xung quanh, đặc biệt với ảnh trong card và header modal.