良好的表单样式设计能够提升用户体验,使表单更易用、更美观。
东巴文(db-w.cn) 认为:表单样式应该注重可用性、可访问性和美观性的平衡。
<form class="form-basic">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" id="username" name="username">
</div>
<div class="form-group">
<label for="email">邮箱</label>
<input type="email" id="email" name="email">
</div>
<button type="submit">提交</button>
</form>
<style>
.form-basic {
max-width: 500px;
margin: 0 auto;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: 500;
color: #333;
}
input[type="text"],
input[type="email"] {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
button {
width: 100%;
padding: 12px;
background: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #45a049;
}
</style>
<form class="form-inline">
<div class="form-group">
<label for="search">搜索</label>
<input type="search" id="search" name="search" placeholder="搜索...">
</div>
<button type="submit">搜索</button>
</form>
<style>
.form-inline {
display: flex;
align-items: flex-end;
gap: 10px;
}
.form-inline .form-group {
margin-bottom: 0;
flex: 1;
}
.form-inline button {
width: auto;
padding: 10px 20px;
}
</style>
<form class="form-grid">
<div class="form-row">
<div class="form-group">
<label for="firstName">名</label>
<input type="text" id="firstName" name="firstName">
</div>
<div class="form-group">
<label for="lastName">姓</label>
<input type="text" id="lastName" name="lastName">
</div>
</div>
<div class="form-group">
<label for="email">邮箱</label>
<input type="email" id="email" name="email">
</div>
<button type="submit">提交</button>
</form>
<style>
.form-grid {
max-width: 600px;
margin: 0 auto;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-bottom: 20px;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: 500;
}
input[type="text"],
input[type="email"] {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
}
</style>
<style>
/* 基本输入框 */
.input-basic {
width: 100%;
padding: 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
transition: border-color 0.3s;
}
/* 聚焦样式 */
.input-basic:focus {
outline: none;
border-color: #4CAF50;
box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.1);
}
/* 禁用样式 */
.input-basic:disabled {
background: #f5f5f5;
cursor: not-allowed;
opacity: 0.6;
}
/* 只读样式 */
.input-basic:read-only {
background: #f9f9f9;
}
</style>
<style>
/* 圆角输入框 */
.input-rounded {
border-radius: 25px;
padding: 12px 20px;
}
/* 无边框输入框 */
.input-borderless {
border: none;
border-bottom: 2px solid #ddd;
border-radius: 0;
padding: 10px 0;
}
.input-borderless:focus {
border-bottom-color: #4CAF50;
}
/* 带阴影输入框 */
.input-shadow {
border: none;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
/* 渐变边框输入框 */
.input-gradient {
border: 2px solid transparent;
background: linear-gradient(white, white) padding-box,
linear-gradient(135deg, #667eea, #764ba2) border-box;
}
</style>
<div class="input-icon-group">
<span class="input-icon">📧</span>
<input type="email" class="input-with-icon" placeholder="请输入邮箱">
</div>
<div class="input-icon-group-right">
<input type="search" class="input-with-icon-right" placeholder="搜索...">
<span class="input-icon-right">🔍</span>
</div>
<style>
.input-icon-group {
position: relative;
margin-bottom: 20px;
}
.input-icon {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: #999;
}
.input-with-icon {
width: 100%;
padding: 12px 12px 12px 40px;
border: 1px solid #ddd;
border-radius: 4px;
}
.input-icon-group-right {
position: relative;
margin-bottom: 20px;
}
.input-icon-right {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
color: #999;
cursor: pointer;
}
.input-with-icon-right {
width: 100%;
padding: 12px 40px 12px 12px;
border: 1px solid #ddd;
border-radius: 4px;
}
</style>
<div class="select-wrapper">
<select class="select-styled">
<option value="">请选择</option>
<option value="1">选项一</option>
<option value="2">选项二</option>
<option value="3">选项三</option>
</select>
</div>
<style>
.select-wrapper {
position: relative;
display: inline-block;
}
.select-styled {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
padding: 12px 40px 12px 12px;
border: 1px solid #ddd;
border-radius: 4px;
background: white;
cursor: pointer;
font-size: 14px;
}
.select-wrapper::after {
content: '▼';
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
pointer-events: none;
color: #999;
font-size: 12px;
}
</style>
<!-- 自定义单选按钮 -->
<div class="radio-group">
<label class="radio-label">
<input type="radio" name="gender" value="male">
<span class="radio-custom"></span>
<span class="radio-text">男</span>
</label>
<label class="radio-label">
<input type="radio" name="gender" value="female">
<span class="radio-custom"></span>
<span class="radio-text">女</span>
</label>
</div>
<!-- 自定义复选框 -->
<div class="checkbox-group">
<label class="checkbox-label">
<input type="checkbox" name="hobby" value="reading">
<span class="checkbox-custom"></span>
<span class="checkbox-text">阅读</span>
</label>
<label class="checkbox-label">
<input type="checkbox" name="hobby" value="music">
<span class="checkbox-custom"></span>
<span class="checkbox-text">音乐</span>
</label>
</div>
<style>
/* 单选按钮 */
.radio-group {
display: flex;
gap: 20px;
margin-bottom: 20px;
}
.radio-label {
display: flex;
align-items: center;
cursor: pointer;
}
.radio-label input[type="radio"] {
display: none;
}
.radio-custom {
width: 20px;
height: 20px;
border: 2px solid #ddd;
border-radius: 50%;
margin-right: 8px;
position: relative;
transition: all 0.3s;
}
.radio-label input[type="radio"]:checked + .radio-custom {
border-color: #4CAF50;
}
.radio-label input[type="radio"]:checked + .radio-custom::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 10px;
height: 10px;
background: #4CAF50;
border-radius: 50%;
}
/* 复选框 */
.checkbox-group {
display: flex;
gap: 20px;
margin-bottom: 20px;
}
.checkbox-label {
display: flex;
align-items: center;
cursor: pointer;
}
.checkbox-label input[type="checkbox"] {
display: none;
}
.checkbox-custom {
width: 20px;
height: 20px;
border: 2px solid #ddd;
border-radius: 4px;
margin-right: 8px;
position: relative;
transition: all 0.3s;
}
.checkbox-label input[type="checkbox"]:checked + .checkbox-custom {
background: #4CAF50;
border-color: #4CAF50;
}
.checkbox-label input[type="checkbox"]:checked + .checkbox-custom::after {
content: '✓';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 14px;
font-weight: bold;
}
</style>
<label class="switch">
<input type="checkbox">
<span class="switch-slider"></span>
</label>
<style>
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.switch-slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: 0.4s;
border-radius: 34px;
}
.switch-slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
transition: 0.4s;
border-radius: 50%;
}
.switch input:checked + .switch-slider {
background-color: #4CAF50;
}
.switch input:checked + .switch-slider:before {
transform: translateX(26px);
}
</style>
<button class="btn btn-primary">主要按钮</button>
<button class="btn btn-secondary">次要按钮</button>
<button class="btn btn-success">成功按钮</button>
<button class="btn btn-danger">危险按钮</button>
<button class="btn btn-warning">警告按钮</button>
<button class="btn btn-info">信息按钮</button>
<style>
.btn {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: all 0.3s;
}
.btn-primary {
background: #007bff;
color: white;
}
.btn-primary:hover {
background: #0056b3;
}
.btn-secondary {
background: #6c757d;
color: white;
}
.btn-secondary:hover {
background: #545b62;
}
.btn-success {
background: #28a745;
color: white;
}
.btn-success:hover {
background: #1e7e34;
}
.btn-danger {
background: #dc3545;
color: white;
}
.btn-danger:hover {
background: #bd2130;
}
.btn-warning {
background: #ffc107;
color: #212529;
}
.btn-warning:hover {
background: #e0a800;
}
.btn-info {
background: #17a2b8;
color: white;
}
.btn-info:hover {
background: #117a8b;
}
</style>
<button class="btn btn-primary btn-sm">小按钮</button>
<button class="btn btn-primary">默认按钮</button>
<button class="btn btn-primary btn-lg">大按钮</button>
<button class="btn btn-primary btn-block">块级按钮</button>
<style>
.btn-sm {
padding: 6px 12px;
font-size: 12px;
}
.btn-lg {
padding: 14px 28px;
font-size: 16px;
}
.btn-block {
width: 100%;
}
</style>
<button class="btn btn-primary" disabled>禁用按钮</button>
<button class="btn btn-primary btn-loading">
<span class="spinner"></span>
加载中...
</button>
<style>
.btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.btn-loading {
position: relative;
padding-left: 40px;
}
.spinner {
display: inline-block;
width: 16px;
height: 16px;
border: 2px solid rgba(255,255,255,0.3);
border-top-color: white;
border-radius: 50%;
animation: spin 0.8s linear infinite;
position: absolute;
left: 15px;
top: 50%;
transform: translateY(-50%);
}
@keyframes spin {
to { transform: translateY(-50%) rotate(360deg); }
}
</style>
<!-- 成功状态 -->
<div class="form-group has-success">
<label for="input-success">成功输入</label>
<input type="text" id="input-success" class="form-control" value="正确">
<span class="success-message">✓ 输入正确</span>
</div>
<!-- 错误状态 -->
<div class="form-group has-error">
<label for="input-error">错误输入</label>
<input type="text" id="input-error" class="form-control" value="错误">
<span class="error-message">✗ 输入错误</span>
</div>
<!-- 警告状态 -->
<div class="form-group has-warning">
<label for="input-warning">警告输入</label>
<input type="text" id="input-warning" class="form-control" value="警告">
<span class="warning-message">⚠ 请检查输入</span>
</div>
<style>
.form-group {
margin-bottom: 20px;
}
.form-control {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
}
.has-success .form-control {
border-color: #28a745;
}
.has-error .form-control {
border-color: #dc3545;
}
.has-warning .form-control {
border-color: #ffc107;
}
.success-message {
color: #28a745;
font-size: 12px;
margin-top: 5px;
}
.error-message {
color: #dc3545;
font-size: 12px;
margin-top: 5px;
}
.warning-message {
color: #ffc107;
font-size: 12px;
margin-top: 5px;
}
</style>
<form>
<fieldset disabled>
<div class="form-group">
<label for="disabled-input">禁用输入</label>
<input type="text" id="disabled-input" class="form-control" value="禁用状态">
</div>
<button type="submit" class="btn btn-primary">禁用按钮</button>
</fieldset>
</form>
<style>
fieldset:disabled {
opacity: 0.6;
pointer-events: none;
}
</style>
<form class="form-responsive">
<div class="form-row">
<div class="form-group">
<label for="firstName">名</label>
<input type="text" id="firstName" name="firstName">
</div>
<div class="form-group">
<label for="lastName">姓</label>
<input type="text" id="lastName" name="lastName">
</div>
</div>
<div class="form-group">
<label for="email">邮箱</label>
<input type="email" id="email" name="email">
</div>
<button type="submit" class="btn btn-primary btn-block">提交</button>
</form>
<style>
.form-responsive {
max-width: 600px;
margin: 0 auto;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-bottom: 20px;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: 500;
}
input[type="text"],
input[type="email"] {
width: 100%;
padding: 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px; /* 移动端至少16px防止缩放 */
}
/* 移动端适配 */
@media (max-width: 576px) {
.form-row {
grid-template-columns: 1fr;
}
}
</style>
<!-- ✅ 推荐:清晰的标签和输入框 -->
<div class="form-group">
<label for="email">邮箱地址 *</label>
<input type="email" id="email" name="email" placeholder="请输入邮箱地址">
<span class="help-text">我们不会泄露您的邮箱地址</span>
</div>
<!-- ❌ 不推荐:标签不清晰 -->
<div class="form-group">
<input type="email" placeholder="邮箱">
</div>
<!-- ✅ 推荐:根据内容设置宽度 -->
<input type="text" name="zipcode" style="width: 120px;" placeholder="邮编">
<input type="text" name="phone" style="width: 200px;" placeholder="手机号">
<!-- ❌ 不推荐:所有输入框相同宽度 -->
<input type="text" name="zipcode" style="width: 100%;">
<input type="text" name="phone" style="width: 100%;">
<!-- ✅ 推荐:明确标记必填项 -->
<label for="email">
邮箱地址 <span class="required">*</span>
</label>
<!-- ❌ 不推荐:不标记必填项 -->
<label for="email">邮箱地址</label>
<!-- ✅ 推荐:具体的错误信息 -->
<span class="error-message">邮箱地址格式不正确,请输入有效的邮箱地址</span>
<!-- ❌ 不推荐:模糊的错误信息 -->
<span class="error-message">输入错误</span>
<!-- ✅ 推荐:使用合适的type触发移动端键盘 -->
<input type="tel" name="phone" pattern="[0-9]{11}">
<input type="email" name="email">
<input type="number" name="age">
<!-- ❌ 不推荐:全部使用text -->
<input type="text" name="phone">
<input type="text" name="email">
问题1:以下哪个CSS属性用于移除下拉框的默认箭头?
A. appearance: none
B. arrow: none
C. select-style: none
D. dropdown: none
答案:A
东巴文解释:appearance: none属性用于移除元素的默认样式,包括下拉框的默认箭头。其他选项都不是有效的CSS属性。
问题2:以下哪个伪类用于设置必填字段的样式?
A. :required
B. :mandatory
C. :necessary
D. :needed
答案:A
东巴文解释::required伪类用于选择设置了required属性的表单元素。其他选项都不是有效的CSS伪类。
任务:创建一个美观的登录表单,包含以下特性:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登录表单 - 东巴文</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.login-container {
background: white;
padding: 40px;
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
width: 100%;
max-width: 400px;
}
.login-header {
text-align: center;
margin-bottom: 30px;
}
.login-header h1 {
color: #333;
font-size: 28px;
margin-bottom: 10px;
}
.login-header p {
color: #666;
font-size: 14px;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 5px;
color: #555;
font-weight: 500;
font-size: 14px;
}
.input-group {
position: relative;
}
.input-icon {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: #999;
font-size: 18px;
}
input[type="text"],
input[type="password"] {
width: 100%;
padding: 12px 12px 12px 40px;
border: 2px solid #e0e0e0;
border-radius: 6px;
font-size: 14px;
transition: all 0.3s;
}
input[type="text"]:focus,
input[type="password"]:focus {
outline: none;
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
input[type="text"]:valid:not(:placeholder-shown),
input[type="password"]:valid:not(:placeholder-shown) {
border-color: #4CAF50;
}
input[type="text"]:invalid:not(:placeholder-shown),
input[type="password"]:invalid:not(:placeholder-shown) {
border-color: #f44336;
}
.error-message {
color: #f44336;
font-size: 12px;
margin-top: 5px;
display: none;
}
.form-options {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.checkbox-label {
display: flex;
align-items: center;
cursor: pointer;
font-size: 14px;
color: #666;
}
.checkbox-label input[type="checkbox"] {
display: none;
}
.checkbox-custom {
width: 18px;
height: 18px;
border: 2px solid #ddd;
border-radius: 4px;
margin-right: 8px;
position: relative;
transition: all 0.3s;
}
.checkbox-label input[type="checkbox"]:checked + .checkbox-custom {
background: #667eea;
border-color: #667eea;
}
.checkbox-label input[type="checkbox"]:checked + .checkbox-custom::after {
content: '✓';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 12px;
font-weight: bold;
}
.forgot-password {
color: #667eea;
text-decoration: none;
font-size: 14px;
transition: color 0.3s;
}
.forgot-password:hover {
color: #764ba2;
}
.btn-login {
width: 100%;
padding: 14px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
border-radius: 6px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: transform 0.3s, box-shadow 0.3s;
}
.btn-login:hover {
transform: translateY(-2px);
box-shadow: 0 5px 20px rgba(102, 126, 234, 0.4);
}
.btn-login:active {
transform: translateY(0);
}
.btn-login:disabled {
background: #ccc;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
.divider {
display: flex;
align-items: center;
margin: 30px 0;
}
.divider::before,
.divider::after {
content: '';
flex: 1;
height: 1px;
background: #e0e0e0;
}
.divider span {
padding: 0 15px;
color: #999;
font-size: 14px;
}
.social-login {
display: flex;
gap: 10px;
}
.btn-social {
flex: 1;
padding: 12px;
border: 2px solid #e0e0e0;
border-radius: 6px;
background: white;
cursor: pointer;
font-size: 18px;
transition: all 0.3s;
}
.btn-social:hover {
border-color: #667eea;
background: #f9f9f9;
}
.register-link {
text-align: center;
margin-top: 20px;
color: #666;
font-size: 14px;
}
.register-link a {
color: #667eea;
text-decoration: none;
font-weight: 500;
}
.register-link a:hover {
text-decoration: underline;
}
@media (max-width: 480px) {
.login-container {
padding: 30px 20px;
}
.login-header h1 {
font-size: 24px;
}
.form-options {
flex-direction: column;
align-items: flex-start;
gap: 10px;
}
}
</style>
</head>
<body>
<div class="login-container">
<div class="login-header">
<h1>东巴文</h1>
<p>欢迎回来,请登录您的账户</p>
</div>
<form id="loginForm">
<div class="form-group">
<label for="username">用户名或邮箱</label>
<div class="input-group">
<span class="input-icon">👤</span>
<input type="text" id="username" name="username"
required
placeholder="请输入用户名或邮箱"
autocomplete="username">
</div>
<span class="error-message" id="username-error">请输入用户名或邮箱</span>
</div>
<div class="form-group">
<label for="password">密码</label>
<div class="input-group">
<span class="input-icon">🔒</span>
<input type="password" id="password" name="password"
required minlength="6"
placeholder="请输入密码"
autocomplete="current-password">
</div>
<span class="error-message" id="password-error">请输入至少6位密码</span>
</div>
<div class="form-options">
<label class="checkbox-label">
<input type="checkbox" name="remember">
<span class="checkbox-custom"></span>
记住我
</label>
<a href="#" class="forgot-password">忘记密码?</a>
</div>
<button type="submit" class="btn-login">登录</button>
</form>
<div class="divider">
<span>或</span>
</div>
<div class="social-login">
<button class="btn-social" title="微信登录">💬</button>
<button class="btn-social" title="QQ登录">🐧</button>
<button class="btn-social" title="微博登录">📝</button>
</div>
<div class="register-link">
还没有账户?<a href="#">立即注册</a>
</div>
</div>
<script>
const form = document.getElementById('loginForm');
const username = document.getElementById('username');
const password = document.getElementById('password');
form.addEventListener('submit', function(e) {
e.preventDefault();
let isValid = true;
// 验证用户名
if (!username.value.trim()) {
document.getElementById('username-error').style.display = 'block';
isValid = false;
} else {
document.getElementById('username-error').style.display = 'none';
}
// 验证密码
if (password.value.length < 6) {
document.getElementById('password-error').style.display = 'block';
isValid = false;
} else {
document.getElementById('password-error').style.display = 'none';
}
if (isValid) {
alert('登录成功!欢迎回来!');
}
});
// 实时验证
username.addEventListener('input', function() {
if (this.value.trim()) {
document.getElementById('username-error').style.display = 'none';
}
});
password.addEventListener('input', function() {
if (this.value.length >= 6) {
document.getElementById('password-error').style.display = 'none';
}
});
</script>
</body>
</html>
</details>
东巴文(db-w.cn) - 让编程学习更有趣、更高效!