Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> CSS

Cách tạo form responsive (tự thích ứng) với CSS

Giới thiệu

Form responsive tự điều chỉnh bố cục trên mọi kích thước màn hình: desktop hiển thị nhiều cột, mobile xếp chồng dọc. CSS Flexbox/Grid + Media Queries là chìa khóa.

Ví dụ hoàn chỉnh - Form đăng ký 2 cột responsive

<!DOCTYPE html>
<html lang="vi">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Responsive Form</title>
  <style>
    * { box-sizing: border-box; }
    body { font-family: 'Segoe UI', system-ui, sans-serif; font-size: 16px; line-height: 1.5; padding: 20px; background: #f9f9f9; }
    .form-wrapper { max-width: 900px; margin: 0 auto; }
    .form-row {
      display: flex;
      flex-wrap: wrap;
      gap: 24px;
      margin-bottom: 20px;
    }
    .form-group {
      flex: 1 1 300px; /* Tối thiểu 300px, tự co giãn */
      min-width: 0;    /* Cho phép co nhỏ hơn 300px nếu cần */
    }
    .form-group.full { flex-basis: 100%; }
    label {
      display: block;
      margin-bottom: 8px;
      font-weight: 500;
      color: #333;
    }
    input[type="text"],
    input[type="email"],
    input[type="password"],
    input[type="tel"],
    select,
    textarea {
      width: 100%;
      padding: 12px 14px;
      font-size: 16px; /* ≥16px để tránh zoom trên iOS */
      border: 1px solid #ddd;
      border-radius: 6px;
      background: #fff;
      transition: border-color 0.2s, box-shadow 0.2s;
    }
    input:focus, select:focus, textarea:focus {
      outline: none;
      border-color: #1eadef;
      box-shadow: 0 0 0 3px rgba(30, 173, 239, 0.2);
    }
    .btn-submit {
      width: 100%;
      max-width: 300px;
      padding: 14px;
      font-size: 16px;
      font-weight: 600;
      color: #fff;
      background: #4caf50;
      border: none;
      border-radius: 6px;
      cursor: pointer;
      transition: background 0.2s;
    }
    .btn-submit:hover { background: #43a047; }
    .btn-submit:focus-visible { outline: 3px solid rgba(76, 175, 80, 0.4); outline-offset: 2px; }
    .form-card {
      background: #fff;
      border: 1px solid #e0e0e0;
      border-radius: 12px;
      padding: 32px;
      box-shadow: 0 2px 8px rgba(0,0,0,0.05);
    }
    @media (max-width: 600px) {
      .form-card { padding: 20px; }
      .form-row { gap: 16px; }
    }
  </style>
</head>
<body>
  <div class="form-wrapper">
    <div class="form-card">
      <h1 style="text-align:center; margin-bottom:24px">Đăng ký tài khoản</h1>
      <form>
        <div class="form-row">
          <div class="form-group">
            <label for="fullname">Họ và tên</label>
            <input type="text" id="fullname" name="fullname" placeholder="Nguyễn Văn An" required>
          </div>
          <div class="form-group">
            <label for="email">Email</label>
            <input type="email" id="email" name="email" placeholder="email@example.com" required>
          </div>
        </div>
        <div class="form-row">
          <div class="form-group">
            <label for="phone">Số điện thoại</label>
            <input type="tel" id="phone" name="phone" placeholder="09x xxx xxxx">
          </div>
          <div class="form-group">
            <label for="birthdate">Ngày sinh</label>
            <input type="date" id="birthdate" name="birthdate">
          </div>
        </div>
        <div class="form-group full">
          <label for="address">Địa chỉ</label>
          <textarea id="address" name="address" rows="3" placeholder="Số nhà, đường, quận/huyện, tỉnh/thành"></textarea>
        </div>
        <div style="text-align:center; margin-top:24px">
          <button type="submit" class="btn-submit">Đăng ký</button>
        </div>
      </form>
    </div>
  </div>
</body>
</html>

Kỹ thuật cốt lõi

  • flex: 1 1 300px: Mỗi nhóm trường (form-group) chiếm 1 phần, tối thiểu 300px. Nếu container < 600px → tự động xuống dòng.
  • gap: Khoảng cách giữa các cột, thay thế margin phức tạp.
  • min-width: 0: Quan trọng cho flex item co được nhỏ hơn flex-basis khi cần.
  • font-size: 16px trên input: Ngăn Safari iOS zoom khi focus.

Grid Alternative (CSS Grid)

Dùng Grid cho bố cục phức tạp hơn:

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
}
.form-grid .full { grid-column: 1 / -1; } /* Chiếm toàn hàng */

Checklist Form Responsive

  • [ ] Label liên kết input bằng for/id.
  • [ ] Input có type đúng (email, tel, password...).
  • [ ] Focus state rõ ràng (outline/box-shadow).
  • [ ] Error state: border đỏ + message dưới input.
  • [ ] Disabled state: opacity: 0.6; cursor: not-allowed;
  • [ ] Submit button đủ lớn, dễ bấm trên mobile.