Thẻ input trong HTML là phần tử bạn sẽ dùng nhiều nhất khi làm form đăng nhập, đăng ký, khảo sát hay ô tìm kiếm. Sai một thuộc tính nhỏ là dữ liệu gửi về backend hỏng, hoặc mật khẩu lộ nguyên văn trên màn hình. Bài viết này tổng hợp đủ loại type, ví dụ form đẹp và cách lấy dữ liệu thật, đúng chuẩn như tài liệu của InterData.
NỘI DUNG BÀI VIẾT
- Thẻ input trong HTML là gì và cú pháp cơ bản?
- Tổng hợp các type của thẻ input kèm ví dụ
- Các thuộc tính quan trọng đi cùng input
- Dựng form đăng nhập và đăng ký hoàn chỉnh
- CSS cho input: làm khung nhập liệu đẹp
- Validation input: chặn dữ liệu rác ngay ở trình duyệt
- Lấy dữ liệu từ form gửi về backend (PHP)
- Lỗi thường gặp khi làm việc với input
- Câu hỏi thường gặp (FAQ)
Thẻ input trong HTML là gì và cú pháp cơ bản?
Thẻ input trong HTML là phần tử dùng để nhận dữ liệu người dùng nhập vào: chữ, số, mật khẩu, lựa chọn, ngày tháng, file. Nó là một thẻ rỗng (empty element), không có thẻ đóng. Mọi hành vi của ô nhập phụ thuộc vào thuộc tính type bạn khai báo.
Cú pháp tối giản nhất chỉ gồm một dòng:
<input type="text" name="hoten" placeholder="Nhập họ tên">
Có ba điểm bạn cần nắm ngay từ đầu, vì thiếu chúng là form chạy nhưng không dùng được:
- Thuộc tính name là bắt buộc để gửi dữ liệu: Backend đọc dữ liệu theo
name, không phải theoid. Quênnamethì giá trị ô đó không bao giờ tới server. - input phải nằm trong thẻ form: Nút submit chỉ gom được dữ liệu của các input cùng nằm trong một
<form>. - id để gắn label và CSS/JS: Dùng
idghép với<label for="...">giúp người dùng bấm vào nhãn là focus vào ô, tốt cho cả trải nghiệm lẫn accessibility.
Một input “đúng chuẩn” thường đi kèm label như sau. Đây là cách viết bạn nên dùng mặc định:
<label for="email">Email</label> <input type="email" id="email" name="email" placeholder="[email protected]" required>
Nắm vững định nghĩa và cú pháp gốc theo tài liệu của MDN Web Docs sẽ giúp bạn tránh đa số lỗi vặt về sau.

Tổng hợp các type của thẻ input kèm ví dụ
Thuộc tính type quyết định ô nhập là dạng gì. HTML hỗ trợ hơn 20 giá trị, nhưng trong thực tế bạn chỉ dùng đi dùng lại khoảng 10. Dưới đây là nhóm quan trọng nhất, sắp theo tần suất dùng thật.
input type text và các biến thể chữ
type="text" là dạng mặc định cho chuỗi ngắn một dòng: họ tên, tiêu đề, mã giảm giá. Với chuỗi dài nhiều dòng (bình luận, địa chỉ), bạn dùng <textarea> chứ không phải input.
<input type="text" name="hoten" maxlength="50" placeholder="Nguyễn Văn A"> <input type="email" name="email" placeholder="[email protected]"> <input type="tel" name="sdt" placeholder="0901234567"> <input type="url" name="website" placeholder="https://..."> <input type="search" name="tukhoa" placeholder="Tìm kiếm...">
Điểm khác biệt thực tế: trên điện thoại, type="email" bật bàn phím có ký tự @, type="tel" bật bàn phím số. Chọn đúng type là bạn đã cải thiện trải nghiệm nhập liệu mà không cần viết thêm dòng nào.
input type password: ẩn mật khẩu khi gõ
type="password" che ký tự thành dấu chấm khi người dùng gõ. Đây là yêu cầu cơ bản của mọi form đăng nhập. Lưu ý quan trọng: password chỉ ẩn trên màn hình, không mã hóa dữ liệu. Mật khẩu vẫn được gửi đi dạng văn bản thuần, nên bắt buộc phải có HTTPS để chống nghe lén.
<input type="password" name="matkhau" minlength="8" required autocomplete="current-password">
input radio và checkbox: tích chọn cho khảo sát
Đây là cặp hay bị nhầm. Quy tắc đơn giản: radio cho chọn một, checkbox cho chọn nhiều.
- input radio: Các radio cùng một câu hỏi phải dùng chung một giá trị name. Nhờ vậy trình duyệt hiểu chúng là một nhóm và chỉ cho chọn một.
- input checkbox: Cho phép chọn nhiều mục độc lập. Nếu muốn gửi nhiều giá trị về backend, đặt
namedạng mảng nhưname="sothich[]".
<!-- Radio: chọn một giới tính --> <input type="radio" name="gioitinh" value="nam" id="nam" checked> <label for="nam">Nam</label> <input type="radio" name="gioitinh" value="nu" id="nu"> <label for="nu">Nữ</label> <!-- Checkbox: chọn nhiều sở thích --> <input type="checkbox" name="sothich[]" value="code" id="c1"> <label for="c1">Lập trình</label> <input type="checkbox" name="sothich[]" value="server" id="c2"> <label for="c2">Quản trị máy chủ</label>
Các type tiện ích: number, date, file, color, range
Nhóm này giúp bạn thu thập dữ liệu web đúng định dạng mà không cần JavaScript:
| Type | Dùng cho | Ghi chú thực tế |
|---|---|---|
number |
Số lượng, tuổi, giá | Kết hợp min, max, step |
date |
Ngày sinh, ngày hẹn | Giao diện lịch khác nhau theo trình duyệt |
file |
Tải ảnh, tài liệu | Form phải có enctype="multipart/form-data" |
color |
Chọn màu | Trả về mã hex như #2563EB |
hidden |
Gửi giá trị ẩn (token, id) | Không hiển thị nhưng vẫn gửi về backend |
button submit và các loại nút
Nút gửi form có hai cách viết: <input type="submit"> hoặc <button type="submit">. Khuyên dùng <button> vì cho phép chèn HTML và icon bên trong. Ngoài ra còn type="reset" để xóa form và type="button" cho nút không submit, chỉ chạy JavaScript.
<button type="submit">Đăng ký</button> <button type="reset">Nhập lại</button> <button type="button" onclick="hienMatKhau()">Hiện mật khẩu</button>
Các thuộc tính quan trọng đi cùng thẻ input
Cùng một type="text", bạn có thể biến nó từ ô nhập thô thành ô thông minh nhờ các thuộc tính. Đây là những thuộc tính bạn sẽ gặp gần như mọi form trong HTML cơ bản:
- placeholder: Gợi ý mờ trong ô. Không phải giá trị mặc định, và biến mất khi gõ. Đừng dùng nó thay cho label.
- value: Giá trị mặc định có sẵn. Khác placeholder ở chỗ nó là dữ liệu thật, sẽ được gửi đi.
- required: Bắt buộc nhập. Trình duyệt chặn submit nếu để trống.
- readonly và disabled:
readonlycho đọc, không sửa, vẫn gửi dữ liệu.disabledkhóa hẳn và không gửi giá trị về backend. - autocomplete: Cho trình duyệt gợi ý điền nhanh. Với mật khẩu nên đặt rõ
current-passwordhoặcnew-password. - maxlength và minlength: Giới hạn số ký tự, hữu ích cho mã OTP, số điện thoại.
Một nhầm lẫn phổ biến: dùng disabled cho ô không cho sửa nhưng vẫn muốn dữ liệu gửi về. Sai. Nếu cần gửi, dùng readonly, hoặc đi kèm một input type="hidden" mang giá trị đó.
Dựng form đăng nhập và đăng ký hoàn chỉnh
Giờ ghép tất cả lại thành một form html dùng được thật. Đây là khung đăng nhập gồm email, mật khẩu, nút submit và một checkbox ghi nhớ. Bạn dán nguyên đoạn này là chạy.
<form action="xu-ly-dang-nhap.php" method="POST"> <label for="email">Email</label> <input type="email" id="email" name="email" required> <label for="mk">Mật khẩu</label> <input type="password" id="mk" name="matkhau" minlength="8" required> <input type="checkbox" id="nhomk" name="ghinho" value="1"> <label for="nhomk">Ghi nhớ đăng nhập</label> <button type="submit">Đăng nhập</button> </form>
Hai thuộc tính của thẻ <form> quyết định dữ liệu đi đâu và đi kiểu gì:
- action: Đường dẫn file backend xử lý dữ liệu. Để trống nghĩa là gửi về chính trang hiện tại.
- method: Dùng
POSTcho mọi form có mật khẩu hoặc dữ liệu nhạy cảm. DùngGETcho ô tìm kiếm vì nó hiện tham số trên URL.
Form đăng ký chỉ là phiên bản dài hơn: thêm họ tên, xác nhận mật khẩu, ngày sinh, radio giới tính và checkbox đồng ý điều khoản. Nguyên tắc giữ nguyên, bạn chỉ nối thêm các input đã học ở trên.
CSS cho input: làm khung nhập liệu đẹp mắt
Input mặc định của trình duyệt nhìn thô và cũ. Chỉ vài dòng CSS cho input là form của bạn trông chuyên nghiệp hẳn. Ba việc cần làm: bo góc, thêm padding cho dễ bấm, và đổi viền khi focus để người dùng biết đang ở ô nào.
input[type="text"],
input[type="email"],
input[type="password"] {
width: 100%;
padding: 12px 14px;
border: 1.5px solid #cbd5e1;
border-radius: 8px;
font-size: 15px;
box-sizing: border-box;
transition: border-color .2s, box-shadow .2s;
}
/* Đổi viền khi người dùng đang nhập */
input:focus {
border-color: #2563EB;
box-shadow: 0 0 0 3px rgba(37, 99, 235, .15);
outline: none;
}
/* Báo lỗi khi nhập sai định dạng */
input:invalid {
border-color: #ef4444;
}
Checklist nhanh để khung nhập liệu vừa đẹp vừa dùng tốt:
- Luôn đặt box-sizing: border-box: Tránh input bị tràn khỏi khung cha khi để
width: 100%. - Padding tối thiểu 10-12px: Ô quá sát khó bấm trên điện thoại.
- Có trạng thái focus rõ ràng: Đừng xóa
outlinemà không thay bằng hiệu ứng khác, sẽ hại accessibility. - Tận dụng pseudo-class :invalid và :valid: Báo lỗi bằng màu viền mà không cần JavaScript.
Validation input: chặn dữ liệu rác ngay ở trình duyệt
HTML5 cho bạn kiểm tra dữ liệu nhập mà không cần viết JavaScript. Đây gọi là validation phía client. Nó chặn người dùng submit form khi dữ liệu sai định dạng, giúp giảm tải cho backend.
| Thuộc tính | Tác dụng | Ví dụ |
|---|---|---|
required |
Không cho để trống | required |
pattern |
Kiểm tra theo regex | pattern="[0-9]{10}" |
min / max |
Giới hạn giá trị số/ngày | min="18" max="100" |
minlength |
Số ký tự tối thiểu | minlength="8" |
Ví dụ ép số điện thoại đúng 10 chữ số:
<input type="tel" name="sdt"
pattern="0[0-9]{9}"
title="Nhập 10 số, bắt đầu bằng 0"
required>
Cảnh báo bắt buộc nhớ: validation phía client không bao giờ thay thế kiểm tra ở backend. Người dùng có thể tắt JavaScript, sửa HTML bằng DevTools hoặc gửi request thẳng tới server. Luôn kiểm tra lại dữ liệu ở backend trước khi lưu vào database.
Lấy dữ liệu từ form gửi về backend (PHP)
Đây là phần nhiều người mới bỏ qua: form đẹp mà không lấy được dữ liệu thì vô nghĩa. Khi người dùng bấm submit, trình duyệt gói toàn bộ giá trị input theo name rồi gửi tới file ghi trong action. Ở phía PHP form, bạn đọc lại bằng $_POST hoặc $_GET.
File xu-ly-dang-nhap.php xử lý form đăng nhập ở trên có thể viết như sau:
<?php
// Chỉ xử lý khi form gửi bằng POST
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Lấy dữ liệu theo thuộc tính name của input
$email = trim($_POST['email'] ?? '');
$matkhau = $_POST['matkhau'] ?? '';
$ghinho = isset($_POST['ghinho']); // checkbox: có tích hay không
// Kiểm tra lại ở backend, không tin client
if ($email === '' || $matkhau === '') {
die('Vui lòng nhập đủ thông tin');
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
die('Email không hợp lệ');
}
// ... so khớp với database, tạo session ...
echo 'Đăng nhập với email: ' . htmlspecialchars($email);
}
?>
Ba quy tắc an toàn khi nhận dữ liệu từ form, áp dụng cho mọi ngôn ngữ backend chứ không riêng PHP:
- Không tin dữ liệu client: Validation HTML chỉ để cải thiện trải nghiệm. Backend phải kiểm tra lại từ đầu.
- Lọc và thoát dữ liệu trước khi hiển thị: Dùng
htmlspecialchars()để chống XSS khi in ra trình duyệt. - Dùng prepared statement khi ghi vào database: Đây là cách chuẩn để chống SQL Injection, đừng nối chuỗi truy vấn trực tiếp.
Với form upload file (type="file"), dữ liệu nằm trong biến $_FILES chứ không phải $_POST, và form bắt buộc khai báo enctype="multipart/form-data". Quên dòng này là file không bao giờ tới server.
Lỗi thường gặp khi làm việc với thẻ input trong HTML
Phần lớn lỗi form đến từ vài sai sót lặp đi lặp lại. Đối chiếu nhanh để không mất thời gian debug:
- Dữ liệu không gửi về server: Thường do quên
name, hoặc input nằm ngoài thẻ<form>, hoặc lỡ đểdisabled. - Radio cho chọn nhiều cùng lúc: Do mỗi radio đặt một
namekhác nhau. Sửa bằng cách cho cả nhóm chung mộtname. - Checkbox chỉ nhận một giá trị ở backend: Do thiếu
[]trongname. Đặtname="mua[]"để nhận mảng. - Bấm label không focus vào ô: Do
forcủa label không trùngidcủa input. - File upload trống: Do form thiếu
enctype="multipart/form-data"hoặc dùngmethod="GET".
Câu hỏi thường gặp về thẻ input
Thẻ input có cần thẻ đóng không?
Không. Input là thẻ rỗng, chỉ viết <input> là đủ, không có </input>. Trong cú pháp XHTML bạn có thể tự đóng bằng <input />, nhưng với HTML5 hiện đại thì không bắt buộc. Mọi thông tin của ô nhập nằm trong các thuộc tính.
Khác nhau giữa input radio và checkbox là gì?
Radio cho chọn duy nhất một phương án trong nhóm có cùng name, dùng cho câu hỏi một đáp án như giới tính. Checkbox cho chọn nhiều mục độc lập, hoặc dùng làm ô tích đồng ý điều khoản. Đó là khác biệt cốt lõi khi làm khảo sát.
Làm sao thêm nút hiện/ẩn mật khẩu?
Dùng JavaScript đổi thuộc tính type của ô từ password sang text và ngược lại khi bấm nút. Bản thân HTML không có sẵn tính năng này. Đây là lý do nhiều form thêm một nút type="button" bên cạnh ô mật khẩu.
Placeholder và value khác nhau thế nào?
Placeholder là gợi ý mờ, biến mất khi gõ và không được gửi về server. Value là giá trị thật có sẵn trong ô, sẽ được gửi đi khi submit. Đừng dùng placeholder thay cho label vì người dùng sẽ mất gợi ý ngay khi bắt đầu nhập.
Backend đọc dữ liệu input theo id hay name?
Theo name. Thuộc tính id chỉ phục vụ CSS, JavaScript và gắn label phía trình duyệt. Server nhận dữ liệu qua các khóa trùng với name của input. Thiếu name thì dù ô có nhập gì, giá trị cũng không tới backend.
Từ ô nhập đầu tiên đến form chạy thật
Nắm vững thẻ input trong HTML là bạn đã có nền để dựng mọi form: đăng nhập, đăng ký, khảo sát, thanh toán. Ghi nhớ ba điều: name quyết định dữ liệu có tới server hay không, chọn đúng type giúp nhập liệu chuẩn mà không cần JavaScript, và validation HTML chỉ là lớp đầu, backend mới là nơi giữ an toàn thật sự. Học xong lý thuyết, bước tiếp theo là đưa form lên một máy chủ chạy được để kiểm tra luồng dữ liệu hoàn chỉnh.
Sẵn sàng đưa form của bạn lên server thật
Một VPS có quyền root là đủ để cài PHP, MySQL và deploy form gửi dữ liệu thật.
Lưu ý: các đoạn mã HTML, CSS và PHP trong bài chỉ mang tính tham khảo cho mục đích học tập. Cú pháp, hành vi trình duyệt và cấu hình có thể thay đổi theo phiên bản trình duyệt, phiên bản PHP và môi trường máy chủ thực tế. Bạn nên kiểm thử trên môi trường dev, sao lưu dữ liệu và đánh giá rủi ro bảo mật trước khi áp dụng cho website chạy production.
