HTML 구조 설계
기본적인 로그인 폼은 중앙에 위치한 컨테이너로 구성되며, 사용자 이름과 비밀번호 입력 필드, 자동 로그인 체크박스, 제출 버튼 및 추가 링크 요소를 포함합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>사용자 인증 페이지</title>
<link rel="stylesheet" href="styles/login-form.css">
<script src="scripts/form-validation.js" defer></script>
</head>
<body>
<div class="login-container">
<form id="authForm">
<div class="logo-section">
<span class="form-title">계정 로그인</span>
</div>
<div class="error-message"></div>
<div class="input-group">
<input type="text" id="usernameInput" placeholder="아이디 또는 휴대폰 번호" />
</div>
<div class="input-group">
<input type="password" id="passwordInput" placeholder="비밀번호" />
</div>
<div class="checkbox-wrapper">
<input type="checkbox" id="autoLogin" />
<label for="autoLogin" class="checkbox-label">다음에 자동 로그인</label>
</div>
<button type="submit" class="submit-btn">로그인</button>
<div class="forgot-link">
<a href="#">비밀번호를 잊으셨나요?</a>
</div>
</form>
<div class="footer-links">
<div class="qr-login">
<a href="#">QR 코드로 로그인</a>
</div>
<div class="register-link">
<a href="#">회원가입하기</a>
</div>
</div>
</div>
</body>
</html>
CSS 스타일링 및 반응형 처리
중앙 정렬을 위한 레이아웃과 클릭 시 효과를 주는 스타일을 적용하며, 포커스 상태와 호버 상태에 따라 색상 변화를 구현합니다.
.login-container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 360px;
height: 400px;
border: 1px solid #ddd;
font-family: 'Segoe UI', sans-serif;
background-color: #fff;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
form {
padding: 28px;
height: 300px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.logo-section {
text-align: center;
margin-bottom: 20px;
}
.form-title {
font-size: 18px;
color: #1a1a1a;
background-image: url('../assets/logo.svg');
background-repeat: no-repeat;
background-position: center left;
background-size: 16px 16px;
padding-left: 24px;
line-height: 28px;
}
.error-message {
height: 20px;
font-size: 12px;
color: #d93025;
margin-bottom: 10px;
visibility: hidden;
}
.input-group input {
width: 100%;
height: 44px;
padding: 12px 14px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 14px;
transition: border-color 0.2s ease;
}
.input-group input:focus {
outline: none;
border-color: #4c7aff;
box-shadow: 0 0 0 2px rgba(76, 122, 255, 0.2);
}
.checkbox-wrapper {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 16px;
}
.checkbox-label {
font-size: 13px;
color: #666;
cursor: pointer;
}
.checkbox-wrapper input {
width: 14px;
height: 14px;
border: 1px solid #aaa;
border-radius: 2px;
accent-color: #4c7aff;
}
.submit-btn {
width: 100%;
height: 42px;
background-color: #4c7aff;
color: white;
border: none;
border-radius: 6px;
font-size: 15px;
font-weight: 500;
cursor: pointer;
transition: background-color 0.2s ease;
}
.submit-btn:hover {
background-color: #3b67e5;
}
.forgot-link a {
font-size: 13px;
color: #4c7aff;
text-decoration: none;
}
.footer-links {
display: flex;
justify-content: space-between;
align-items: center;
height: 70px;
background-color: #f4f7ff;
padding: 0 24px;
border-top: 1px solid #e0e0e0;
}
.footer-links a {
text-decoration: none;
font-size: 14px;
color: #4c7aff;
transition: opacity 0.2s ease;
}
.footer-links a:hover {
opacity: 0.8;
}
JavaScript 기능 확장
폼 유효성 검사 및 사용자 입력 추적을 위한 간단한 스크립트를 추가하여 실시간 피드백을 제공합니다.
document.getElementById('authForm').addEventListener('submit', function (event) {
event.preventDefault();
const username = document.getElementById('usernameInput').value.trim();
const password = document.getElementById('passwordInput').value;
const errorElement = document.querySelector('.error-message');
if (!username || !password) {
errorElement.textContent = '모든 항목을 입력해주세요.';
errorElement.style.visibility = 'visible';
return;
}
// 실제 인증 로직은 여기서 수행됨
alert('로그인 요청이 전송되었습니다.');
errorElement.style.visibility = 'hidden';
});