Form validation với HTML5 — không cần JavaScript

Bạn có thể xây dựng kiểm tra dữ liệu đầu vào (validation) mạnh mẽ chỉ với HTML5, không cần viết một dòng JavaScript nào. Bài này hướng dẫn cách dùng đúng các thuộc tính và kiểu input để trình duyệt tự kiểm tra, hiển thị lỗi thân thiện, tối ưu SEO và khả năng truy cập.

Form validation với HTML5 — không cần JavaScript

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ợp title để gợi ý.
  • multiple: cho phép nhập nhiều giá trị (vd: nhiều email, nhiều file).
  • accept (với type="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ó label liên kết bằng for/id.
  • Dùng type phù hợp thay vì text “vạn năng”.
  • Áp dụng required, min/max/step, minlength/maxlength hợp lý.
  • Chỉ dùng pattern khi thật sự cần; luôn thêm title.
  • Không dùng novalidate trừ 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


  • Không có bình luận.

Init Toolbox

Nhấn Ctrl + \ trên máy tính, hoặc vuốt sang trái ở bất kỳ đâu trên mobile.

Đăng nhập





Đang tải...