아주 간단한 Q&A 사이트를 만드는 중에 질문하기 폼을 어디다 둬야할지 고민하다가, 질문하기 버튼을 누르면 버튼 하단에 바로 폼이 보이도록 만들어보고자 했다.
결과물 ⬇️
내 프로젝트에서 질문 폼은 기본적으로 질문하기
버튼 아래, 질문 모아보기
리스트 위에 위치한다.
질문 폼이 (버튼을 누르기 전까지) 눈에 보이지도 않고, 공간을 차지하지 않게 하기 위해 3가지 속성을 적용했다.
.form__container {
visibility: hidden;
position: absolute;
opacity: 0;
}
visibility
속성 값으로 hidden
을 주면 질문 폼이 보이지 않게 된다.
단, 눈에 보이진 않지만 질문 폼의 자리는 그대로 차지하고 있는 상태다.
이때 display: none
속성을 주면 눈에 보이지도 않고 질문 폼 자리도 차지하지 않게끔 해 주지만, 사용하지 않았다. 사용하지 않은 이유는 마지막에!
position
속성 값으로 absolute
를 사용하면 해당 요소가 부모로부터 벗어나 위치를 옮길 수 있게 된다.
현재 질문 폼의 html 계층 관계는 다음처럼 <main>
의 자식 요소로 있는 상황인데,
<main> // 부모
<section class="메인이미지와 질문하기 버튼이 있는 곳"></section> // 첫 번째 자식
<section class="질문 폼"></section> // 두 번째 자식
<section class="질문 모아보기"></section> // 세 번째 자식
</main>
absolute
를 줌으로써 main을 벗어난 느낌 즉, main의 첫 번째 자식 요소 아래 위치하는 것이 아니라 main의 시작점에 위치하게 된다.
다른 요소 위에 겹쳐 놓음으로써 원래 차지하던 공간에서 벗어난 곳에 위치시킨 것이다.
위 사진을 보면 두 요소가 겹쳐져 있기 때문에, 질문 폼을 투명하게 만들어 마치 숨겨진 것처럼 만들었다.
버튼을 클릭하면 질문 폼의 위치가
의 첫 번째 자식 요소 아래 위치해야 하고 visibility를 변경하면 되므로,/* show */
.form__container.show {
position: static
opacity: 1;
visibility: visible;
}
show 클래스를 만들어 질문하기 버튼에 클릭 이벤트 발생 시 show 클래스를 토글하도록 했다.
위에까지 작성하고 질문하기 버튼을 누르면 질문 폼이 딱!! 등장하게 되는데,
크게 나쁘진 않지만, 좀 더 부드럽게 질문 폼을 나타내기 위해 transition
을 줬다.
/* show */
.form__container.show {
position: static
opacity: 1;
visibility: visible;
transition: visibility 0s, opacity 0.5s ease;
}
그럼 부드럽게 뜬다!
실은 display: none
속성을 주고, 클릭 시 display: block
으로 바꿔주면 간단하게 구현할 수 있다.
/* 질문 폼 */
.form__container {
display: none;
opacity: 0;
}
하지만 질문 폼을 부드럽게 띄우는 transition
이 적용되지 않는 문제가 있었다.
/* show */
.form__container.show {
display: block;
opacity: 1;
transition: display 0s, opacity 0.5s ease;
}
왜냐하면 display
속성은 transition-property
값으로 사용할 수 없는 속성이기 때문이다.
transition
은 이전 상태에서 이후 상태로 변화할 때 애니메이션을 적용하는 것인데, display: none
을 주면 해당 DOM은 아예 생성되지 않기 때문에 비교할 이전 상태가 없어 transition
이 발생하지 않는다.
줄 수 없는 줄 알고 visibility
를 바꾸는 식으로 작성했지만,
display
를 사용하는 경우 keyframes
로 애니메이션을 적용할 수 있다.
나는 display
속성이 none
에서 block
으로 바뀔 때, opacity
가 천천히 변경되는 애니메이션을 원했기 때문에 다음처럼 formopen 애니메이션
을 만들었다.
@keyframes formopen {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
만든 애니메이션을 animation
속성 값으로 주고, 애니메이션이 0.5초 동안 발생하도록 animation-duration
속성 값을 설정했다.
이때 animation-timing-function
은 기본값인 ease
로 적용된다.
/* 질문 폼 */
.form__container {
display: none;
opacity: 0;
}
/* show */
.form__container.show {
display: block;
opacity: 1;
animation: formopen;
animation-duration: 0.5s;
}
그럼 visibility를 수정한 것과 동일하게 동작한다 👍