[ 멋쟁이 사자처럼 🦁 프론트엔드 스쿨 6기 | HTML/CSS 팀프로젝트 ]
🔗 배포 주소 : https://taing.netlify.app/
OTT 서비스 웹사이트를 반응형으로 구현합니다.
| 프로필 | 이름 | GitHub |
|---|---|---|
| 신승민(팀장) | https://github.com/M-Moong | |
| 고명현 | https://github.com/gobeeisfree | |
| 김다인 | https://github.com/kimInDa | |
| 신현주 | https://github.com/shju0317 |
- 아이스 브레이킹
- 기술 스택, 코딩 컨벤션, 접근성 체크리스트, 구현 페이지 범위 확정
- 개발 환경 셋팅
- 파트 배분
- 개인 파트 구현
- 개인 파트 함께 디버깅
- 모두의 작업물 merge & 디버깅
- 구현 페이지 추가 & 작업
- README 작성
- 과제 제출
| 구분 | 모바일(320px) | 태블릿(768px) | 데스크톱(1920px) |
|---|---|---|---|
| 메인 | ![]() |
![]() |
![]() |
| 로그인 | ![]() |
![]() |
![]() |
| 아이디 찾기 | ![]() |
![]() |
![]() |
| 비밀번호 찾기 | ![]() |
![]() |
![]() |
| 회원가입 | ![]() |
![]() |
![]() |
- 주민등록번호조의 CSS 프레임워크는 Tailwind를 사용한다.
커스텀 CSS 클래스명은 BEM 패턴을 사용한다. (예시)
.form__inputBEM패턴은 class에서 사용되는 방법론이므로
id나label,name에서는 카멜케이스를 사용한다.
tab 간격은 2칸으로 한다.
줄바꿈은 각자의 작업 방식에 따라 자유롭게 한다.
CSS 주석 방식은 한 줄이든 여러줄이든
/* */로 한다.따옴표는
“ “겹따옴표를 사용한다.
screens: {
mobile: {'min': '320px', 'max': '767px'},
tablet: {'min': '768px', 'max': '1199px'},
desktop: {'min': '1200px', 'max': '1920px'}
}- 모바일,태블릿, 데스크탑에 따른 반응형 스크린을 위하여 tailwind.config.js 파일에 각 스크린의 크기를 지정합니다.
<section>
<h2>섹션별 제목</h2>
<ul class="flex overflow-y-hidden scroll">
<li class="shrink-0 w-[14.8vw] min-w-[139px] max-w-[285px]"><a href="#"><img /></a></li>
.
.
</ul>
</section>- 섹션 내 콘텐츠를
ul또는ol을 사용하여 리스트화 합니다. ul또는ol에flex를 사용하여 콘텐츠 리스트를 가로 정렬 합니다.- 리스트 내부의 콘텐츠
li가 부모ul또는ol의 범위를 벗어날 경우, 부모요소에 가려지면서 스크롤이 발생하도록overflow-y-hidden속성을 부여합니다. - css 스타일링으로 화면상에서 스크롤바를 숨깁니다.
.scroll::-webkit-scrollbar { display: none; }
- 각 콘텐츠의 크기가 부모의
flex box크기가 아닌 뷰포트에 따라 크기가 변화하도록 각 콘텐츠li에shrink-0속성을 부여하고width값을 vw단위로 지정합니다.
<title>TAING</title>
<meta name="description" content="타잉 오리지널 콘텐츠, 방송, 영화, 해외시리즈까지! 재미를 플레이해보세요.">
<link rel="shortcut icon" href="./images/favicon.ico" type="image/x-icon" />title로 HTML 문서 전체의 제목을 나타냅니다.meta의content속성으로 검색 엔진에서 해당 사이트의 정보를 표시하고 검색 될 수 있도록 합니다.link의shortcut icon속성으로 파비콘을 설정하여 꾸며줍니다.
header의 마크업 순서는 키보드 사용자와 스크린리더 사용자의 접근성을 고려하여 로고 제목, 검색, 네비게이션의 순서로 합니다.- 시안의 순서로 바꾸어 주기 위해
header에flex를 지정해주고 2번ol의 order를 2로 지정합니다. - 1번 로고는 클릭 시 메인 페이지로 이동할 수 있어야 하므로
a의 background-image로 넣어주고aria-label로 대체 텍스트 "타잉"을 지정합니다. 페이지의 대제목이 될 수 있도록h1을 부모요소로 합니다.<h1> <a href="#" aria-label="타잉" class="bg-[url('/images/icon-logo.svg')] bg-no-repeat"></a> </h1>
- 2번 검색 아이콘은
button의 background-image로 넣어주고aria-label로 대체 텍스트 "검색"을 지정해 줍니다. - 2번 프로필 사진은 클릭 시 마이페이지로 이동할 수 있도록
a로 마크업 하고, background-image로 프로필 이미지를 넣어준 뒤aria-label로 대체 텍스트 "마이페이지"를 지정해 줍니다. - 3번 네비게이션은
mobile:hidden으로 모바일에서는 보이지 않게 합니다. - 3번 네비게이션을 스크린리더 사용자에게 메인메뉴 임을 알려주기 위하여
<h2>메인메뉴</h2>에sr-only속성을 사용합니다.
article태그 안 메인이 되는 이미지를figure태그안에 배치하고figcaption으로 설명을 적어 배치합니다.- 해당 이미지에 대한
자세히보기 button첫번째, 다음으로 슬라이드 기능으로 동작할이전, 다음 화살표 모양 button그리고 마지막으로는pagination 기능을 할 button순으로 마크업 합니다. 이전, 다음 화살표 모양 button은 해당 기능이 이미지의 좌·우의 각 세로 어디를 눌러도 동작할 수 있도록 height에 100%를 지정합니다.- 접근성
이전, 다음 화살표 모양 button에aria-label값으로 각각이전 슬라이드,다음 슬라이드를 지정합니다.pagination 기능을 할 button에aria-label값으로 각각n번째 슬라이드를 지정합니다.
h2로 섹션의 제목을 구성했습니다.ol>li로 각 이미지들의 리스트를 구현하였고,<a>로 figure를 감싸 링크 형식으로 작성하였습니다.<img>와<figcaption>을<figure>로 감싸 독립적으로 포스터에 제목을 나타냈습니다.- 횡 스크롤은
overflow-y-hidden을 주어 좌우 이동될수있게 표현하였습니다. (section별 횡스크롤)
h2로 섹션의 제목을 구성했습니다.ol>li로 각 이미지들의 리스트를 구현하였고,<a>로 figure를 감싸 링크 형식으로 작성하였습니다.- 포스터의 제목과 설명은
dl>(dt+dd)*2의 구조로dt는aria-label로 숨김처리를 하였고,dd가 무슨 역할인지 설명할수 있도록 작성하였습니다.
- 순위와 프로그램명을 a 태그 안에 배치해 링크 영역에 속할 수 있도록 합니다.
- 순위와 프로그램명을
dl 태그로 구성하고 화면에 보이지 않는 부분은dt 태그, 보이는 부분은dd 태그에 정의합니다.dt의 텍스트 노드에 빈 값을 주고 aria-label에 각각 순위, 프로그램명 이라는 값을 줍니다.<dl> <dt aria-label="순위"></dt> <dd>1</dd> <dt aria-label="프로그램명"></dt> <dd>황혼: 빛과 그림자</dd> </dl>
- 실시간 인기 프로그램 섹션과 동일한 구성으로 마크업
- 순위와 채널명, 프로그램명, 시청률을 a 태그 안에 배치해 링크 영역에 속할 수 있도록 합니다.
- 순위와 채널명, 프로그램명, 시청률을
dl 태그로 구성하고 화면에 보이지 않는 부분은dt 태그, 보이는 부분은dd 태그에 정의합니다.dt의 텍스트 노드에 빈 값을 주고 aria-label에 각각 순위, 프로그램명 이라는 값을 줍니다.<dl> <dt aria-label="순위"></dt> <dd>1</dd> <dt aria-label="채널명"></dt> <dd>JTBC</dd> <dt aria-label="프로그램명"></dt> <dd>JTBC 뉴스룸</dd> <dt aria-label="시청률"></dt> <dd>27.9%</dd> </dl>
<section>
<h2>섹션 제목</h2>
<ul class="flex gap-[10px] overflow-y-hidden scroll">
<li class="shrink-0 w-[18vw] min-w-[145px] max-w-[346px]">
<a href="#">
<img src="이미지 경로" alt="대체 텍스트"/>
</a>
</li>
.
.
</ul>
</section>section의 제목을h2로 마크업 합니다.- 콘텐츠 목록은 순서가 없는
ul과li로 마크업 합니다. - 각 콘텐츠는 클릭 시 해당 프로그램의 정보 페이지로 넘어가야하므로
img의 부모 요소로a를 마크업 합니다. ul에overflow-y-hidden속성을 이용하여 횡스크롤이 생기도록 합니다. (section별 횡스크롤)img의alt속성을 이용하여 스크린 리더 사용자에게 해당 이미지의 대체 텍스트를 줍니다.
<section class="mobile:pr-[8px] tablet:pr-[40px] desktop:pr-[70px] mobile:py-4 tablet:py-7 desktop:py-9 ">
<h2 class="sr-only">광고</h2>
<figure class="min-w-[304px] max-w-[1780px]">
<img src="/images/sports-1.jpg" />
<figcaption class="sr-only">타빙 스포츠 경기 생중계 UFC 월드복싱 슈퍼매치 분데스리가 AFC 챔피언스리그</figcaption>
</figure>
</section>- 해당
section의 제목인 "광고"를h2로 마크업하고sr-onyl(a11yHidden)속성으로 스크린 리더에 정보를 제공하면서 화면에서는 숨깁니다. - 광고 이미지는
figure를 부모 요소로 하여img로 마크업 합니다. img에 대한 대체 텍스트로figcaption을 마크업하고 화면에는 보이지 않도록sr-onyl(a11yHidden)속성을 부여합니다.
- 가로 구분선의 위의 요소들은
flexbox를 주어 좌우로 배치를 하였습니다. - 가로 구분선은 아래요소의
border-top을 주어 나타내었습니다. div>ol>li도flexbox를 주어 가로로 배치를 하였고, 밑줄있는 요소는a태그의underline을 주어 밑줄을 표현하였습니다.mail요소는a태그에mailto를 주어 바로 메일을 작성할수 있도록 하였습니다.- 아래의 아이콘은
a태그에image를 넣어 구현하였습니다.
-
로그인 페이지에는 서버로 전달되어야 하는 정보(아이디, 비밀번호 등)가 있기 때문에
form태그로 마크업합니다. -
아이디와 비밀번호
input에label을 지정하여 어떤 입력란인지에 대한 정보를 제공합니다.label에는sr-only클래스를 지정하여 스크린리더는 읽되 화면에는 보이지 않도록 합니다.<!-- 아이디 --> <div class="w-[38vw] min-w-[288px] max-w-[732px] h-[5vw] min-h-[46px] max-h-[96px]"> <label for="userId" class="sr-only">아이디</label> <input id="userId" name="userId" class=" form__input border p-4 outline-none rounded login__txt w-full h-full" type="text" placeholder="아이디" required /> </div>
-
border를 지정하여focus를 받고 있는 요소를 알 수 있도록 합니다./* focus되면 빨간색 border 적용 */ .form__input:focus{ border: 2px solid #ff153c; }
-
input에required속성을 주어 아이디와 비밀번호를 입력하지 않고 버튼을 누를 경우 메시지를 띄우도록 합니다.
-
background-image로 체크이미지를 표현할 경우 해당 이미지에는 탭할 수 없습니다. 키보드로도 접근할 수 있도록input요소와background-image의 크기와 위치를 조정합니다.

<!-- 자동 로그인 --> <div class="flex relative mt-4 mb-10"> <input class="auto-login appearance-none absolute top-1/2 -translate-y-1/2 w-[26px] h-[26px] checked:bg-checkbox-checked" type="checkbox" id="autoLogin" name="autoLogin" /> <label for="autoLogin" class="pl-9 bg-checkbox-default bg-no-repeat bg-left text-lg">자동 로그인</label> </div>
-
border-right를 지정하여아이디 찾기와비밀번호 찾기사이의 구분선을 표현합니다.
-
input을type="email"로 지정하여 이메일 형식으로 입력하지 않는 경우 메시지를 보여줍니다. -
before와after가상요소를 사용하여 구분선을 표현합니다. 구분선이 가운데에 위치하도록my-auto를 지정합니다.<!-- 구분선 --> <div class="flex w-[38vw] min-w-[288px] max-w-[732px] my-24 text-base text-gray-700 align-middle before:content-[''] before:flex-grow before:h-[1px] before:bg-gray-700 before:my-auto before:mr-4 after:content-[''] after:flex-grow after:h-[1px] after:bg-gray-700 after:my-auto after:ml-4">또는</div>
-
form 태그안에 전체요소를 감싸는fieldset으로 영역을 지정합니다. -
legend는 화면에 표시되지 않기 위해sr-only class를 추가합니다. -
div으로 스타일링 할 영역을 감싸줍니다. -
p 태그에는 비밀번호 찾기에 대한 텍스트를 작성합니다. -
sr-only 속성 추가로 화면에 보이지 않는label 태그와, placeholder에아이디를 포함한input 태그로 화면과 같이 구현합니다. -
<form> <fieldset> <div> <p></p> <label></label> <input/> <button></button> </div> </fieldset> </form>
form태그에flexbox를 요소를 추가해 item들이 세로정렬을 할수 있게 구현하였습니다.Legend와p태그를 이용하여 제목과 설명을 배치하였습니다.- 아이디와 비밀번호 박스의 구성은
div>label+input+div로 구성하여 배치하였습니다. - 약관사항의 요소들은
flexbox의column으로 배치하였습니다. 각 아이템들은 text는label로 구성하였고,checkbox이미지는input으로 구성했습니다. input의 타입은checkbox로 설정하였고,checked시 이미지를 교체하여 체크표시가 되게끔 구현했습니다.
구현한 페이지들에 문법 검사를 시행한 결과 에러가 없음을 확인합니다.
각 모던 브라우저 Chrome, Firefox, Safari, Edge 환경에 맞춰 구현됨을 확인합니다.
![]() |
![]() |
![]() |
![]() |
Core Web Vitals를 사용하여 웹사이트의 성능 최적화를 검사합니다.







































