<section class="pick-your-favorite">
.pick-your-favorite {
background-image: url(../images/favorite_bg.jpg);
background-attachment: fixed;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
}
background-image
: url() 을 통해서 이미지를 가져오기background-attachment: fixed;
: 기본적으로 상하 스크롤 될때 요소에 배경으로 설정된 이미지가 같이 스크롤(기본값)이 되지 않고 뷰포트에 고정이 된다.background-position
: 배경의 위치는 section
정가운데 위치시키기background-size: cover;
: 배경의 이미지를 요소의 더 넓은 너비에 맞춰서 비율적으로 설정된다.background-repeat
: 배경이미지 반복 여부 설정하기.reserve-store .medal {
/* 가로사이즈가 최대한 늘어나려고 하기 때문에 사이즈를 기재해준다 */
width: 334px;
height: 334px;
/* 원근거리를 설정한다 */
perspective: 600px;
}
.reserve-store .medal .front,
.reserve-store .medal .back {
position: absolute;
width: 334px;
height: 334px;
/* 요소를 뒤집었을때 화면에서 보이지 않는다 */
backface-visibility: hidden;
/* transition은 이곳에 작성한다 */
transition: 1s;
}
.reserve-store .medal .front {
/* 명시적으로 0deg 작성을 해준다 */
transform: rotateY(0deg);
}
.reserve-store .medal .back {
/* 요소를 뒤집어준다 */
transform: rotateY(-180deg);
}
.reserve-store .medal:hover .front {
transform: rotateY(180deg);
}
.reserve-store .medal:hover .back {
transform: rotateY(0deg);
}
.reserve-store .medal .back .btn {
/* width는 btn에 이미 지정되어있으므로 생략가능하다 */
position: absolute;
top: 240px;
left: 0;
right: 0;
margin: auto;
}
transform: rotateY(0deg)
: 브라우저마다 지원이 안 될수도 있기 때문에 명시적으로 설정한다.transform: rotateY(-180deg)
: 요소를 뒤집는다.backface-visibility
: 뒷면이 어떻게 처리될 것인지 지정한다. hidden
은 안보이도록 하는 값이다.perspective
: 원근법을 이용해서 3차원의 효과를 시각적으로 확인할 수 있게된다..reserve-store .medal:hover .front
: hover는 .medal 에 붙인다. box-shadow: 2px 2px 8px 0 rgba(0 0 0 /50%);
box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.5);
// 섹션요소 중 scroll-spy 클래스명이 붙은 el들을 찾아서 spyEls에 할당
const spyEls = document.querySelectorAll("section.scroll-spy");
spyEls.forEach((spyEl) => {
new ScrollMagic
.Scene({
triggerElement: spyEl, // 보여짐 여부를 감시할 요소를 지정
triggerHook: .8,
})
.setClassToggle(spyEl, 'show')
.addTo(new ScrollMagic.Controller());
});
Scene()
메소드는 스크롤매직 이라는 js라이브러리를 통해서 특정한 요소를 감시하는 옵션을 지정해준다. (화면에 섹션이 보이는지 보이지 않는지 감시할때 필요한 여러가지 옵션들을 scene이라는 메소드에 추가하기)setClassToggle()
메소드를 붙여준다. html클래스 속성을 넣었다 뺏다 제어해주는 역할이다.addTo()
스크롤매직 이라는 js 라이브러리가 필요한 컨트롤러라는 개념의 내용을 추가하기 위해 해당 메소드를 사용해야 한다. (api문서에 작성이되어 있다.)triggerHook
: 내가 감시하고 있는 요소가 뷰포트에서 어느지점에 걸려야 감시되었다는 것을 판단할지 지정한다. 감시가 되었음이 판단되면, 뒤의 메소드를 부른다.setClassToggle
addTo(new ScrollMagic.Controller())
: 스크롤 매직에서 우리가 추가한 옵션들을 내부의 컨트롤러에 내용을 할당해서 실제로 동작가능하도록 만들어준다.✍️ 이처럼 js로 동작시키기 까다롭거나 시간이 오래걸리는 경우 js라이브러리를 통해서 원하는 동작을 간편하게 실행시킬 수 있다.
✍️ 애니메이션의 효과들은 css에서 작성을 하는 것이 좋지만, 너무 복잡하거나 구현하기 힘들 경우 js의 도움을 받아서 작성할 수 있으며, 마찬가지로 js라이브러리(Gsap과 같은) 도움을 받을 수 있다. 🙂
/* section 애니메이션 */
.back-to-position {
opacity: 0;
transition: 1s;
}
.back-to-position.to-right {
transform: translateX(-150px);
}
.back-to-position.to-left {
transform: translateX(150px);
}
.show .back-to-position {
opacity: 1;
transform: translateX(0);
}
opacity: 0;
으로 보이지 않고, translateX(-150px 혹은 150px)로 이미 이동되어져 있는 상태이다. 여기서 show의 후손 으로back-to-position 클래스명이 부여된 요소는 보여지면서 제자리로 이동된다. 이러한 속성으로 움직임 애니메이션을 설정한다..back-to-position.to-right
혹은 .back-to-position.to-left
을 설정한다.show
는 라이브러리에 의해 자동적으로 감지 되었을때 추가된다.div
태그의 'more' 로 감싼 이유는, 기본적으로 btn 전체에 부여된 css속성과 중복되는 것을 방지하기 위함이다.✍️ 즉 특정 버튼의 more태그에 transition 효과를 기존 btn 속성과 관계없이 추가적으로 부여하거나 수정하기 위해 사용할 수 있다. 처음엔 불필요한 태그를 굳이 복잡하게 사용할 이유가 있는지 궁금했는데 이렇게 따로 분리해서 필요에 맞게 사용할 수 있다는 것도 알았다.
.show .back-to-position.delay-0 {
/* 기본값, 바로실행된다.*/
transition-delay: 0s;
}
.show .back-to-position.delay-1 {
transition-delay: 0.3s;
}
©
: ©
<
: <
>
: >
footer .menu li a {
display: block;
padding: 15px;
font-size: 12px;
font-weight: 700;
color: #ccc;
}
display
속성을 block으로 지정한다.position-absolute
position-fixed
→ ::before
는 인라인 요소이다. 따라서 가로세로 값을 가지려면 display
를 block
으로 변경해야 한다.
→ position
속성이 absolute
나 fixed
가 사용되는 요소는 display
값이 자동으로 block
으로 바뀐다.
block 요소는 width
값과 margin: 0 auto
으로 중앙정렬이 가능하다.
❗️ img 요소는 display:block
+ margin:0 auto
이면, width 속성이 없어도 가운데 정렬이 가능하다.
→ 이유는 브라우저가 이미지를 출력하는 가로너비를 알고 있다고 가정하고 margin auto를 자동으로 계산하기 때문이다. 🤔
gsap.to(window, .7, {
scrollTo: 0
});
<form>
<input type="text" placeholder="아이디를 입력하세요." />
<input type="password" placeholder="비밀번호를 입력하세요." />
<input type="submit" value="로그인" />
<p>
* 비밀번호를 타 사이트와 같이 사용할 경우 도용 위험이 있으니, <br />
정기적으로 비밀번호를 변경하세요!
</p>
</form>
input
태그 : 사용자에게 데이터를 입력받는 역할을 한다.type='text'
를 통해 텍스트를 입력받는다.type='password'
를 통해 비밀번호를 입력받는다.type='submit'
를 통해 제출의 의사를 입력받는다. 제출하는 버튼의 이름은 value를 통해 설정할 수 있다..sign-in .signin__card [type="submit"] {
background-color: #006633;
color: #fff;
font-size: 20px;
cursor: pointer;
border: none;
}
[type="submit"]
: 타입이라는 속성이 submit인 요소를 선택한다..sign-in .signin__card .actions a {
flex-grow: 1;
flex-basis: 0;
text-align: center;
padding: 20px;
color: #555;
font-size: 14px;
border-right: 1px solid #ddd;
}
flex-grow: 1
: 요소의 증가 너비가 1 비율flex-basis: 0
: 요소 기본너비 0 (없는상태)✍️ 이 프로젝트를 통해서 이미 알고 있던 개념은 다시 정리함으로써 복습하고, 모르는 부분이나 헷갈렸던 개념들은 다시 정리 할 수 있어서 좋았다. 기초적인 위치설정 개념도 그 근본이나 기본값 등을 제대로 인지하고 있지 않으면 원하는 방향으로 출력되지 않을 수 있다는 것도 주의해야 겠다.🤔 처음 js 라이브러리를 사용해 본 프로젝트인데, 확실히 그 사용법만 숙지하면 앞으로 자주 쓰이게 될 것 같다. (그래도 순수js코드가 조금 더 재미있다.😂)
애니메이션 효과도 자유자재로 다룰 수 있게되면 훨씬 재미있게 코딩할 수 있을 것 같다.✨