CSS 트랜지션을 상태·접근성·실행 시점에 연결하기

저장 버튼은 요청 시작, 성공과 실패를 서로 다른 상태로 표시해야 합니다. CSS 트랜지션은 이 상태 변화를 표현하지만 저장 결과를 판정하지는 않습니다. 성공 표시를 실제 저장 결과와 연결해야 합니다.
인터페이스의 트랜지션은 메뉴가 열리는 위치, 저장이 끝난 시점, 선택한 탭의 이동처럼 상태 변화를 보여줍니다. transitions.dev는 이러한 CSS 패턴의 예제를 제공하며 코딩 에이전트가 참조할 스킬 형태로도 소개됐습니다. 이 글에서는 직접 작성한 저장 버튼 예시로 상태, 실행 시점과 움직임 감소 처리를 설명합니다.
동작에 맞는 상태와 전환
드롭다운 메뉴라면 닫힘과 열림이 기본 상태입니다. 메뉴를 여는 버튼, 바깥 영역 클릭, 키보드 조작에 따른 상태 변경도 필요합니다. CSS 효과는 상태 변경을 표현하며 메뉴의 기능 전체를 대신하지 않습니다.
모달에서는 열기와 닫기뿐 아니라 초점 이동과 복귀, 배경 조작 제한도 확인합니다. 닫는 애니메이션이 끝나기 전에 요소를 제거하면 전환이 보이지 않을 수 있습니다. 반대로 보이지 않는 요소가 계속 클릭을 받으면 동작에 문제가 생깁니다.
성공 표시와 오류 표시도 실제 결과에 연결해야 합니다. 요청을 시작하자마자 성공 애니메이션을 실행하면 저장 실패가 발생했을 때 사용자가 상태를 잘못 이해할 수 있습니다. 실제 성공 응답을 받은 뒤 표시하는 등 실행 시점을 정의합니다.

직접 그린 저장 버튼의 상태 예시입니다. 요청 시작은 성공이 아니며, 움직임을 줄여도 상태 글자는 남도록 표시했습니다.
실제 저장 결과에 연결할 속성
transition: all을 사용하면 의도하지 않은 속성까지 움직일 수 있습니다. 색상만 전환하려는 버튼에서 크기나 위치도 바뀐다면 클릭 위치와 화면 배치가 달라질 수 있습니다. 전환할 속성을 명시하면 영향을 추적하기 쉽습니다.
.action {
transition: background-color 160ms ease, opacity 160ms ease;
}
.action[data-state="saving"] {
opacity: 0.65;
}
.action[data-state="success"] {
background-color: #17694f;
}
.action[data-state="error"] {
background-color: #9d2929;
}
직접 작성한 저장 버튼의 CSS 예시입니다. data-state 값이 바뀌면 브라우저가 불투명도나 배경색을 전환합니다. 시간과 색상은 예시이며 실제 화면의 역할에 맞게 정해야 합니다. 다음 함수에서는 비동기 저장 함수 save를 전달받는다고 가정합니다.
async function handleSave(button, save) {
button.disabled = true;
button.dataset.state = "saving";
try {
await save();
button.dataset.state = "success";
} catch {
button.dataset.state = "error";
} finally {
button.disabled = false;
}
}
예시에서 save는 저장 성공 시 이행되고 실패 시 거부되는 Promise를 반환해야 합니다. fetch를 사용한다면 HTTP 오류도 직접 확인해 실패로 처리해야 합니다. 예시 함수는 이 계약에 따라 save가 완료된 뒤에만 성공 상태를 설정합니다. 개발자는 실제 화면에 상태별 글자나 아이콘과 오류 설명도 연결해야 합니다. 이 함수는 저장 서버나 상태 안내를 구현한 완성 코드가 아닙니다.
크기나 위치를 움직일 때는 성능도 관찰합니다. 특정 CSS 속성을 선택했다는 사실만으로 성능 개선을 확정할 수 없습니다. 실제 페이지에서 프레임 지연이나 레이아웃 변화를 확인해야 합니다.
움직임 없이 전달하는 상태
사용자는 운영체제에서 움직임 감소를 선택할 수 있습니다. 웹에서는 prefers-reduced-motion 조건을 사용해 이를 반영할 수 있습니다. 예제를 복사할 때 해당 처리가 있다면 보존하고 실제 적용 결과를 확인합니다.
@media (prefers-reduced-motion: reduce) {
.action {
transition: none;
}
}
움직임을 제거해도 성공, 오류, 선택 상태를 알아볼 수 있어야 합니다. 글자, 아이콘, 상태 설명을 함께 사용합니다. 오류를 흔들림만으로 표시하면 움직임을 줄인 사용자는 이유를 알기 어렵습니다.
프레임워크의 상태와 CSS 연결
프레임워크에 예제를 가져올 때는 CSS 클래스와 상태 속성을 연결합니다. 위 예시라면 data-state가 저장 시작, 성공, 실패 시점에 바뀌는지를 먼저 검사합니다. transitions.dev에서 고른 예제도 필요한 스크립트와 정리 시점을 함께 읽습니다.
저장 실패에서는 성공 색상이 나타나지 않는지, 빠른 반복 클릭에서는 저장 요청이 중복되지 않는지 확인합니다. 메뉴 전환 중 다시 열거나 닫았을 때도 최종 상태가 맞아야 합니다. 타이머와 이벤트를 사용했다면 요소가 제거된 뒤 불필요한 처리가 남지 않는지도 살펴봅니다. 움직임 감소 설정에서도 글자와 상태 설명으로 결과를 알 수 있어야 합니다.
저장 성공과 실패를 각각 발생시켜 상태 표시가 실제 결과와 일치하는지 확인합니다. 움직임을 줄인 환경에서도 진행 상태와 오류 설명이 남는지를 함께 검사합니다.