fastcampus 사이트의 '한번에 끝내는 프론트엔드 개발 강의' 를 수강하며 공부 목적으로 작성하는 글입니다.
클론 코딩 완성형태
강의의 예제를 따라해보며 스타벅스 클론코딩을 해보았습니다. 한번에 많은 기능을 넣다보니 정리가 필요할 것 같아 파트별로 하나하나 요점들을 적어보려고 합니다.
순서
1. 헤더로고
2. 드롭 다운 메뉴
3. BEM
4. 전역 배지
● 헤더 로고
▷ 헤더로고 좌측상단에 배치하기
<header>
<div class="inner">
<a href="/" class="logo">
<img src="./images/logo.png" alt="logo" />
</a>
</header>
헤더 안에 inner 클래스를 따로 설정해 두어 영역을 나눠 줍니다. 그리고 CSS를 통해 헤더와 inner의 부분을 색깔로 구분해주면 보기 쉽습니다. inner의 스타일은 가로. 세로 길이를 설정하고 margin : 0 auto;의 값을 통해 가운데 정렬을 할 수 있습니다.(auto는 컴퓨터가 뷰 포트에 맞게 가운데 위치할 수 있도록 자동으로 가운데 정렬을 해주는 기능입니다.)
파란색은 헤더의 영역이고 주황색은 inner의 영역입니다.
로고의 이미지를 세로의 중간에 위치하도록 하기 위해서는 CSS를 통해 몇 가지 설정해야 할 것이 있습니다.
이미지는 inline 속성을 가지는데 이를 display: block; 으로 변환을 시켜줘야 합니다. inline의 속성은 글자면 글자 칸 수 만큼, 이미지이면 이미지 크기만큼을 영역으로 할당하고 늘이거나 줄일 수 없습니다. 따라서 block 값을 주어 margin 값을 넣을 수 있도록 해줍니다. 그리고 로고의 부모요소인 inner position은 relative로 로고의 position은 absolute의 값을 주고, top: 0; bottom: 0; margin: auto 0 ; 값을 주면 가운데 정렬을 시킬 수 있습니다.
header part1
...
codepen.io
코드펜에 업로드 해놓았으니 이해가 되지 않는다면 확인해보세용..
▷ 헤더 서브메뉴 구성하기
<div class="sub-menu">
<ul class="menu">
<li>
<a href="javascript:void(0)">Sign In</a>
</li>
<li>
<a href="javascript:void(0)">My Starbucks</a>
</li>
<li>
<a href="javascript:void(0)">Customer Service & Ideas</a>
</li>
<li>
<a href="javascript:void(0)">Find a Store</a>
</li>
</ul>
<div class="search">
<input type="text" />
<div class="material-icons">search</div>
</div>
</div>
그림과 같은 메뉴를 만들기 위해서는 여러개의 클래스로 구분지어 활용해야 합니다. 각각의 메뉴부터 search 바까지 sub-menu 하나, 각각의 메뉴 하나, 그리고 search 바까지 세개로 구성될 수 있겠네요.
우선 메뉴들을 한 줄로 만들기 위해 ul.menu 태그를 가진 CSS에다 display는 flex로 설정해줍니다.
메뉴 사이 사이 12px의 작은 선은 CSS 선택자 중 ::before라는 가상 선택자를 통해 만들 수 있습니다. ::before 가상선택자를 사용하며 꼭 추가해야하는 속성은 content 속성이었는데요. 이 속성이 CSS에 빠져 있으면 아무런 변화가 적용되지 않으니 꼭 추가해주세요. 그리고 가상선택자는 자동적으로 인라인 속성을 가지고 있습니다. 그러므로 블럭 속성으로 변경하기 위해서는 display: block으로 속성을 변경해주거나, position의 값을 fixed나 absolute로 주어 block 속성을 갖도록 해주어야합니다.
header part2
...
codepen.io
▷ 헤더 서치바 구현하기
확인해야 할 점
1. 아이콘 클릭시 화면이 늘어남
2. 클릭하면 아이콘은 없어지고 placeholder를 통해 '통합검색' 이라는 단어 출력
이 두가지를 유념하며 스타일을 적용해야합니다. 하지만 이 부분은 CSS만 사용해서 꾸미기에는 어려움이 있어 JS를 사용하여 구현하여야 합니다.
<div class="search">
<input type="text" />
<div class="material-icons">search</div>
</div>
확인해야할 점 1번에 강조를 준 이유는 CSS 스타일만 적용할 시에 input 박스만 누를 때 변화가 생기고, 아이콘을 누르면 아무런 반응이 없습니다. 두 개의 클래스가 다르기 때문에 발생하는 것인데 이는 JS를 통해서 추가적으로 다뤄야합니다.
JS 파트를 살펴보도록 할게요.
------------------------------------- 아이콘 클릭 시 화면 늘어남 ------------------------------------------------------
const searchEl = document.querySelector('.search'); //.search 클래스를 가진 태그 검색
const searchInputEl = searchEl.querySelector('input'); // 위에서 찾은 태그 내에서 input 요소 검색
searchEl.addEventListener('click', function () { //행동추가하기. '클릭'시에 함수 실행
searchInputEl.focus(); //input 요소를 focus 하겠다. 따라서 input 요소 하위에 있는 아이콘을 클릭해도 적용
});
-------------------------------------아이콘 사라짐, placeholder 설정--------------------------------------------------
searchInputEl.addEventListener('focus', function () { //input 요소가 focus 상태이면
searchEl.classList.add('focused'); // 클래스 명에 'focused'를 추가
searchInputEl.setAttribute('placeholder', '통합검색'); // 속성 추가
});
// 아이콘이 사라지는 효과는 CSS header .sub-menu .search.focused .material-iconst 선택자에서 별도로 지정할 것
searchInputEl.addEventListener('blur', function () { //focused의 반대 의미는 'blur'
searchEl.classList.remove('focused'); //포커스가 해제되면 클래스명에 'focused' 제거
searchInputEl.setAttribute('placeholder', ''); //placeholder에는 내용 없음으로 변경
});
header part3
...
codepen.io
▷ 헤더 고정하기
헤더 영역은 휠을 내리든 올리든 항상 상단에 위치해야합니다. 따라서 헤더의 CSS를 설정해줘야합니다.
그러기 위해서는 position의 값을 fixed로 변경해야하는데요. 여기서 중요한 점이 하나 있습니다.
position이 relative 일 때 width의 값이 auto이면 가로 너비는 최대한 넓어지려는 성격을 가지지만, position이 fixed나 absolute이면 최소한으로 줄어들려는 속성을 가지고 있습니다. 그래서 width의 값을 auto 대신 100%로 변경하여 최대 너비를 가질 수 있도록 해야합니다.
● 드롭다운 메뉴
▷ 메뉴
<ul class="main-menu">
<li class="item">
<div class="item__name">COFFEE</div>
<div class="item__contents">
<div class="contents__menu"></div>
<div class="contents__texture"></div>
</div>
</li>
</ul>
메뉴의 구성은 ul 태그의 main-menu 클래스 li 태그의 item클래스가 있고 안에 메뉴 이름을 담는 item__name 클래스와 드롭다운 메뉴부분에 해당하는 item__contents 클래스로 구성되어 있습니다.
메뉴를 만들며 주의해야할 점은
- 메뉴의 hover 선택자의 영역을 지정할 때 item__name 클래스가 아닌 부모 클래스의 item클래스에 선택자를 두어 마우스가 드롭다운 메뉴에서 이동하더라도 작동되도록 할 것
- z-index를 통해 드롭다운 메뉴가 전역배지보다 앞에 뜨도록 설정할 것
- 드롭다운 메뉴는 페이지의 위치에 상관없이 항상 메뉴 아래 위치에 고정적으로 뜰 수 있도록 position값을 fixed로 설정할 것
입니다.
▷ 드롭다운메뉴
위의 사진처럼 드롭 다운메뉴를 고정시키기 위해서 CSS로 설정해주어야합니다.
header .main-menu .item .item__contents{
width: 100%;
position: fixed; /*뷰포트를 기준으로 배치하겠다.*/
left: 0;
display: none
}
header .main-menu .item:hover .item__contents{
display: block;
}
display를 none으로 설정해줌으로써 평소에는 뜨지 않다가 마우스가 메뉴를 가리킬 때 block으로 설정하여 뜨도록 하면 드롭다운 메뉴를 만들 수 있습니다.
그 외에는 위 사진처럼 구조를 만든다면 쉽게 할 수 있습니다.
● BEM(HTML 클래스 속성의 작명법)
→ Block Element Modifier
→ 요소__일부분 : Underscore(Lodash) 기호로 요소의 일부분을 표시한다는 의미
→ 요소--상태 : Hyphen(Dash) 기호로 요소의 상태를 표시한다는 의미
<div class="container">
<div class="name"></div>
<div class="item">
<div class="name"></div>
</div>
</div>
요소__일부분 에 대해 위를 예시로 들겠습니다.
CSS로 처리할 때 보통 .container .name으로 선택자를 입력하는 경우가 있습니다. 하지만 이는 container 자식의 name과 item 자식의 name을 모두 가리키게 됩니다. 따라서 이러한 문제를 처리하기 쉽도록 요소__일부분 의 형태로 고쳐서 사용합니다.
위의 예시를 변경한다면
<div class="container">
<div class="container__name"></div>
<div class="item">
<div class="item__name"></div>
</div>
</div>
이 되는 거죠.
<div class="btn gold"></div>
<div class="btn white"></div>
<div class="btn brown"></div>
요소--상태 의 경우를 예시를 들겠습니다.
버튼의 클래스명과 별도의 클래스명이 하나씩 더 들어있네요. 하지만 이들이 무엇을 의미하는지 명확하지 않습니다. 따라서 이 둘의 관계가 연결관계가 있다면 btn--을 넣어
<div class="btn btn--gold"></div>
<div class="btn btn--white"></div>
<div class="btn btn--brown"></div>
나타내어 준다면 의미전달을 확실히 할 수 있습니다.
● 전역배지
전역배지를 만들면서 생각해야하는 부분은 항상 상단에 위치하지만 스크롤을 내리면 서서히 사라지도록 동작시켜야 하는 부분입니다. 이 부분은 JS를 통해서 동작시킬 수 있는데 lodash.js 라이브러리를 사용한다면 쉽게 동작시킬 수 있습니다.
lodash.js - Libraries - cdnjs - The #1 free and open source CDN built to make life easier for developers
A utility library delivering consistency, customization, performance, & extras. - Simple. Fast. Reliable. Content delivery at its finest. cdnjs is a free and open-source CDN service trusted by over 12.5% of all websites, serving over 200 billion requests e
cdnjs.com
위의 사이트에서 min.js 를 copy해 index.html에 붙여주세요.
lodash 라이브러리에서 제가 사용할 함수는 바로 _.throttle()이라는 함수입니다. 이 안의 매개변수는 함수, 시간이 들어가게 됩니다. 이 함수는 정해진 시간마다 함수가 동작하라는 의미를 가지고 있습니다. 즉, 이 함수를 쓰지 않는다면 계속해서 함수가 동작하여 느려지는 현상이 있겠지만, _.throttle()함수를 사용하면 특정시간마다 함수가 동작해 필요하지 않은 함수의 동작을 줄일 수 있게 됩니다.
다음 단계는 전역배지가 서서히 사라지도록 또 다른 JS라이브러리를 사용해야하는데요. 해당 함수는 gsap이라는 JS라이브러리 안에 있습니다.
gsap - Libraries - cdnjs - The #1 free and open source CDN built to make life easier for developers
GSAP is a JavaScript library for building high-performance animations that work in **every** major browser. Animate CSS, SVG, canvas, React, Vue, WebGL, colors, strings, motion paths, generic objects...anything JavaScript can touch! No other library delive
cdnjs.com
마찬가지로 min.js 를 copy하여 index.html에 붙여 사용할 수 있습니다.
여기서 사용하는 함수는 gsap.to()라는 함수입니다. 매개변수로는 요소, 지속시간, 옵션(객체 데이터 사용)이 들어가는데 애니메이션을 처리할 요소와 지속시간, 그리고 애니메이션을 어떻게 처리해야할지에 대한 옵션을 입력해주면 됩니다.
전역배지 JS 처리 내용입니다.
const badgeEl = document.querySelector('header .badges'); //헤더에 badges 클래스 찾기
window.addEventListener('scroll', _.throttle(function () {
// 화면이 scroll 될 때마다 throttle을 걸어 해당 함수 실행
console.log(window.scrollY); //스크롤의 위치를 수치로 나타내기
if (window.scrollY > 500){
//배지 숨기기
gsap.to(badgeEl, .6, { //gsap.to(요소, 지속시간, 옵션);
opacity: 0,
display: 'none'
});
}else {
//배지 보이기
gsap.to(badgeEl, .6, {
opacity: 1,
display: 'block'
});
}
}, 300));
// _.throttle(함수, 시간)
정리
강의를 들어본 후 한번 더 수강하며 복습을 하고 정리를 해보았습니다. 강의 내용을 무작정 따라하기만 해서는 익숙해지지 않더군요. 강의를 두번 들으며 스스로 만들어보고 복습해보니 그나마 정리가 되는 것 같습니다.
공부하며 느낀점을 정리해보자면
1. 웹페이지를 무작정 만들기보다는 파트별로 세세히 나누어 클래스명을 지정하는 것이 바람직합니다.
2. html을 다 만들고 스타일을 수정하는 것보다 동시에 작업하는 것이 훨씬 수월합니다.
3. CSS를 작업할 때는 HTML에서 클래스를 생성할 때 CSS에서도 생성해주어 적용시키기 편하도록 하는 것이 좋습니다.
'Frontend' 카테고리의 다른 글
16-3 스타벅스 클론 코딩하기 - Part3 Youtube 영상 삽입 (0) | 2021.08.04 |
---|---|
16-2 스타벅스 클론 코딩하기 - Part2 애니메이션 효과와 슬라이드 (0) | 2021.08.04 |
15. HTML 오픈 그래프란 무엇인가 (0) | 2021.08.02 |
14. 웹 개발에 필요한 구글 무료 웹 폰트 사용하기 (0) | 2021.08.02 |
13. 웹 개발에 필요한 구글 무료 웹 아이콘 라이브러리 사용하기 - Material icons (0) | 2021.08.02 |