section-main
1. element style 반복사용
.btn {
width: 130px;
padding: 10px;
text-align: center;
border: 2px solid #333;
border-radius: 4px;
counter-reset: #333;
font-size: 16px;
font-weight: 700;
display: block;
transition: 0.4s;
}
.btn:hover {
background-color: #333;
color: white;
}
.btn.btn--reverse {
background-color: #333;
}
.btn.btn--reverse:hover {
background-color: transparent;
color: #333;
}
.btn.btn--brown {
color: #592b18;
border-color: #592b18;
}
.btn.btn--brown:hover {
color: #fff;
background-color: #592b18;
}
- btn 요소가 자주 반복되므로 전역 공간에 전체적인 큰 틀은 css스타일을 먼저 지정해 준 후, 때에 따라 각각의 요소를 약간씩 변형 + 재사용 한다.
display:block
으로 인라인요소에 btn 클래스를 지정할 경우를 대비하여 미리 값을 설정해줄 수 있다.
- 기존 버튼스타일을 받아와서 새로운 클래스를 활용, 우선순위가 더 높은 스타일로 덮어쓸 수 있다.
(처음에는 그냥 필요에따라서 그때 그때 각각 덮어쓰는 것으로만 생각했었는데 이렇게 하는게 가독성, 재사용성에 도움이 될 것 같다고 생각했다.🤔)
- 미리 버튼별 스타일을 지정해두고 필요에따라 가져와서 사용할 수 있다. (부트스트랩 원리)
2. position 속성으로 묶기
.visual .title {
position: absolute;
top: 88px;
left: -10px;
}
.visual .title .btn {
position: absolute;
top: 259px;
left: 173px;
}
- 현재 css스타일에서
.btn
은 position:absolute
로 상위 부모인 .title
에 묶여있는 상태이다.
- 즉 필요에 따라
.title
을 이동했을 때, 자식요소인 .btn
도 별다른 지정없이 함께 따라 배치하게 되므로 쉽게 컴포넌트화 가능하다.
3. 순차적 애니메이션
const fadeEls = document.querySelectorAll(".visual .fade-in");
fadeEls.forEach((fadeEl, index) => {
gsap.to(fadeEl, 1, {
delay: (index + 1) * 0.7,
opacity: 1,
});
});
- badge에서 라이브러리를 사용했던 것처럼 여기에서도 라이브러리를 이용할 수 있다.
- index 초기값은0이므로 첫번째 인덱스0은 0*0.7 = 0 이 되고, 이후 인덱스 부터는 forEach문에 의해서 차례대로 0.7, 1.4, 2.1 초의 딜레이가 적용된다.
- 작성하기 전, 순수 js로 이부분을 작성한다면 addEventListner와 load, 그리고 setTimeout 함수를 이용하면 어떨지 생각했다.🤔
section-notice
1. style 속성의 상호작용
.notice .notice-line {
position: relative;
}
.notice .notice-line .bg-left {
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
background-color: #333;
}
.notice .notice-line .bg-right {
position: absolute;
top: 0;
right: 0;
width: 50%;
height: 100%;
background-color: #f6f5ef;
}
.notice .notice-line .inner {
height: 200px;
}
- 자식 요소인 left와 right에 width와 height 값을 100%로 부여하고
.inner
에 높이값을 지정했다.
inner
의 부모요소인 .notice .notice-line
에 높이속성이 별도로 없으므로 기본값인 height:auto
(세로 너비가 최대한 줄어들려고 함) 로 동작하기때문에 inner
의 높이값에서 걸려서 최대 높이가 200이 된다.
2. 요소 슬라이드
- swiper 라이브러리를 활용해서 세로 슬라이드 작성하기 (demo)
✍️ 라이브러리를 이번 클론을 통해 처음 사용해 보았는데 사용하는 데 필요한 조건들을 맞게 작성해야 하지만 익숙해지면 빠르고 편하게 코드를 작성할 수 있게 될 것 같았다.😀
3. calc 함수
- calc(100px * 3 + 10px) 과 같이 계산에 필요한 식을 사용할 수 있다.
- calc(100% - 20px) 과 같이 꼭 픽셀이 아니어도 계산이 가능하다는 것은 처음 알게되었다.
4. absolute로 중앙 배치
.notice .promotion .swiper {
position: absolute;
top: 40px;
left: 50%;
margin-left: calc((819px * 3 + 20px) / -2);
width: calc(819px * 3 + 20px);
height: 553px;
background-color: orange;
text-align: center;
font-size: 200px;
}
- left 50% 로 이동, 요소의 크기 절반만큼 다시 제자리로(-) 이동 하는 개념은 자주 봤던 방법이다.
- 확대시 중앙 기준으로 확대되고, 안의 요소도 중앙 기준으로 잘 확대 되는 것을 볼 수 있다.
- calc()를 통해서 /2를 음수로 해준다.
5. 개발자도구 element 살펴보기
- 라이브러리를 이용해서 자동으로 제공하는 지정된 클래스 속성들이 보이는 것이라고 생각했다.
- 여기서 active는 현재 지정된 요소의 클래스 명에만 붙어있고 이 부분을 활용해서 다른 동일한 클래스네임의 요소와는 차별된 css style 속성을 줄 수 있다.
.notice .promotion .swiper-slide {
opacity: 0.5;
}
.notice .promotion .swiper-slide-active {
opacity: 1;
}
- 이러한 것은 swiper-pagination에서도 활용할 수 있다.
6. 토글버튼-요소가 흘러넘치지 않게하기
.notice .promotion {
position: relative;
height: 693px;
background-color: #f6f5ef;
transition: height 0.4s;
overflow: hidden;
}
.notice .promotion.hide {
height: 0;
}
- js를 통해서
let isHidePromotion = false;
변수로 토글동작이 가능한 btn을 만들고 classList.add or remove로 토글버튼 제어하기.
- 이후 css로 스타일을 지정하면 되는데 여기서
overflow: hidden;
를 꼭 넣어야만 요소가 높이사이즈에 맞게 흘러넘치지 않고 같이 위로 올라오게 된다.
✍️ 처음에는 그냥 오퍼시티나 디스플레이 속성을 사용하면 되지 않을까 했는데, 그렇게 하면 원하는 애니메이션 효과 등을 얻을 수 없을 것이다. height과 overflow로 해결하는 법을 알게 되었다.
section-rewards
1. 클래스 선택자
<section class="rewards">
<div class="bg-left"></div>
<div class="bg-right"></div>
<div class="inner">
<div class="btn-group">
<div class="btn btn--reverse sign-up">회원가입</div>
<div class="btn sign-in">로그인</div>
<div class="btn gift">e-Gift 선물하기</div>
</div>
</div>
</section>
- html에서 띄어쓰기가 포함된 여러 클래스명을 css에 가져올때 헷갈리는 부분에 대해서 다시 메모했다.
.rewards .btn-group .btn.sign-up {}
: rewards 안에 btn-group 안에 있는 btn이면서 sign-up인 요소를 가져온다.
- 중간 inner 같은 경우 inner는 단지 영역을 위한 컨테이너 이므로 생략하는 것도 하나의 방법이다.
2. width값 대신 flex-grow 사용하기
.rewards .btn-group .btn.gift {
flex-grow: 1;
margin-top: 10px;
}
- 부모요소의 너비만큼 채우기 위해 250px을 사용해도 같은 결과가 나오지만, 일일이 수정하는 것 대신 flex-grow 속성을 사용할 수 있다.
section-youtube
1. n:n 비율로 요소 사이즈 지정하기
<div class="container">
<div class="item"></div>
</div>
.container{
width:300px;
background-color: green;
}
.container .item{
width: 100%;
height:0;
padding-top: 50%
}
- 부모 컨테이너에
width
사이즈를 지정하고, 자식요소 item에 padding-top
으로 50%를 지정한다.
- 부모 요소의 width 를 기준으로 세로 패딩 높이값이 50%가 되기 때문에 2:1 비율로써 자식요소와 부모요소의 가로세로 비율이 설정된다.
- 유튜브와 같이 어떤 특정한 비율의 가로세로 사이즈가 필요할 때 사용될 수 있는데, 만약 16:9 비율로 지정하고 싶다면 100% : 56.25% = 16:9 이므로 padding-top: 56.25%를 넣어준다.
2. absolute 중앙배치
.youtube .youtube__area {
position: absolute;
left: 0;
right: 0;
margin: auto;
background-color: orange;
width: 1920px;
}
.youtube .youtube__area {
position: absolute;
left: 50%;
margin-left: calc(1920px / -2);
background-color: orange;
width: 1920px;
}
.youtube .youtube__area {
position: absolute;
left: 50%;
transform: translateX(-50%);
background-color: orange;
width: 1920px;
}
- 자주 사용할 방법이므로 한번 더 정리해보기
- 앞에서 사용한 absolute를 활용한 중앙배치 두 가지 방법과 translateX를 활용한 방법도 추가해 보았다. 어떤 방법이 어떤 상황에서 어떤 장점이 있는지는 차근차근 경험을 통해 알아가보자.✍️
.youtube .youtube__area {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: orange;
width: 1920px;
}
- calc로 계산을 해서 두거나 transform 속성으로 한번에 조절하거나 결과는 같았다. 둘다 내가 직접 일일이 수정할 필요가 없을 것 같아서 나는 가독성이 좋은 translate속성을 이용했다.🤔
3. youtube iframe api
- IFrame Player API를 통해 YouTube 동영상을 제어할 수 있다. api 활용법에 대해 설명된 글을 참고 한다.
- js로 필요한 코드를 작성한다.
- 플레이어 매개변수(playerVars)에서 더 많은 옵션을 확인할 수 있다.
4. 플로팅 요소 만들기
- html, css 설정을 마친 후 js에서 다시 라이브러리를 활용한다.
function floatingObj(selector) {
gsap.to(selector, 1, {
y: 20,
repeat: -1,
yoyo: true,
ease: Power1.easeInOut,
delay: 1,
});
}
floatingObj(".floating");
5. 랜덤함수 만들기
function random(min, max) {
return parseFloat((Math.random() * (max - min) + min).toFixed(2))
}
- random(1,6) 이면 숫자 1~6 사이에서 소수점 2자리까지 랜덤한 숫자를 반환한다.
function random(min, max) {
return parseFloat((Math.random() * (max - min) + min).toFixed(2));
}
function floatingObj(selector,delay,size) {
gsap.to(selector, random(1.5, 2.5), {
y: size,
repeat: -1,
yoyo: true,
ease: Power1.easeInOut,
delay: random(0, delay),
});
}
floatingObj(".floating1", 1, 15);
floatingObj(".floating2", .5, 15);
floatingObj(".floating3", 1.5, 20);