Skip to content

Conversation

@anarose314
Copy link
Collaborator

진행한 미션 버전

  • 초급 (Ver 1)
  • 중급 (Ver 2)

미션 요구사항

[ 미션3 ] 기본

공통

  • 브라우저에 현재 보이는 화면의 영역(viewport) 너비를 기준으로 분기되는 반응형 디자인을 적용합니다.
    • PC: 1200px 이상
    • Tablet: 768px 이상 ~ 1199px 이하
    • Mobile: 375px 이상 ~ 767px 이하
    • 375px 미만 사이즈의 디자인은 고려하지 않습니다

랜딩 페이지

  • Tablet 사이즈로 작아질 때 “판다마켓” 로고의 왼쪽에 여백 24px, “로그인” 버튼 오른쪽 여백 24px을 유지할 수 있도록 “판다마켓” 로고와 “로그인" 버튼의 간격이 가까워집니다.
  • Mobile 사이즈로 작아질 때 “판다마켓” 로고의 왼쪽에 여백 16px, “로그인” 버튼 오른쪽 여백 16px을 유지할 수 있도록 “판다마켓” 로고와 “로그인" 버튼의 간격이 가까워집니다.
  • 화면 영역이 줄어들면 “Privacy Policy”, “FAQ”, “codeit-2024”이 있는 영역과 SNS 아이콘들이 있는 영역의 간격이 줄어듭니다.

로그인, 회원가입 페이지 공통

  • Tablet 사이즈에서 내부 디자인은 PC사이즈와 동일합니다.
  • Mobile 사이즈에서 좌우 여백 16px 제외하고 내부 요소들이 너비를 모두 차지합니다.
  • Mobile 사이즈에서 내부 요소들의 너비는 기기의 너비가 커지는 만큼 커지지만 400px을 넘지 않습니다.

[ 미션3 ] 심화

  • 페이스북, 카카오톡, 디스코드, 트위터 등 SNS에서 Linkbrary 랜딩 페이지(“/”) 공유 시 좌측 예시와 같은 미리보기를 볼 수 있도록 랜딩 페이지 메타 태그를 설정해 주세요.
  • 미리보기에서 제목은 “판다 마켓”, 설명은 “일상의 모든 물건을 거래해보세요”로 설정합니다.
  • 주소와 이미지는 자유롭게 설정하세요.

[ 미션4 ] 기본

로그인

  • 이메일 input에서 focus out 할 때, 값이 없을 경우 input에 빨강색 테두리와 아래에 "이메일을 입력해주세요." 빨강색 에러 메세지를 보입니다.
  • 이메일 input에서 focus out 할 때, 이메일 형식에 맞지 않는 경우 input에 빨강색 테두리와 아래에 "잘못된 이메일 형식입니다" 빨강색 에러 메세지를 보입니다.
  • 비밀번호 input에서 focus out 할 때, 값이 없을 경우 아래에 "비밀번호를 입력해주세요." 에러 메세지를 보입니다
  • 비밀번호 input에서 focus out 할 때, 값이 8자 미만일 경우 아래에 "비밀번호를 8자 이상 입력해주세요." 에러 메세지를 보입니다.
  • input 에 빈 값이 있거나 에러 메세지가 있으면 '로그인' 버튼은 비활성화 됩니다.
  • input 에 유효한 값을 입력하면 '로그인' 버튼이 활성화 됩니다.
  • 활성화된 '로그인' 버튼을 누르면 "/items" 로 이동합니다

회원가입

  • 이메일 input에서 focus out 할 때, 값이 없을 경우 input에 빨강색 테두리와 아래에 "이메일을 입력해주세요." 빨강색 에러 메세지를 보입니다.
  • 이메일 input에서 focus out 할 때, 이메일 형식에 맞지 않는 경우 input에 빨강색 테두리와 아래에 "잘못된 이메일 형식입니다" 빨강색 에러 메세지를 보입니다.
  • 닉네임 input에서 focus out 할 때, 값이 없을 경우 input에 빨강색 테두리와 아래에 "닉네임을 입력해주세요." 빨강색 에러 메세지를 보입니다.
  • 비밀번호 input에서 focus out 할 때, 값이 없을 경우 아래에 "비밀번호를 입력해주세요." 에러 메세지를 보입니다
  • 비밀번호 input에서 focus out 할 때, 값이 8자 미만일 경우 아래에 "비밀번호를 8자 이상 입력해주세요." 에러 메세지를 보입니다.
  • 비밀번호 input과 비밀번호 확인 input의 값이 다른 경우, 비밀번호 확인 input 아래에 "비밀번호가 일치하지 않습니다.." 에러 메세지를 보입니다.
  • input 에 빈 값이 있거나 에러 메세지가 있으면 '회원가입' 버튼은 비활성화 됩니다.
  • input 에 유효한 값을 입력하면 '회원가입' 버튼이 활성화 됩니다.
  • 활성화된 '회원가입' 버튼을 누르면 로그인 페이지로 이동합니다

[ 미션4 ] 심화

  • 눈 모양 아이콘 클릭시 비밀번호의 문자열이 보이기도 하고, 가려지기도 합니다.
  • 비밀번호의 문자열이 가려질 때는 눈 모양 아이콘에는 사선이 그어져있고, 비밀번호의 문자열이 보일 때는 사선이 없는 눈 모양 아이콘이 보이도록 합니다.

주요 변경사항 및 학습 포인트

[ 미션 2 ]

미션2 풀리퀘스트

1. css/common.css

* {
  box-sizing: border-box;
}

img {
  display: block;
  max-width: 100%;
  width: 100%;
}

일반적으로 적용하는 이 속성들은 왜 이렇게 선언하는 걸까요?
다음 미션 때 학습 포인트로 적어보면 좋을 것 같아요. 🤩

< box-sizing: border-box 부분 >

모든 요소의 box-sizing 속성의 기본 값 : content-box

  • box-sizing: content-box 의 실제 div 크기 : width + padding + border
  • box-sizing: border-box 의 실제 div 크기 : padding 값과 border 값이 포함된 width

즉, 레이아웃을 디자이너 시안대로 편히 적용하기 위해 border-box 를 적용

< img 부분 >

  • display: block; : img 는 기본적으로 inline 요소라 baseline을 따라감
    그로 인해 이미지 아래에 약간의 여백이 발생하기 때문에, 이 불필요한 여백을 제거하기 위해 block 값을 부여
  • max-width: 100%; : 이미지가 부모 요소를 넘어 가는 것을 방지하고, 후에 반응형 적용 시에도 이미지가 가변되는 효과를 줌
  • width: 100%; : 위의 max-width: 100% 는 부모의 너비를 넘치지 않게만 하기 때문에, 부모보다 작은 이미지를 사용하면 상황에 따라 레이아웃이 깨지는 경우가 있음. 이를 방지하고 이미지가 항상 부모 너비만큼 너비를 채우기 위해 사용

2. index.html

          </div>
          <div class="hero__img">
            <img src="img/img_home_top.png" alt="" />

여기서도 생각할 만한 점이 있어요. alt 속성의 값을 비워놓으셨는데, 의도한 것으로 보여요. 이에 대한 이유와 다른 방법도 있는데 이렇게 구현한 이유도 함께 다음 미션에서 설명해주시면 좋을 것 같아요! 😊

  • alt의 경우, 이미지가 표시되지 않을 때 대체 텍스트를 표시하는 역할이 있지만, 시각 장애를 갖고 계신 분들이 스크린 리더를 사용하여 웹사이트를 탐색할 때, 이미지의 내용을 설명해주는 기능도 갖고 있음
  • 그렇기에 꼭 설명이 필요하지 않은 단순 디자인용 이미지의 경우, 큰 의미 없이 alt를 쓰면 오히려 정보 탐색을 불편하게 할 수 있기 때문에, alt="" 로 값을 비움

3. index.html

      <section class="intro">
        <div class="intro__wrap">
          <article class="intro__item">

article 태그를 사용하신 이유는 무엇일까요? 이 부분도 함께 작성해주시면 좋겠네요! 🧐

  • 먼저 section 으로 각 영역 ( 히어로 / 본문 / 아래쪽 히어로 ) 을 구분
  • 그 중 본문은 Hot item / Search / Register 라는 각각의 기능을 소개하는 의미 있는 콘텐츠로 구성되어 있었기에, 각 소개 블록에 div 대신 시멘틱 태그 article 사용

[ 미션 3 ]

  • 반응형으로 작업하면서, 모바일용 이미지와 포맷 맞추기 위해 png이미지 svg로 변경
  • index.html의 rem 사이즈 → px로 변경하면서 전체적으로 피그마와 더 맞게 사이즈 재조정
  • 웹폰트 이용하여 전체 폰트 피그마와 동일한 폰트로 변경
  • 로그인 / 회원가입 페이지 버튼 색 미션3 색상으로 변경 & placeholder 추가

[ 미션 4 ]

  • 이메일 형식 확인 방법에 대해 인터넷 검색 후 가장 많이 쓰이는 듯한 표현식을 사용
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
/ : 정규식 시작
^ : 문자열 시작
[a-zA-Z0-9._%+-] : 이메일 아이디 부분 ( 영문 대소문자, 숫자, 점, 밑줄, 퍼센트, 플러스, 하이픈 )
`+` : 1글자 이상
@ : 이메일 기호
[a-zA-Z0-9.-] : 도메인 이름 부분 ( 영문 대소문자, 숫자, 점, 하이픈 ) e.g : gmail, naver
`+` : 1글자 이상
\. : 점이라는 의미
[a-zA-Z] : 최상위 도메인 부분 ( 영문 대소문자 ) e.g : com, net, co, kr
{2,} : 2글자 이상
$ : 문자열 끝
/ : 정규식 끝
  • 모든 폼이 정상 입력되었을 때 버튼 활성 방법에 대해 고민, 객체에 불린값을 저장하여 조건을 충족하면 true가 되는 방법이 좋아보여 이 방법으로 작성
  • 이메일/닉네임/비밀번호 : 과제 지시대로 포커스아웃시에 동작하게 이벤트 추가
  • 비밀번호확인/버튼활성화 : 입력 완료 시 작동하게 하기 위해 keyup ( 키보드 버튼을 눌렀다 떼는 순간 ) 이벤트 사용
  • 로그인과 회원가입 페이지는 폼의 개수가 다르지만 동작 자체는 같기 때문에, 스크립트 하나로 어느 페이지에서도 사용할 수 있게 작성
  • 비밀번호/비밀번호체크 입력이 정상 완료된 후에 비밀번호 수정을 하게될 시 동작이 꼬이는 현상 ( 버튼이 활성화된 상태로 유지/비밀번호가 달라지고 있음에도 표시 안뜸 ) 을 확인하여, 어느쪽을 먼저 수정하더라도 위화감 없게 동작하도록 코드 수정
  • figma 디자인을 참고해서 문제 없이 값이 입력되면, 에러 때랑 달리 입력폼에 파란 테두리가 뜨게 설정
  • 폼 체크 동작 중복 등 여러모로 길어지는 코드가 많아, 최대한 길이를 줄여보기 위해 리팩토링

※ 미션과 관련 없지만 .gitignore 설정하고 싶어서 커밋 했습니다! 작업 내용과는 따로 커밋을 분리했지만 참고 부탁 드립니다!


주강사에게

집중적으로 봐줬으면 하는 부분

  • 미션 4 ... 자바스크립트를 처음부터 끝까지 작성해 본 것은 거의 처음이라 이 부분을 집중적으로 봐주시면 감사합니다!
    • 더 효율적인 로직
    • 리팩토링 가능한 부분 등...

해결하지 못한 문제 / 궁금한 점

  • 실무에서 쓰는 이메일 형식 확인 방법이 궁금합니다!

@anarose314 anarose314 added the 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. label Dec 31, 2025
Copy link
Collaborator

@ByungyeonKim ByungyeonKim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

예지님, 안녕하세요!

작성하신 내용보고 저 솔직히 조금 감동했습니다..🥹
이렇게나 열심히 준비해오실 줄이야!
게다가 꼼꼼하고 깔끔하게 잘 정리해주셨네요.

사실 저는 실무에서 문서화도 굉장히 중요한 능력 중 하나라고 믿어요.
예지님은 무슨 일을 하셔도 잘 하실 거라 생각합니다. 👍
열심히 하시는 모습 정말 보기 좋습니다!

피드백 바로 시작할게요~!

즉, 레이아웃을 디자이너 시안대로 편히 적용하기 위해 border-box 를 적용

: 맞습니다. 우리가 일반적인 상식에서 의도한 대로 디자인을 적용하기 위함이죠. box-sizing은 CSS의 기초 개념 중 박스 모델과 연관이 있어요. 박스 모델의 개념과 구성을 보시면 왜 이름이 content-box이고 border-box인지 더 이해가 잘 되실 거예요.

display: block; : img 는 기본적으로 inline 요소라 baseline을 따라감
그로 인해 이미지 아래에 약간의 여백이 발생하기 때문에, 이 불필요한 여백을 제거하기 위해 block 값을 부여
max-width: 100%; : 이미지가 부모 요소를 넘어 가는 것을 방지하고, 후에 반응형 적용 시에도 이미지가 가변되는 효과를 줌
width: 100%; : 위의 max-width: 100% 는 부모의 너비를 넘치지 않게만 하기 때문에, 부모보다 작은 이미지를 사용하면 상황에 따라 레이아웃이 깨지는 경우가 있음. 이를 방지하고 이미지가 항상 부모 너비만큼 너비를 채우기 위해 사용

: 그렇죠~항상 '왜' 이렇게 코드를 작성하는지 호기심을 갖고 학습하시면 좋습니다. 너무 잘해주셨습니다.

alt의 경우, 이미지가 표시되지 않을 때 대체 텍스트를 표시하는 역할이 있지만, 시각 장애를 갖고 계신 분들이 스크린 리더를 사용하여 웹사이트를 탐색할 때, 이미지의 내용을 설명해주는 기능도 갖고 있음
그렇기에 꼭 설명이 필요하지 않은 단순 디자인용 이미지의 경우, 큰 의미 없이 alt를 쓰면 오히려 정보 탐색을 불편하게 할 수 있기 때문에, alt="" 로 값을 비움

: 이유가 명확하고 좋습니다. 기술 면접에서도 동일하게, 예지님이 이렇게 코드를 작성한 이유를 잘 설명할 수 있으면 됩니다. 단순히 디자인용 이미지거나 텍스트가 충분히 내용을 설명하고 있다면 alt 속성값을 비워놔도 되죠. 💯

먼저 section 으로 각 영역 ( 히어로 / 본문 / 아래쪽 히어로 ) 을 구분
그 중 본문은 Hot item / Search / Register 라는 각각의 기능을 소개하는 의미 있는 콘텐츠로 구성되어 있었기에, 각 소개 블록에 div 대신 시멘틱 태그 article 사용

: 제가 아는 한, article 태그는, 해당 요소 부분만 분리하더라도 어색함이 없을 때 사용하는 걸로 알고 있어요. 블로그 글이나 뉴스 글과 같은 곳에 쓰이죠. 각각의 글이 해당 페이지에서 벗어나도 어색함이 없습니다. 하지만 Hot item / Search / Register 섹션은 어떤가요? 🤔

해당 서비스 페이지 내에서 주요 특징이나 기능을 설명하는 섹션에 article 태그가 적합할지는 고민을 해봐야겠네요. 🤓

실무에서 쓰는 이메일 형식 확인 방법이 궁금합니다!

: React와 Next.js를 쓴다고 가정했을 때, react-hook-form과 zod 조합을 가장 많이 사용하지 않나 싶어요. 물론, 프로젝트의 크기와 다양한 변수, 상황들을 고려해서 사용해야겠죠!

현재 상황과 프로젝트 크기에서는 매우 적합한 방식으로 구현했다고 생각해요.
정규 표현식을 사용하시다니..정말 대단합니다! 👍

미션 4 ... 자바스크립트를 처음부터 끝까지 작성해 본 것은 거의 처음이라 이 부분을 집중적으로 봐주시면 감사합니다!
더 효율적인 로직
리팩토링 가능한 부분 등...

: 저는 너무나 괜찮다고 생각합니다. 이벤트 위임부터 시작해서, 함수도 하나의 기능만 하도록 만들어주셨어요. 굳이 따지자면, 유효성 검사 부분과 이벤트 등록 부분을 모듈로 분리해보는 정도가 있을 것 같네요.


이번 미션도 고생하셨습니다 예지님! 👏
다음 미션 기다리고 있겠습니다~! 🤓

Comment on lines +17 to +87
@font-face {
font-family: "Pretendard";
src: url("https://cdn.jsdelivr.net/gh/projectnoonnu/[email protected]/Pretendard-Thin.woff2")
format("woff2");
font-weight: 100;
font-display: swap;
}

@font-face {
font-family: "Pretendard";
src: url("https://cdn.jsdelivr.net/gh/projectnoonnu/[email protected]/Pretendard-ExtraLight.woff2")
format("woff2");
font-weight: 200;
font-display: swap;
}

@font-face {
font-family: "Pretendard";
src: url("https://cdn.jsdelivr.net/gh/projectnoonnu/[email protected]/Pretendard-Light.woff2")
format("woff2");
font-weight: 300;
font-display: swap;
}

@font-face {
font-family: "Pretendard";
src: url("https://cdn.jsdelivr.net/gh/projectnoonnu/[email protected]/Pretendard-Regular.woff2")
format("woff2");
font-weight: 400;
font-display: swap;
}

@font-face {
font-family: "Pretendard";
src: url("https://cdn.jsdelivr.net/gh/projectnoonnu/[email protected]/Pretendard-Medium.woff2")
format("woff2");
font-weight: 500;
font-display: swap;
}

@font-face {
font-family: "Pretendard";
src: url("https://cdn.jsdelivr.net/gh/projectnoonnu/[email protected]/Pretendard-SemiBold.woff2")
format("woff2");
font-weight: 600;
font-display: swap;
}

@font-face {
font-family: "Pretendard";
src: url("https://cdn.jsdelivr.net/gh/projectnoonnu/[email protected]/Pretendard-Bold.woff2")
format("woff2");
font-weight: 700;
font-display: swap;
}

@font-face {
font-family: "Pretendard";
src: url("https://cdn.jsdelivr.net/gh/projectnoonnu/[email protected]/Pretendard-ExtraBold.woff2")
format("woff2");
font-weight: 800;
font-display: swap;
}

@font-face {
font-family: "Pretendard";
src: url("https://cdn.jsdelivr.net/gh/projectnoonnu/[email protected]/Pretendard-Black.woff2")
format("woff2");
font-weight: 900;
font-display: swap;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 방법으로 폰트를 불러와도 되지만, 프리텐다드는 좀 더 모던한 방법으로 폰트 최적화를 할 수 있도록 지원해요.

글꼴은 생각보다 파일 크기가 큰 편이에요. 제가 말씀드린 방법으로 적용하면, 파일 크기를 훨씬 많이 줄일 수 있어요. 아래 링크를 참고하여 적용해본 후, 개발자 도구의 네트워크 탭에서 리소스 크기를 비교해보세요! 🤓

Comment on lines +50 to +60
<picture>
<source
srcset="img/img_home_top_mobile.svg"
media="(max-width: 767px)"
/>
<source
srcset="img/img_home_top.svg"
media="(min-width: 768px)"
/>
<img src="img/img_home_top.svg" alt="" />
</picture>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오..좋은 시도네요 예지님! 이렇게 구현한 이유와 장점은 어떤 게 있을까요?
현재 구현에서도 장점을 가져갈 수 있을까요?

우선, SVG는 벡터 기반이라 크기를 조절해도 품질 손실이 없어요. 지금 상황에서 적절한 구현인지 한번 고민해보시면 좋을 것 같아요! 이 부분도 다음 미션에서 학습 포인트로 적어주시면 좋을 것 같습니다. 🙂

Comment on lines +37 to +71
function formCheckEvent(e) {
const id = e.target.id;
const value = e.target.value;

switch (id) {
case "email":
if (value === "") {
setError(formEmail, "이메일을 입력해주세요.");
} else if (!emailCheck.test(value)) {
setError(formEmail, "잘못된 이메일 형식입니다.");
} else {
setSuccess(formEmail);
}
break;

case "nickname":
if (value === "") {
setError(formNickname, "닉네임을 입력해주세요.");
} else {
setSuccess(formNickname);
}
break;

case "password":
if (value === "") {
setError(formPass, "비밀번호를 입력해주세요.");
} else if (value.length < 8) {
setError(formPass, "비밀번호를 8자 이상 입력해주세요.");
} else {
setSuccess(formPass);
}
break;
}
}
authForm.addEventListener("focusout", formCheckEvent);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switch 문 활용과 이벤트 위임까지..💯

여기서, 폼 안에 버튼의 존재와 키보드 포커스가 있다는 것도 생각해보면 좋을 것 같아요!
만약, id 값이 없다면 얼리 리턴을 통해, 아래 코드가 실행되지 않도록 해보는 건 어떨까요?

@anarose314
Copy link
Collaborator Author

안녕하세요!
좋은 말씀과 상세한 피드백 정말 감사합니다!🥹🥹🥹

시멘틱 태그는 항상 고민이 많았는데,
말씀 주신 내용 참고해서 article 사용에 대해 좀 더 고민해봐야겠어요...!!!

또한, 새로 피드백 주신 부분에 대해서는 이전과 같이 다음 미션 때 반영해보겠습니다!

바쁘신 와중에 코드 리뷰 해주셔서 감사합니다!!!
다음에도 잘 부탁 드립니다🙇🏻‍♀️✨

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants