본문 바로가기
Frontend2026년 8월 15일5분 읽기

@starting-style · allow-discrete — display:none 요소를 부드럽게 여닫기

YS
김영삼
조회 6
@starting-style · allow-discrete — display:none 요소를 부드럽게 여닫기

@starting-styletransition-behavior: allow-discretedisplay: none이던 요소가 화면에 나타나거나 사라질 때 부드럽게 트랜지션을 걸 수 있게 해주는 CSS 기능입니다. 예전엔 불가능했던 '진입 애니메이션'을 자바스크립트 없이 순수 CSS로 만들 수 있게 됐죠.

왜 이게 필요했냐면, display는 원래 트랜지션이 안 되는 속성이라 그렇습니다. 나도 예전엔 모달을 부드럽게 띄우려고 setTimeout으로 클래스를 순서대로 붙였다 뗐다 하는 지저분한 코드를 썼습니다. 이제 그럴 필요가 없습니다.

문제의 뿌리 — 두 가지 벽

요소를 부드럽게 나타나게 하려면 두 개의 벽을 넘어야 합니다.

  • 첫 번째 벽: display: noneblock은 이산(discrete) 변화라 중간값이 없습니다. 그냥 툭 나타납니다.
  • 두 번째 벽: 방금 만들어진(혹은 방금 보이게 된) 요소는 '시작 스타일'이 없어서, opacity 0에서 1로 갈 출발점을 브라우저가 모릅니다.

이 둘을 각각 allow-discrete@starting-style이 해결합니다.

allow-discrete — display도 전환에 태우기

transition-behavior: allow-discrete를 주면 displayoverlay 같은 이산 속성도 트랜지션 목록에 낄 수 있습니다. 나타날 땐 트랜지션 시작에 곧바로 display가 켜지고, 사라질 땐 애니메이션이 끝날 때까지 display가 유지됐다가 마지막에 꺼집니다. 덕분에 사라지는 모션도 끝까지 보입니다.

@starting-style — 출발점 정의

@starting-style 블록 안에 쓴 값이 '요소가 처음 보이기 시작하는 순간의 상태'가 됩니다. 아래를 보면 감이 옵니다.

dialog[open] {
  opacity: 1;
  transition: opacity .3s, display .3s allow-discrete;
}
/* 열리기 직전의 출발점 */
@starting-style {
  dialog[open] { opacity: 0; }
}
/* 닫힐 때(=열림 조건이 아닐 때)의 도착점 */
dialog:not([open]) {
  opacity: 0;
}

정리하면 세 지점을 각각 정의하는 겁니다. 출발(@starting-style) → 표시 상태([open]) → 종료(:not([open])). 축약형 transitionallow-discrete를 함께 적어야 display가 같이 굴러갑니다.

팝오버에도 그대로

Popover API로 만든 요소에도 똑같이 통합니다. 이때는 overlay 속성까지 전환에 넣어 최상위 레이어(top layer) 이탈 타이밍을 맞춥니다.

[popover]:popover-open { opacity: 1; }
@starting-style { [popover]:popover-open { opacity: 0; } }
[popover] {
  opacity: 0;
  transition: opacity .25s, display .25s allow-discrete,
              overlay .25s allow-discrete;
}

흔한 실수

증상원인
들어올 때만 안 되고 나갈 땐 됨@starting-style 누락
나갈 때 툭 사라짐display .3s allow-discrete 빠짐
아무 반응 없음축약형에 전환 속성 나열 누락

특히 첫 줄이 함정입니다. @starting-style이 없으면 브라우저는 '이미 그 상태였다'고 여겨 진입 애니메이션을 통째로 건너뜁니다.

자주 묻는 질문

지금 써도 되는 기능인가요?

네. 2024년경 주요 브라우저에 자리 잡아 2026년 현재 모던 브라우저에서 폭넓게 동작합니다. 미지원 환경에서도 그냥 애니메이션만 생략될 뿐 요소는 정상적으로 나타나므로 점진적 향상으로 안전하게 쓸 수 있습니다.

@keyframes로 하면 안 되나요?

됩니다. 하지만 @keyframes는 나타날 때 자동 재생만 쉽고, 사라질 때(요소 제거 타이밍)를 맞추려면 결국 JS가 필요합니다. @starting-style+allow-discrete는 여닫힘 양쪽을 CSS만으로 처리하는 게 강점입니다.

height: 0에서 auto로도 애니메이션 되나요?

이산 속성 처리와는 별개의 문제입니다. height: auto 전환은 interpolate-size: allow-keywords 또는 calc-size() 같은 별도 기능이 필요합니다. display 전환과 자주 함께 쓰이지만 서로 다른 스위치라는 점을 기억하세요.

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록