[CSS] 요소를 숨겨뒀다가 버튼을 클릭하면 보여주기

초코침·2023년 4월 15일
1

CSS

목록 보기
8/8

아주 간단한 Q&A 사이트를 만드는 중에 질문하기 폼을 어디다 둬야할지 고민하다가, 질문하기 버튼을 누르면 버튼 하단에 바로 폼이 보이도록 만들어보고자 했다.

결과물 ⬇️

질문 폼 숨기기

내 프로젝트에서 질문 폼은 기본적으로 질문하기 버튼 아래, 질문 모아보기 리스트 위에 위치한다.

질문 폼이 (버튼을 누르기 전까지) 눈에 보이지도 않고, 공간을 차지하지 않게 하기 위해 3가지 속성을 적용했다.

.form__container {
	visibility: hidden;
	position: absolute;
	opacity: 0;
}

visibility: hidden

visibility 속성 값으로 hidden을 주면 질문 폼이 보이지 않게 된다.

단, 눈에 보이진 않지만 질문 폼의 자리는 그대로 차지하고 있는 상태다.

이때 display: none 속성을 주면 눈에 보이지도 않고 질문 폼 자리도 차지하지 않게끔 해 주지만, 사용하지 않았다. 사용하지 않은 이유는 마지막에!

position: absolute

position 속성 값으로 absolute를 사용하면 해당 요소가 부모로부터 벗어나 위치를 옮길 수 있게 된다.

현재 질문 폼의 html 계층 관계는 다음처럼 <main>의 자식 요소로 있는 상황인데,

<main> // 부모
	<section class="메인이미지와 질문하기 버튼이 있는 곳"></section> // 첫 번째 자식
	<section class="질문 폼"></section> // 두 번째 자식
	<section class="질문 모아보기"></section> // 세 번째 자식
</main>

absolute를 줌으로써 main을 벗어난 느낌 즉, main의 첫 번째 자식 요소 아래 위치하는 것이 아니라 main의 시작점에 위치하게 된다.

다른 요소 위에 겹쳐 놓음으로써 원래 차지하던 공간에서 벗어난 곳에 위치시킨 것이다.

opacity: 0

위 사진을 보면 두 요소가 겹쳐져 있기 때문에, 질문 폼을 투명하게 만들어 마치 숨겨진 것처럼 만들었다.

버튼 클릭 시, 질문 폼 보이기

버튼을 클릭하면 질문 폼의 위치가

의 첫 번째 자식 요소 아래 위치해야 하고 visibility를 변경하면 되므로,

  1. position을 원래대로 돌려주기 위해 static으로 변경하고
  2. 투명하지 않게 opacity를 1로 한 다음
  3. visibility는 visible로 만들면 된다.
/* 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: 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이 발생하지 않는다.

그럼 display에는 애니메이션을 줄 수 없는가?

줄 수 없는 줄 알고 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를 수정한 것과 동일하게 동작한다 👍

profile
블로그 이사중 🚚 (https://sungjihyun.vercel.app)

0개의 댓글