Corner radius là tham số bo góc của các phần tử UI, được đo bằng pixel logic (pt trên iOS, dp trên Android) và xác định bán kính của hình tròn nội tiếp trong góc của hình chữ nhật. Chọn corner radius đúng ảnh hưởng đến cảm nhận giao diện: bo góc lớn tạo cảm giác mềm mại, thân thiện, bo góc nhỏ — nghiêm túc và trang trọng. Theo Material Design Guidelines (Google, 2026), radius được khuyến nghị cho thẻ là 8–16 dp, cho nút — 4–8 dp. Tìm hiểu thêm về quản lý giao diện phần tử trong bài viết về bóng trong UI.
Những điểm chính
Corner radius là một giá trị số xác định mức độ bo tròn của các góc của một phần tử hình chữ nhật. Giá trị càng cao, góc càng tròn. Ở giá trị 0, góc vẫn vuông (90°); ở giá trị bằng một nửa cạnh ngắn hơn, phần tử biến thành hình tròn (đối với hình vuông) hoặc hình chữ nhật bo tròn với các cạnh thẳng (viên nang).
Trong thiết kế di động, corner radius được sử dụng cho: thẻ và ô, nút, trường nhập liệu, cửa sổ modal, hình ảnh và hình đại diện, chỉ báo tiến trình, chip và huy hiệu. Mỗi loại phần tử có phạm vi được khuyến nghị về độ bo góc dựa trên Material Design và Human Interface Guidelines.
Theo Material Design 3 (Google, 2026), bo góc được phân loại thành ba cấp độ: nhỏ (4 dp) cho nút và trường nhập liệu, trung bình (8–12 dp) cho thẻ và trang tính, lớn (16–28 dp) cho hộp thoại và bottom sheet. Apple HIG (2025) khuyến nghị corner radius thống nhất 10–12 pt cho các phần tử hệ thống (UIButton, UITextField) và 20+ pt cho trình bày modal.
Trên iOS, bo góc được triển khai thông qua thuộc tính cornerRadius của CALayer. Trong UIKit, mỗi UIView có một layer mà cornerRadius có thể được thiết lập. Đối với các bo góc phức tạp hơn (bán kính khác nhau cho các góc khác nhau), sử dụng maskedCorners và CACornerMask kết hợp với UIBezierPath.
// UIKit: bo góc qua CALayer
import UIKit
let cardView = UIView()
cardView.backgroundColor = .systemBackground
cardView.layer.cornerRadius = 12
cardView.layer.maskedCorners = [
.layerMinXMinYCorner,
.layerMaxXMinYCorner
]
Trong SwiftUI, bo góc được thiết lập qua bộ điều chỉnh cornerRadius() hoặc qua ClipShape với RoundedRectangle. SwiftUI cũng hỗ trợ bo góc riêng lẻ thông qua UIRectCorner kết hợp với clipped() và overlay().
// SwiftUI: bo góc qua RoundedRectangle
import SwiftUI
VStack {
Text("Corner Radius 16")
.padding()
.background(
RoundedRectangle(cornerRadius: 16)
.fill(Color.blue)
)
}
// Bo góc riêng lẻ
RoundedRectangle(
cornerSize: CGSize(width: 16, height: 16),
style: .continuous
)
Continuous corner radius là kiểu bo góc được Apple sử dụng trong iOS kể từ iOS 7. Không giống như bán kính cổ điển (hình tròn), bán kính liên tục tạo ra độ bo góc mượt mà hơn bằng cách sử dụng đường cong Bezier bậc ba thay vì cung tròn. SwiftUI hỗ trợ kiểu này thông qua tham số style: .continuous trong RoundedRectangle. Apple khuyến nghị continuous corner radius cho tất cả các phần tử hệ thống vì nó tự nhiên hơn về mặt thị giác.
Trên Android, bo góc được triển khai truyền thống thông qua tài nguyên XML shape trong thư mục res/drawable. Shape xác định hình dạng nền với các tham số cornerRadius và solid. Đối với các góc khác nhau, sử dụng <corners android:bottomLeftRadius="..." />. Trong Material Design 3, MaterialShapeDrawable đã được thêm vào với hỗ trợ chủ đề và hình dạng động.
<!-- res/drawable/bg_card.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners android:radius="12dp" />
</shape>
Trong Jetpack Compose, bo góc được thiết lập qua tham số shape của Modifier. Compose cung cấp RoundedCornerShape với hỗ trợ bán kính khác nhau cho mỗi góc và kiểu (CircularShape hoặc CutCornerShape). Compose cũng hỗ trợ continuous corner radius thông qua RoundedCornerShape kết hợp với đường viền đồ họa.
// Jetpack Compose: bo góc qua RoundedCornerShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
Card(
shape = RoundedCornerShape(
topStart = 16.dp,
topEnd = 16.dp,
bottomStart = 4.dp,
bottomEnd = 4.dp
),
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
) {
Text(text = "Card với bo góc tùy chỉnh")
}
MaterialShapeDrawable trong hệ thống View của Android cho phép thay đổi corner radius động mà không cần tạo lại drawable. Sử dụng ShapeAppearanceModel để cấu hình chính xác: đặt cornerFamily (rounded hoặc cut) và cornerSize cho từng góc riêng lẻ.
Chọn corner radius phụ thuộc vào loại phần tử, ngữ cảnh sử dụng và nền tảng. Không có quy tắc phổ quát, nhưng Material Design và Apple HIG cung cấp các khuyến nghị rõ ràng cho các thành phần tiêu chuẩn. Nguyên tắc chính: độ bo góc phải đáng chú ý nhưng không cản trở nội dung.
| Loại phần tử | Radius khuyến nghị | Nền tảng | Ghi chú |
|---|---|---|---|
| Nút | 4–8 dp / 8 pt | iOS, Android | Nút càng lớn, radius càng lớn |
| Thẻ | 8–16 dp / 10–12 pt | iOS, Android | Material Design: 12 dp mặc định |
| Trường nhập liệu | 4–8 dp / 8 pt | iOS, Android | Bo góc quá mức trông không tự nhiên |
| Cửa sổ modal | 16–28 dp / 20+ pt | iOS, Android | iOS 18: 24 pt mặc định |
| Hình đại diện | 50% kích thước | iOS, Android | Với hình đại diện tròn radius = nửa cạnh |
| Chip / Huy hiệu | 16–20 dp / 14 pt | Android | Hình viên nang với bo góc lớn |
Quy tắc tương phản: các phần tử có corner radius khác nhau trong cùng một giao diện nên chênh lệch ít nhất 4 dp để sự khác biệt thị giác có thể nhận thấy. Không sử dụng 3 cấp độ bo góc trên một màn hình — điều này tạo ra nhiễu thị giác. Material Design 3 khuyến nghị sử dụng không quá hai cấp độ bo góc trên mỗi màn hình: một cho vùng chứa (thẻ, hộp thoại) và một cho các phần tử tương tác (nút, trường).
Trong Flutter, bo góc được triển khai thông qua lớp BorderRadius, lớp này chấp nhận các giá trị Radius.circular() hoặc Radius.elliptical(). Flutter hỗ trợ bo góc riêng lẻ thông qua BorderRadius.only() và BorderRadius.horizontal()/vertical(). Widget ClipRRect cắt phần tử con theo BorderRadius đã cho.
// Flutter: bo góc qua ClipRRect và Container
import 'package:flutter/material.dart';
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0),
topRight: Radius.circular(16.0),
bottomLeft: Radius.circular(4.0),
bottomRight: Radius.circular(4.0),
),
),
child: Text('Bo góc tùy chỉnh'),
)
// ClipRRect với Image
ClipRRect(
borderRadius: BorderRadius.circular(12.0),
child: Image.network(
'https://example.com/image.jpg',
fit: BoxFit.cover,
),
)
ClipRRect trong Flutter được sử dụng khi bạn cần cắt một hình ảnh hoặc widget phức tạp dọc theo đường viền bo tròn. Đối với vùng chứa nền đơn giản, BoxDecoration với borderRadius là đủ — điều này hiệu quả hơn vì không tạo lớp cắt riêng biệt. Material Flutter 3.22+ hỗ trợ continuous corner radius thông qua ContinuousRectangleBorder.
Các câu hỏi thường gặp
dp (density-independent pixels) trên Android và pt (points) trên iOS là các đơn vị logic tương ứng với kích thước vật lý trên màn hình bất kể mật độ pixel. 1 dp ≈ 1 pt ≈ 1/160 inch. Các giá trị số của corner radius trong dp và pt có thể được sử dụng thay thế cho nhau khi chuyển đổi thiết kế giữa các nền tảng.
Trên iOS, sử dụng maskedCorners với CACornerMask: layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]. Trong Android XML — . Trong Jetpack Compose — RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp). Trong Flutter — BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)).
Continuous corner radius là kiểu bo góc trong đó góc được tạo thành không phải bằng cung tròn mà bằng đường cong Bezier bậc ba. Apple đã sử dụng kiểu này từ iOS 7 cho tất cả các phần tử hệ thống. Về mặt thị giác, bo góc liên tục trông mượt mà và tự nhiên hơn so với kiểu tròn cổ điển.
10–12 pt trên iOS (như bàn phím hệ thống) và 8–12 dp trên Android được khuyến nghị. Các phím bên trong bàn phím có thể có radius nhỏ hơn (4–6 dp) hoặc không bo góc. Để tăng diện tích chạm, sử dụng padding 4–8 dp giữa đường viền bo tròn và cạnh nút.
UITableViewCell không tự động kế thừa cornerRadius từ contentView vì nền của ô được vẽ trong backgroundView. Để bo góc một ô, đặt cornerRadius trên cả contentView.layer và backgroundView.layer cùng một lúc. Trong SwiftUI, sử dụng .listRowBackground() với RoundedRectangle.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm