cubic-bezier 뜻: CSS 이징 함수 숫자 4개의 원리

CSS에서 transition-timing-function에 ease나 ease-in-out 같은 이름을 넣어봤다면, cubic-bezier(0.42, 0, 0.58, 1) 같은 숫자 네 개짜리 표기도 한 번쯤 본 적 있을 겁니다. 이 네 개의 숫자가 정확히 무엇을 뜻하는지 모른 채 어디선가 복사해서 붙여넣기만 하는 경우가 많습니다.
사실 ease·linear·ease-in-out은 전부 같은 수학적 곡선의 서로 다른 값일 뿐입니다. 이 곡선이 무엇을 나타내고, 그중에서도 linear만 유독 뻣뻣하게 느껴지는 이유가 무엇인지 원리부터 짚어보겠습니다.
요약 ① cubic-bezier(x1, y1, x2, y2)의 네 숫자는 시작점(0,0)과 끝점(1,1)을 잇는 3차 베지어 곡선의 두 중간 제어점 좌표입니다. ② x축은 "시간이 얼마나 지났는가", y축은 "애니메이션이 얼마나 진행됐는가"를 뜻하며, 이 곡선의 기울기가 곧 순간 속도입니다. ③ ease·linear·ease-in-out 같은 이름은 전부 이 네 숫자 조합에 붙은 프리셋 이름일 뿐, 별도의 계산 방식이 따로 있는 게 아닙니다.
cubic-bezier(x1, y1, x2, y2) 네 숫자가 가리키는 것
cubic-bezier() 함수 안에 들어가는 x1, y1, x2, y2 이 네 숫자는 3차 베지어 곡선을 그리는 두 개의 제어점 좌표입니다. 곡선의 시작점(0,0)과 끝점(1,1)은 CSS 스펙에서 이미 고정돼 있어서, 실제로 우리가 조절할 수 있는 값은 그 사이에 있는 두 제어점뿐입니다.
그래프의 가로축(x)은 애니메이션이 시작된 뒤 전체 지속시간 중 얼마가 지났는지를 0에서 1 사이 비율로 나타냅니다. 세로축(y)은 그 시점에 애니메이션이 얼마나 진행됐는지, 즉 위치나 크기 같은 값이 시작값과 끝값 사이에서 몇 %까지 옮겨왔는지를 나타냅니다.
x는 시간이 거꾸로 흐를 수 없기 때문에 0과 1 사이로 고정되지만, y는 1을 넘거나 0 아래로 내려갈 수 있습니다. y가 1을 넘는 구간은 목표 지점을 살짝 지나쳤다가 되돌아오는, 튕기는 듯한 움직임을 만들어냅니다.
곡선의 기울기가 곧 체감 속도인 이유
이 곡선에서 특정 지점의 기울기는 그 순간에 애니메이션 값이 얼마나 빠르게 변하고 있는지를 나타냅니다. 기울기가 가파르면 짧은 시간 안에 값이 크게 움직이고, 기울기가 완만하면 시간이 지나도 값이 거의 바뀌지 않습니다.
실제 물체는 정지 상태에서 갑자기 최고 속도로 움직이지 않고, 멈추기 직전에도 갑자기 속도가 0이 되지 않습니다. 서서히 빨라지고 서서히 느려지는 이 과정이 우리 눈에 자연스럽게 보이는 이유입니다.
ease 계열 곡선은 시작과 끝 부근의 기울기를 일부러 완만하게 설계해서 이 가속·감속 구간을 만듭니다. 반대로 시작과 끝의 기울기까지 가팔라지는 곡선을 만들면, 움직임이 튀듯이 급하게 느껴집니다.
linear가 부자연스럽게 느껴지는 이유
linear는 사실 cubic-bezier(0, 0, 1, 1)과 똑같습니다. 두 제어점이 각각 시작점·끝점과 같은 자리에 놓이면서, 곡선 전체가 (0,0)과 (1,1)을 잇는 완전한 직선이 됩니다.
직선은 어느 지점에서든 기울기가 똑같습니다. 즉 애니메이션이 시작되는 순간부터 끝나는 순간까지 속도가 하나도 변하지 않고 일정하게 유지된다는 뜻입니다.
문제는 애니메이션 전후입니다. 정지해 있던 요소가 속도 0에서 갑자기 일정한 속도로 뛰어오르고, 끝날 때도 그 속도를 유지한 채로 갑자기 멈춥니다. 이 순간적인 속도 변화가 눈에는 뚝뚝 끊기는 부자연스러운 움직임으로 보입니다.
ease·ease-in·ease-out·ease-in-out은 사실 이 값 하나일 뿐
브라우저가 기본으로 제공하는 이름 붙은 이징들은 전부 미리 정해둔 cubic-bezier 좌표 하나에 붙은 별명일 뿐입니다. 별도의 계산 방식이 따로 있는 게 아니라, 자주 쓰는 제어점 조합에 이름을 붙여둔 것입니다.
| 이름 | cubic-bezier 값 | 특징 |
|---|---|---|
| linear | (0, 0, 1, 1) | 시작부터 끝까지 속도 일정 |
| ease | (0.25, 0.1, 0.25, 1) | 살짝 빠르게 출발해 서서히 느려짐(기본값) |
| ease-in | (0.42, 0, 1, 1) | 느리게 시작해 점점 빨라지다 끝에서도 속도 유지 |
| ease-out | (0, 0, 0.58, 1) | 빠르게 시작해 점점 느려지다 멈춤 |
| ease-in-out | (0.42, 0, 0.58, 1) | 느리게 시작, 중간에 빨라짐, 다시 느리게 끝남 |
ease-in은 끝 지점 제어점이 (1,1), 즉 끝점과 같은 자리에 있어서 마지막까지 가속이 붙은 채로 끝납니다. 화면 밖으로 사라지는 요소에 자주 쓰이는 이유입니다.
ease-out은 반대로 시작 지점 제어점이 (0,0)과 같은 자리에 있어 처음부터 속도를 내다가 끝에서 서서히 멈춥니다. 화면에 들어와 멈춰 서는 요소에 어울립니다.
손으로 이 곡선을 직접 확인하려면
이 값이 실제로 어떤 움직임을 만드는지 손으로 확인하려면, 3차 베지어 공식에 t를 0부터 1까지 여러 번 대입해 곡선 위의 점을 하나씩 계산하고 그래프 용지에 찍어봐야 합니다.
곡선 모양만 그려서는 부족합니다. 실제 CSS에 적용해서 눈으로 봐야 그 값이 원하는 속도감을 주는지 알 수 있으므로, 값을 조금 바꾸고 브라우저를 새로고침해서 다시 보는 과정을 여러 번 반복해야 합니다.
슬라이더로 곡선을 조정하고 실제 움직임 미리보기와 transition CSS를 바로 복사하는 큐빅 베지어 이징 생성기

도구가 곡선 계산과 움직임 확인을 동시에 보여주는 방식
큐빅 베지어 이징 생성기는 지금까지 설명한 그래프를 눈에 보이는 곡선으로 직접 그려줍니다. 왼쪽 영역에 정사각형 좌표평면과 곡선, 그리고 두 제어점의 위치가 점으로 표시되어 x1·y1·x2·y2 값이 그래프 위 어디에 해당하는지 바로 확인됩니다.
오른쪽 영역에서는 같은 cubic-bezier 값을 실제 CSS transition에 적용한 원과 막대가 반복해서 움직입니다. 이 미리보기는 실제 브라우저 렌더링 그대로이기 때문에, 그래프에서 본 곡선 모양과 화면에서 느껴지는 속도감이 정확히 일치하는지 바로 대조할 수 있습니다.
프리셋과 지속시간으로 곡선을 빠르게 비교하기
ease부터 bounce-ish까지 여덟 개의 프리셋 버튼을 누르면 지금까지 설명한 좌표 값이 슬라이더와 숫자 입력창에 그대로 채워집니다. x1·x2는 0에서 1 사이로 값이 제한되지만 y1·y2는 그 범위를 벗어날 수 있어, back-out처럼 튕기는 곡선도 직접 만들어볼 수 있습니다.
지속시간 슬라이더로 같은 곡선을 다른 속도에서 비교해볼 수 있고, 완성된 값은 transition 한 줄 또는 transition-timing-function 한 줄로 각각 바로 복사할 수 있습니다.
정리
- cubic-bezier(x1, y1, x2, y2)의 네 숫자는 고정된 시작점(0,0)·끝점(1,1) 사이 두 제어점의 좌표입니다.
- 곡선의 기울기는 그 순간의 속도를 뜻하며, 기울기가 완만할수록 느리게, 가파를수록 빠르게 값이 변합니다.
- linear는 cubic-bezier(0, 0, 1, 1), 즉 완전한 직선이라 시작과 끝에서 속도가 갑자기 바뀌어 부자연스럽게 느껴집니다.
- ease·ease-in·ease-out·ease-in-out은 별도의 알고리즘이 아니라 자주 쓰는 좌표값에 붙은 이름일 뿐입니다.
- y값은 1을 넘거나 0 밑으로 내려갈 수 있어, 목표 지점을 지나쳤다 되돌아오는 오버슈트 곡선도 같은 원리로 만들어집니다.
슬라이더로 곡선을 조정하고 실제 움직임 미리보기와 transition CSS를 바로 복사하는 큐빅 베지어 이징 생성기
자주 묻는 질문
cubic-bezier 값에서 x가 1을 넘거나 음수가 될 수 있나요?
x는 시간 축이라 0에서 1 사이로 고정됩니다. 시간이 거꾸로 흐르거나 지속시간보다 더 길게 흐를 수는 없기 때문입니다. 반면 y는 진행률 축이라 1을 넘거나 0 아래로 내려갈 수 있고, 이 경우 목표 지점을 지나쳤다가 되돌아오는 오버슈트 움직임이 만들어집니다.
ease와 ease-in-out은 뭐가 다른가요?
둘 다 느리게 시작해서 빨라지는 구간이 있다는 점은 비슷하지만 제어점 좌표가 다릅니다. ease는 cubic-bezier(0.25, 0.1, 0.25, 1)로 시작 부분의 기울기가 상대적으로 더 가파르게 잡혀 있어 살짝 빠르게 출발하는 느낌이고, ease-in-out은 cubic-bezier(0.42, 0, 0.58, 1)로 시작과 끝의 기울기가 더 대칭적으로 완만합니다.
transition-timing-function에 cubic-bezier 대신 이름(ease 등)을 써도 되나요?
네, 브라우저 입장에서는 완전히 동일합니다. ease 같은 이름은 특정 cubic-bezier 좌표를 미리 등록해둔 별칭일 뿐이라서, 이름을 쓰든 좌표를 직접 쓰든 렌더링 결과는 같습니다. 다만 프리셋에 없는 세밀한 속도감을 원한다면 좌표를 직접 조정해야 합니다.
왜 linear를 써야 할 때도 있나요?
시작과 끝에서 가속·감속이 없어야 자연스러운 경우에는 linear가 오히려 맞는 선택입니다. 예를 들어 계속 반복되며 방향이 바뀌지 않는 회전 애니메이션은 각 구간의 속도가 일정해야 이어지는 지점에서 속도가 뚝 끊기지 않습니다.
