Vì sao nên ưu tiên validation HTML5?
- Nhanh và gọn: Không phụ thuộc JS, hoạt động ngay cả khi người dùng tắt JS.
- Nhất quán: Dựa vào thông điệp lỗi gốc của trình duyệt, hỗ trợ bàn phím ảo, định dạng quốc tế…
- Truy cập tốt: Trình đọc màn hình hiểu cấu trúc form/label/fieldset.
- SEO & UX: HTML ngữ nghĩa, label đúng, input type chính xác giúp bot hiểu nội dung và người dùng thao tác dễ hơn.
Những thuộc tính/kiểu cốt lõi cần nắm
required: bắt buộc nhập.type:email,url,tel,number,date,password,file… giúp trình duyệt tự kiểm tra định dạng cơ bản.min,max,step: ràng buộc phạm vi số/ngày/giờ.minlength,maxlength: độ dài chuỗi.pattern: biểu thức chính quy để kiểm tra tùy biến; kết hợptitleđể gợi ý.multiple: cho phép nhập nhiều giá trị (vd: nhiều email, nhiều file).accept(vớitype="file"): gợi ý loại tệp hợp lệ (MIME/đuôi).autocomplete: gợi ý tự động (vd:name,email,organization…).inputmode: gợi ý bàn phím ảo trên di động (vd:numeric,tel,email…).
Ví dụ form “chuẩn chỉnh” chỉ dùng HTML5
Dán đoạn dưới vào là chạy. Trình duyệt sẽ tự báo lỗi khi dữ liệu không hợp lệ.
<form action="/subscribe" method="post">
<fieldset>
<legend>Đăng ký nhận tin</legend>
<div>
<label for="fullname">Họ và tên</label>
<input id="fullname" name="fullname" type="text"
required minlength="2" maxlength="60"
autocomplete="name" placeholder="Nguyễn Văn A">
</div>
<div>
<label for="email">Email</label>
<input id="email" name="email" type="email"
required autocomplete="email" placeholder="[email protected]">
</div>
<div>
<label for="website">Website (tùy chọn)</label>
<input id="website" name="website" type="url"
placeholder="https://inithtml.com">
</div>
<div>
<label for="phone">Số điện thoại (10–11 chữ số)</label>
<input id="phone" name="phone" type="tel"
inputmode="numeric" pattern="^\d{10,11}$"
title="Nhập 10–11 chữ số, không khoảng trắng"
placeholder="0987123456">
</div>
<div>
<label for="age">Tuổi</label>
<input id="age" name="age" type="number"
required min="16" max="120" step="1" placeholder="18">
</div>
<div>
<label for="start">Ngày bắt đầu dự kiến</label>
<input id="start" name="start" type="date" required>
</div>
<div>
<span>Gói quan tâm</span><br>
<label><input type="radio" name="plan" value="basic" required> Basic</label>
<label><input type="radio" name="plan" value="pro"> Pro</label>
<label><input type="radio" name="plan" value="enterprise"> Enterprise</label>
</div>
<div>
<label for="topics">Chủ đề muốn nhận</label>
<select id="topics" name="topics" required>
<option value="">-- Chọn một --</option>
<option value="wp">WordPress</option>
<option value="perf">Tối ưu hiệu năng</option>
<option value="seo">SEO kỹ thuật</option>
</select>
</div>
<div>
<label for="avatar">Ảnh đại diện (PNG/JPEG, < 2MB)</label>
<input id="avatar" name="avatar" type="file"
accept=".png,.jpg,.jpeg,image/png,image/jpeg">
</div>
<div>
<label for="bio">Giới thiệu ngắn (tối đa 160 ký tự)</label>
<textarea id="bio" name="bio" maxlength="160"
placeholder="Tôi là dev WordPress..."></textarea>
</div>
<div>
<label>
<input type="checkbox" name="agree" required>
Tôi đồng ý với Điều khoản dịch vụ
</label>
</div>
<button type="submit">Gửi đăng ký</button>
</fieldset>
</form>
Mẫu “ràng buộc nâng cao” với pattern
Dùng khi bạn cần quy tắc chi tiết (ví dụ mã đơn hàng, slug, hoặc username). Hãy luôn thêm title để giúp người dùng hiểu yêu cầu.
<label for="username">Username (a–z, 0–9, gạch dưới, 3–16 ký tự)</label>
<input id="username" name="username" type="text" required
pattern="^[a-z0-9_]{3,16}$"
title="Chỉ chữ thường, số, gạch dưới; 3–16 ký tự">
<label for="slug">Slug (kebab-case)</label>
<input id="slug" name="slug" type="text" required
pattern="^[a-z0-9]+(-[a-z0-9]+)*$"
title="Chỉ chữ thường/số, nối bằng dấu gạch ngang">
Tùy biến trải nghiệm mà không cần JS
- Viết label rõ ràng, đặt
placeholderđể gợi ý, nhưng không thay thế label. - Nhóm radio/checkbox bằng
fieldset/legendđể trình đọc màn hình hiểu ngữ cảnh. - Hạn chế lạm dụng
pattern: nếu đã cótype="email"thì thường không cần pattern email phức tạp. - Gợi ý bàn phím di động với
inputmode(vd: số, email, tel) để giảm lỗi nhập. - Đa ngôn ngữ thông điệp lỗi: thông báo mặc định phụ thuộc ngôn ngữ trình duyệt; dùng
titleđể bổ sung chỉ dẫn.
Bỏ qua validation khi cần
Trong một số tình huống (ví dụ nút “Lưu nháp”), bạn có thể bỏ qua kiểm tra:
<button type="submit" formnovalidate>Lưu nháp</button>
Hoặc tắt hoàn toàn ở cấp form (không khuyến nghị cho form sản xuất):
<form action="/x" method="post" novalidate>...</form>
Kiểm tra nhanh checklist
- Mỗi trường đều có
labelliên kết bằngfor/id. - Dùng
typephù hợp thay vìtext“vạn năng”. - Áp dụng
required,min/max/step,minlength/maxlengthhợp lý. - Chỉ dùng
patternkhi thật sự cần; luôn thêmtitle. - Không dùng
novalidatetrừ khi có lý do. - Kiểm tra trên di động:
inputmode, bàn phím ảo, tự động điền.
Kết luận
HTML5 đã cung cấp bộ công cụ validation đầy đủ cho hầu hết form phổ biến. Chỉ với thuộc tính và kiểu input đúng đắn, bạn có thể giảm lỗi nhập, rút ngắn thời gian triển khai và vẫn giữ trải nghiệm, SEO, khả năng truy cập ở mức cao — tất cả mà không cần JavaScript.
Bình luận