▣ 회원가입 초안
- html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="../css/join.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>
<div class="inner">
<div class="top-image">
<a href=""><img src="../img/img_ezenInside2.png" alt=""></a>
</div>
<div class="ess">
<span class="red">*</span>
<span>필수입력사항</span>
</div>
<form action="">
<div class="middle-information">
<div class="information">
<div class="id">
<span>아이디</span>
<span class="red">*</span>
<input type="text" class="in" id="username" placeholder="아이디를 입력해주세요.">
<input type="button" class="check-btn" value="중복확인">
</div>
<ul class="List">
<li class="success-message hide">O 사용 가능한 아이디입니다.</li>
<li class="failure-message hide">X 6자 이상의 영문 혹은 숫자를 조합해야 합니다.</li>
</ul>
<div class="pw">
<span>비밀번호</span>
<span class="red">*</span>
<input type="text" class="in" id="password" placeholder="비밀번호를 입력해주세요.">
</div>
<ul class="List">
<li class="success-message2 hide">O 사용 가능한 비밀번호입니다.</li>
<li class="failure-message2 hide">X 8글자 이상, 영문/숫자/특수문자(공백 제외)를 조합해야 합니다.</li>
</ul>
<div class="pw-check">
<span>비밀번호확인</span>
<span class="red">*</span>
<input type="text" class="in" id="password-retype" placeholder="동일한 비밀번호를 입력해주세요.">
</div>
<ul class="List">
<li class="mismatch-message hide">O 동일한 비밀번호입니다.</li>
</ul>
<div class="name">
<span>이름</span>
<span class="red">*</span>
<input type="text" class="in" placeholder="이름을 입력해주세요.">
</div>
<div class="email">
<span>이메일</span>
<span class="red">*</span>
<input type="text" class="in" placeholder="이메일을 입력해주세요.">
<input type="button" class="check-btn" value="중복확인">
</div>
<div class="phoneNumber">
<span>전화번호</span>
<span class="red">*</span>
<input type="text" class="in" placeholder="숫자만 입력해주세요.">
<input type="button" class="check-btn" value="인증번호 받기">
</div>
<div class="address">
<span>주소</span>
<span class="red">*</span>
<span>
<button type="button" class="addressBtn" id="addressBtn" onclick="sample6_execDaumPostcode()">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-search" viewBox="0 0 16 16">
<path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0"/>
</svg>
주소 검색
</button>
<br>
</span>
<div>
<input type="text" class="address-box" id="sample6_postcode" placeholder="우편번호">
<input type="text" class="address-box" id="sample6_address" placeholder="주소"><br>
<input type="text" class="address-box" id="sample6_detailAddress" placeholder="상세주소">
<input type="text" class="address-box" id="sample6_extraAddress" placeholder="참고항목">
</div>
</div>
<div class="gender">
<span>성별</span>
<span class="radio-check">
<label>
<input type="radio" name="contact" value="email">
<span>남성</span>
</label>
<label>
<input type="radio" name="contact" value="phone">
<span>여성</span>
</label>
<label>
<input type="radio" name="contact" value="mail" />
<span>상관없음</span>
</label>
</span>
</div>
<div class="birth">
<span>생년월일</span>
<span class="birth-container">
<input type="text" class="birth-box" placeholder="YYYY">
<span>/</span>
<input type="text" class="birth-box" placeholder="MM">
<span>/</span>
<input type="text" class="birth-box" placeholder="DD">
</span>
</div>
<div class="entrance">
<span>입학연도</span>
<span class="red">*</span>
<span>
<select id="entrance-list">
<option value="">연도 선택(학번)</option>
<option value="2024">2024학번</option>
<option value="2023">2023학번</option>
<option value="2022">2022학번</option>
<option value="2021">2021학번</option>
<option value="2020">2020학번</option>
<option value="2019">2019학번</option>
<option value="2018">2018학번</option>
<option value="2017">2017학번</option>
<option value="2016">2016학번</option>
<option value="2015">2015학번</option>
<option value="2014">2014학번</option>
<option value="2013">2013학번</option>
<option value="2012">2012학번</option>
<option value="2011">2011학번</option>
<option value="2010">2010학번</option>
<option value="2009">2009학번</option>
<option value="2008">2008학번</option>
<option value="2006">2007학번</option>
<option value="2007">2006학번</option>
<option value="2005">2005학번</option>
<option value="2004">2004학번</option>
<option value="2003">2003학번</option>
<option value="2002">2002학번</option>
<option value="2001">2001학번</option>
<option value="2000">2000학번</option>
<option value="1999">1999학번</option>
<option value="1998">1998학번</option>
<option value="1997">1997학번</option>
<option value="1996">1996학번</option>
<option value="1999">1995학번</option>
</select>
</span>
</div>
<div class="college">
<span>대학교</span>
<span class="red">*</span>
<input type="text" class="in inn" placeholder="학교 이름을 입력해주세요.">
</div>
<div class="major">
<span>학과 / 학부</span>
<span class="red">*</span>
<input type="text" class="in inn" placeholder="학과 또는 학부 이름을 입력해주세요.">
</div>
</div>
</div>
<div class="bottom-consent">
<span>이용약관동의</span>
<span class="red">*</span>
<span class="consent">
<div class="bottom-title">
<input type="checkbox" class="checkbox" id="allCheck" name="consentCheck" style="width: 20px; height: 20px;" onclick="selectAll(this)">
<label for="allCheck">전체 동의합니다.</label>
</div>
<div>
<input type="checkbox" class="checkbox" id="one" name="consentCheck" style="width: 20px; height: 20px; margin-top: 5px;">
<label for="one">이용약관 동의</label>
<span class="red">(필수)</span>
<a href="">
<span class="clauseFirst">약관보기 ></span>
</a>
</div>
<div>
<input type="checkbox" class="checkbox" id="two" name="consentCheck" style="width: 20px; height: 20px; margin-top: 5px;">
<label for="two">개인정보 수집·이용 동의</label>
<span class="red">(필수)</span>
<a href="">
<span class="clause">약관보기 ></span>
</a>
</div>
<div>
<input type="checkbox" class="checkbox" id="three" name="consentCheck" style="width: 20px; height: 20px; margin-top: 5px;">
<label for="three">개인정보 수집·이용 동의</label>
<span class="red">(선택)</span>
<a href="">
<span class="clause">약관보기 ></span>
</a>
</div>
<div>
<input type="checkbox" class="checkbox" id="four" name="consentCheck" style="width: 20px; height: 20px; margin-top: 5px;">
<label for="four">정보 수신 동의</label>
<span class="red">(선택)</span>
</div>
<div>
<input type="checkbox" class="checkbox" id="five" name="consentCheck" style="width: 20px; height: 20px; margin-top: 5px;">
<label for="five">본인은 만 14세 이상입니다.</label>
<span class="red">(필수)</span>
</div>
<div class="joinBtn"><input type="button" class="signup" value="가입하기"></div>
</span>
</div>
</form>
</div>
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script src="../js/join.js"></script>
</body>
</html>
- css
@font-face {
font-family: "NotoSansKR";
src: url(../font/NotoSansKR-VariableFont_wght.ttf);
}
body {
font-family: "NotoSansKR";
}
.inner{
width: 1280px;
}
.red{
color: #FFA100;
font-size: 15px;
font-weight: 700;
}
.inner>.top-image{
width: 100%;
}
.inner>.ess{
position: absolute;
top: 27%;
left: 66%;
}
.inner>.top-image>a>img{
width: 240px;
position: absolute;
top: 15%;
left: 50%;
transform: translate(-50%, -50%);
}
.inner>form>.middle-information{
position: absolute;
width: 960px;
border-top: 5px solid #737373;
border-bottom: 5px solid #737373;
top: 30%;
left: 50%;
transform: translate(-50%);
padding: 20px 0 20px 150px;
}
.inner>form>.middle-information>.information{
width: 650px;
}
.inner>form>.middle-information>.information .check-btn{
margin-left: 10px;
padding: 5px 20px;
border: 2px solid #FFA100;
color: #FFA100;
font-size: 15px;
font-weight: 500;
/* 형광펜 css */
background: linear-gradient(to right, transparent 50%, #FF9900 50%) ;
background-size: 200%;
font-weight: 700;
transition: .25s;
}
.inner>form>.middle-information>.information .check-btn:hover{
color: white;
/* 형광펜 css */
background-position: -100%,0;
}
.in{
width: 350px;
height: 45px;
padding: 10px;
box-sizing: border-box;
margin-bottom: 10px;
border: 3px solid #a6a6a625;
outline: none;
font-size: 15px;
font-weight: 500;
}
.inner>form>.middle-information>.information>ul{
margin: 0 0 20px 110px;
}
.inner>form>.middle-information>.information>ul>li{
margin: 0 5px 5px 5px;
list-style: none;
}
.inner>form>.middle-information>.information>.id>.in{
margin-left: 70px;
}
.inner>form>.middle-information>.information>.pw>.in{
margin-left: 55px;
}
.inner>form>.middle-information>.information>.pw-check{
margin-bottom: 15px;
}
.inner>form>.middle-information>.information>.pw-check>.in{
margin-left: 25px;
}
.inner>form>.middle-information>.information>.name{
margin-bottom: 15px;
}
.inner>form>.middle-information>.information>.name>.in{
margin-left: 90px;
}
.inner>form>.middle-information>.information>.email{
margin-bottom: 15px;
}
.inner>form>.middle-information>.information>.email>.in{
margin-left: 75px;
}
.inner>form>.middle-information>.information>.phoneNumber{
margin-bottom: 15px;
}
.inner>form>.middle-information>.information>.phoneNumber>.in{
margin-left: 60px;
}
.inner>form>.middle-information>.information>.address>span>.addressBtn{
margin-left: 92px;
width: 351px;
height: 45px;
background-color: white;
border: 3px solid #FFA100;
color: #FFA100;
font-size: large;
font-weight: 700;
/* 형광펜 css */
background: linear-gradient(to right, transparent 50%, #FF9900 50%) ;
background-size: 200%;
font-weight: 700;
transition: .25s;
}
.inner>form>.middle-information>.information>.address>span>.addressBtn:hover{
color: white;
/* 형광펜 css */
background-position: -100%,0;
}
.bi-search{
margin-bottom: 3px;
}
.inner>form>.middle-information>.information>.address>div{
margin: 30px 0 15px 140px;
}
.inner>form>.middle-information>.information>.address>div>.address-box{
width: 175px;
height: 30px;
margin-bottom: 5px;
padding: 10px;
box-sizing: border-box;
margin-bottom: 10px;
border: 3px solid #a6a6a625;
outline: none;
font-size: 15px;
font-weight: 500;
}
/* radio css 효과 */
label {
font-size: 18px;
line-height: 2rem;
padding: 0.2em 0.4em;
}
[type="radio"], span {
vertical-align: middle;
}
[type="radio"] {
appearance: none;
border: max(2px, 0.1em) solid gray;
border-radius: 50%;
width: 1.25em;
height: 1.25em;
transition: border 0.2s ease-in-out;
}
[type="radio"]:checked {
border: 0.4em solid #FF9900;
}
[type="radio"]:focus-visible {
outline-offset: max(2px, 0.1em);
outline: max(2px, 0.1em) dotted #FF9900;
}
[type="radio"]:hover {
box-shadow: 0 0 0 max(4px, 0.2em) lightgray;
cursor: pointer;
}
[type="radio"]:hover + span {
cursor: pointer;
}
/* Global CSS */
*,
*::before,
*::after {
box-sizing: border-box;
}
.inner>form>.middle-information>.information>.gender{
display: flex;
align-items: center;
margin-bottom: 15px;
}
.inner>form>.middle-information>.information>.gender>.radio-check{
margin-left: 85px;
}
.inner>form>.middle-information>.information>.gender>.radio-check>label{
margin: 0 20px;
}
.inner>form>.middle-information>.information>.birth{
margin-bottom: 15px;
}
.inner>form>.middle-information>.information>.birth>.birth-container{
display: inline-block;
width: 360px;
border: 3px solid #a6a6a625;
margin-left: 70px;
}
.inner>form>.middle-information>.information>.birth>.birth-container>span{
position: absolute;
line-height: 45px;
color: #737373;
}
.inner>form>.middle-information>.information>.birth>.birth-container>.birth-box{
width: 60px;
height: 45px;
padding: 10px;
border: none;
outline: none;
font-size: 15px;
font-weight: 500;
margin: 0 20px 0 35px;
}
.inner>form>.middle-information>.information>.birth>.birth-container>.birth-box:first-child{
margin-left: 34px;
}
.inner>form>.middle-information>.information>.entrance{
margin-bottom: 15px;
}
.inner>form>.middle-information>.information>.entrance>span>select{
margin-left: 55px;
padding: 10px;
width: 360px;
height: 45px;
border: 3px solid #a6a6a625;
color: #737373;
}
.inn{
width: 360px;
}
.inner>form>.middle-information>.information>.college{
margin-bottom: 15px;
}
.inner>form>.middle-information>.information>.college>.in{
margin-left: 70px;
}
.inner>form>.middle-information>.information>.major{
margin-bottom: 15px;
}
.inner>form>.middle-information>.information>.major>.in{
margin-left: 38px;
}
.inner>form>.bottom-consent{
position: absolute;
width: 980px;
top: 140%;
left: 50%;
background-color: none;
transform: translate(-50%);
padding: 20px 0 20px 150px;
display: flex;
}
.inner>form>.bottom-consent>.consent{
margin-left: 30px;
}
.inner>form>.bottom-consent>.consent>div{
margin: 20px;
}
.inner>form>.bottom-consent>.consent>.bottom-title>div{
font-size: 15px;
font-weight: 700;
}
.inner>form>.bottom-consent>.consent>div>.checkbox{
accent-color: #FF9900;
margin-right: 20px;
vertical-align: text-top;
}
.inner>form>.bottom-consent>.consent>div>a{
font-size: 15px;
font-weight: 500;
text-decoration: none;
color: #FF9900;
}
.inner>form>.bottom-consent>.consent>div>a>.clause{
margin-left: 200px;
}
.inner>form>.bottom-consent>.consent>div>a>.clauseFirst{
margin-left: 280px;
}
.joinBtn>input{
margin: 50px 0 0 5px;
width: 351px;
height: 45px;
background-color: white;
border: 3px solid #FFA100;
color: #FFA100;
font-size: large;
font-weight: 700;
/* 형광펜 css */
background: linear-gradient(to right, transparent 50%, #FF9900 50%) ;
background-size: 200%;
font-weight: 700;
transition: .25s;
}
.joinBtn>input:hover{
color: white;
/* 형광펜 css */
background-position: -100%,0;
}
- js
// 카카오 주소 api
function sample6_execDaumPostcode() {
new daum.Postcode({
oncomplete: function(data) {
// 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.
// 각 주소의 노출 규칙에 따라 주소를 조합한다.
// 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
var addr = ''; // 주소 변수
var extraAddr = ''; // 참고항목 변수
//사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
addr = data.roadAddress;
} else { // 사용자가 지번 주소를 선택했을 경우(J)
addr = data.jibunAddress;
}
// 사용자가 선택한 주소가 도로명 타입일때 참고항목을 조합한다.
if(data.userSelectedType === 'R'){
// 법정동명이 있을 경우 추가한다. (법정리는 제외)
// 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
if(data.bname !== '' && /[동|로|가]$/g.test(data.bname)){
extraAddr += data.bname;
}
// 건물명이 있고, 공동주택일 경우 추가한다.
if(data.buildingName !== '' && data.apartment === 'Y'){
extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
}
// 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
if(extraAddr !== ''){
extraAddr = ' (' + extraAddr + ')';
}
// 조합된 참고항목을 해당 필드에 넣는다.
document.getElementById("sample6_extraAddress").value = extraAddr;
} else {
document.getElementById("sample6_extraAddress").value = '';
}
// 우편번호와 주소 정보를 해당 필드에 넣는다.
document.getElementById('sample6_postcode').value = data.zonecode;
document.getElementById("sample6_address").value = addr;
// 커서를 상세주소 필드로 이동한다.
document.getElementById("sample6_detailAddress").focus();
}
}).open();
}
// 체크박스 모두 체크
function selectAll(selectAll) {
const checkboxes
= document.querySelectorAll('input[type="checkbox"]');
checkboxes.forEach((checkbox) => {
checkbox.checked = selectAll.checked
})
};
▷ 출력
◈ 형광펜 효과
- html
<p>일상에 마주하는 불편함을 <span>새로운 가능성으로 만들겠습니다.</span></p>
- css
span{
background: linear-gradient(to right, transparent 50%, #ddbdd5 50%) ;
background-size: 200%;
font-weight: 700;
transition: .35s;
}
span:hover{
background-position: -100%,0;
}
- background에서 linner-gradient를 이용해 오른쪽으로 절반은 투명, 절반은 원하는 색을 넣어줍니다.
- background-size를 이용해 투명한 부분만 보이도록 200%로 지정해줍니다.
- hover시 background-position에 x축의 -100%를 주어 색상을 입력한 절반 부분이 보이도록 해줍니다.
-> 인라인 속성(display:inline)이거나 인라인 요소(span, a, img..)이어야만 효과를 볼 수 있습니다.
▷ 출력
◈ radio 스타일링
- html
<fieldset>
<label>
<input type="radio" name="contact" value="email" checked />
<span>이메일</span>
</label>
<label>
<input type="radio" name="contact" value="phone" />
<span>전화</span>
</label>
<label>
<input type="radio" name="contact" value="fax" disabled />
<span>팩스</span>
</label>
<label>
<input type="radio" name="contact" value="mail" />
<span>우편</span>
</label>
</fieldset>
- css
label {
font-size: 18px;
line-height: 2rem;
padding: 0.2em 0.4em;
}
[type="radio"], span {
vertical-align: middle;
}
[type="radio"] {
appearance: none;
border: max(2px, 0.1em) solid gray;
border-radius: 50%;
width: 1.25em;
height: 1.25em;
transition: border 0.5s ease-in-out;
}
[type="radio"]:checked {
border: 0.4em solid tomato;
}
[type="radio"]:focus-visible {
outline-offset: max(2px, 0.1em);
outline: max(2px, 0.1em) dotted tomato;
}
[type="radio"]:hover {
box-shadow: 0 0 0 max(4px, 0.2em) lightgray;
cursor: pointer;
}
[type="radio"]:hover + span {
cursor: pointer;
}
[type="radio"]:disabled {
background-color: lightgray;
box-shadow: none;
opacity: 0.7;
cursor: not-allowed;
}
[type="radio"]:disabled + span {
opacity: 0.7;
cursor: not-allowed;
}
/* Global CSS */
fieldset {
display: flex;
justify-content: center;
border: none;
margin: 0;
padding: 40px 20px;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
- 라디오 버튼과 레이블 텍스트간 정렬
label {
font-size: 18px;
line-height: 2rem;
padding: 0.2em 0.4em;
}
[type="radio"],
span {
vertical-align: middle;
}
- 기본 스타일 제거
[type="radio"] {
vertical-align: middle;
appearance: none;
}
- 라디오 버튼 스타일
[type="radio"] {
vertical-align: middle;
appearance: none;
border: max(2px, 0.1em) solid gray;
border-radius: 50%;
width: 1.25em;
height: 1.25em;
}
- 체크 상태 스타일
[type="radio"]:checked {
border: 0.4em solid tomato;
}
- 포커스 상태 스타일
[type="radio"]:focus-visible {
outline: max(2px, 0.1em) dotted tomato;
outline-offset: max(2px, 0.1em);
}
- 호버 상태 스타일
[type="radio"]:hover {
box-shadow: 0 0 0 max(4px, 0.2em) lightgray;
cursor: pointer;
}
[type="radio"]:hover + span {
cursor: pointer;
}
- 불능 상태 스타일
[type="radio"]:disabled {
background-color: lightgray;
box-shadow: none;
opacity: 0.7;
cursor: not-allowed;
}
[type="radio"]:disabled + span {
opacity: 0.7;
cursor: not-allowed;
}
- 애니메이션 효과
[type="radio"] {
vertical-align: middle;
appearance: none;
border: max(2px, 0.1em) solid gray;
border-radius: 50%;
width: 1.25em;
height: 1.25em;
transition: border 0.5s ease-in-out;
}
▷ 출력
◈ checkbox 전체 선택 및 해제
- html
<input type='checkbox'
name='animal'
value='selectall'
onclick='selectAll(this)'/> <b>Select All</b>
<br />
<input type='checkbox'
name='animal'
value='dog'/> 개
<br />
<input type='checkbox'
name='animal'
value='cat' /> 고양이
<br />
<input type='checkbox'
name='animal'
value='rabbit' /> 토끼
- js
function selectAll(selectAll) {
const checkboxes
= document.getElementsByName('animal');
checkboxes.forEach((checkbox) => {
checkbox.checked = selectAll.checked;
})
}
▷ 출력
- 느낀 점
회원가입의 유효성 검사가 너무 복잡했던 것 같아서 너무 힘들었다.. 회원가입 코드를 다시 보면서 복습을 해야겠다!
'Project > AWS-Front' 카테고리의 다른 글
화면 프로젝트 (6) - AWS 풀스택 과정 30일차 (0) | 2024.08.26 |
---|---|
화면 프로젝트 (5) - AWS 풀스택 과정 29일차 (0) | 2024.08.23 |
화면 프로젝트 (3) - AWS 풀스택 과정 27일차 (0) | 2024.08.21 |
화면 프로젝트 (2) - AWS 풀스택 과정 26일차 (0) | 2024.08.20 |
화면 프로젝트 (1) - AWS 풀스택 과정 25일차 (0) | 2024.08.19 |