본문으로 건너뛰기

© 2026 Molayo

CSS-T헤드라인2026. 05. 25. 07:50

접힌 모서리(Folded Corners)를 위한 CSS corner-shape 활용하기

요약

CSS의 새로운 기능인 `corner-shape`를 활용하여 종이의 접힌 모서리 효과를 구현하는 방법을 설명합니다. `border-radius`의 좌표 원리를 이해하고 CSS 변수를 사용하여 애니메이션이 가능한 접힘 효과를 만드는 과정을 다룹니다.

핵심 포인트

  • CSS `corner-shape`를 이용한 접힌 모서리 구현 방법
  • border-radius의 x, y 좌표 원리 활용
  • CSS 변수를 통한 접힘 효과 애니메이션 구현
  • 브라우저 지원 현황 및 fallback 전략

Kitty Giraudel의 접힌 모서리 기술을 접하게 되었습니다. 이 기술은 CSS clip-path를 활용하는데, 정말 멋진 방식이라고 생각했습니다. 최근 웹 브라우저들이 shape() 함수를 지원하게 되면서 clip-path가 트렌드가 되고 있는 것 같습니다.

하지만 저는 최근 corner-shape에 푹 빠져 있는 상태라 (제 corner-shape 입문 가이드와 이 스크롤 기반 corner-shape 애니메이션도 확인해 보세요), corner-shape를 사용해서도 접힌 모서리를 만들 수 있지 않을까 생각했고, 다음과 같은 결과물을 만들어냈습니다:

CodePen Embed Fallback

White paper with the top-right corner folded in.

그러니 corner-shape를 지원하는 Chrome을 열고 자세히 살펴봅시다 (만약 다른 브라우저에서 이 글을 보고 계신다면, 기본적으로 둥근 모서리로 대체되어 보일 것입니다).

1단계: CSS 변수 설정하기

요소에는 네 개의 모서리가 있지만, border-radius를 사용할 때 각 모서리는 두 개의 좌표로 나뉩니다. x축 좌표는 해당 모서리로부터 x축을 따라 이동하고, y축 좌표는 y축을 따라 동일하게 이동합니다. border-radius는 바로 이 좌표들을 바탕으로 둥근 모서리의 곡률을 그립니다.

Diagramming the shape showing border-radius applied to the bottom-left corner. The rounded corner is 50% on the y-axis and 50% on the x-axis.

먼저, 이 좌표들을 CSS 변수로 저장합니다. 이 값들은 여러 번 사용해야 하므로, 변수로 저장하면 작업이 간편해지고, 접힘 효과에 애니메이션을 적용할 수 있으며, 어느 정도의 사실감을 유지할 수 있습니다.

:root {
  /* x축 좌표 */
  --x-coord: 9rem;
...

2단계: 접힘 구현하기

이제 border-radius에 대해 알게 된 내용을 바탕으로, border-top-right-radius가 어떤 역할을 하는지 명확히 알 수 있을 것입니다. corner-top-right-shape: bevel의 경우, 둥근 모서리(corner-top-right-shape: round) 대신 좌표 사이에 직선이 그려지도록 보장합니다. 맞습니다, border-radius는 기본적으로 (물론 내부적으로) corner-shape: round를 포함하고 있습니다.

/* Square */
div {
  /* Place coordinates */
...

CodePen Embed Fallback

White paper with a diagonal cut in the top-right corner.

3단계: 뒷면 만들기

이제 접힘(fold)을 구현했으니, 뒷면을 만들 차례입니다. 먼저 ::before를 선택한 다음, content: ""를 선언하여 내용이 없는 요소를 생성합니다. background는 사각형(square)으로부터 상속받을 수 있으며, 크기는 우리가 저장해둔 좌표를 활용해야 합니다. 보시는 바와 같이, 저는 블러 반경(blur radius)이 --x-coord--y-coord에 따라 조절되는 box-shadow를 추가했지만, 여러분의 필요에 따라 공식을 자유롭게 수정하셔도 좋습니다.

/* Square */
div {
  /* Place coordinates */
...

CodePen Embed Fallback

White paper with s white rectangle in the top-left corner and a diagonal cut in the top-right corner.

4단계: 뒷면(::before) 위치시키기

다음으로, ::before를 (상단) 오른쪽 모서리로 이동시켜야 합니다. 여기서는 앵커 포지셔닝 (anchor positioning)을 사용하지 않을 것입니다. 왜냐하면 동일한 양의 코드로 더 많은 브라우저에서 지원되는 기능을 잘 사용할 수 있다면, 굳이 최신 기능을 사용할 필요가 없기 때문입니다. 따라서 사각형에는 position: relative를, ::before에는 position: absolute를 선언합니다. 이렇게 하면 ::before가 사각형을 기준으로 위치하게 되는데, 이는 부모-자식 관계에서만 작동하는 트릭입니다. 사실 이러한 한계 때문에 앵커 포지셔닝이 발명되었지만, 이번 사례에서는 굳이 필요하지 않습니다.

또한, ::beforeinset: 0 0 auto auto를 선언하여 사각형의 오른쪽 상단 모서리에 맞추고, 사각형에 overflow: clip을 선언하여 사각형 밖으로 넘치는 ::before의 절반을 잘라냅니다.

/* Square */
div {
  /* Place coordinates */
...

CodePen Embed Fallback

White paper with the top-right corner folded in.

원하는 대로 여기서 멈춰도 되지만, 더 개선할 여지가 있습니다…

5단계: 뒷면 조각하기 (Sculpting the flip side)

결과물을 조금 더 사실적으로 만들기 위해, 이번에는 ::before 요소에 corner-bottom-left-shape: bevel을 사용하여 직선 절단면을 하나 더 추가하겠습니다. 접힌 부분을 얼마나 날카롭게 만들지, 뒷면을 얼마나 높게 띄울지, 그리고 사각형을 어떤 각도에서 바라볼지에 따라 이를 해결하는 방법은 아마도 매우 다양할 것입니다. 하지만 효과가 그럴싸해 보이기만 한다면 어떤 방식이든 상관없다고 생각하므로, 우리는 날카로운 주름, 위로 솟아오른 뒷면, 그리고 항공뷰(aerial view)를 목표로 합니다. 만약 다른 스타일을 원하신다면, 그림자 또한 결과물에 영향을 미치며 구현 방식이 더 까다로워질 수 있다는 점을 유념하세요.

제가 제안하는 유일한 복잡성 단계는 다음과 같습니다:

/* 사실적인 접힘 보장 */
@container style(--x-coord < --y-coord) {
  border-bottom-left-radius: 100% calc(100% - var(--x-coord));
...

이것은 범위 구문(range syntax)을 사용하는 컨테이너 스타일 쿼리 (container style queries using the range syntax)입니다. 만약 --x-coord의 값이 --y-coord의 값보다 작다면, 100%에서 --x-coord 값을 뺀 값을 해당 테두리 반경(border-bottom-left-radius, 이 경우에는)의 y축 좌표로 사용합니다. 다른 축은 100%로 설정됩니다. 반대로, --x-coord의 값이 --y-coord의 값보다 크거나 같다면, 100%에서 --y-coord 값을 뺀 값을 x축 좌표로 사용합니다. 다시 한번, 다른 축은 100%로 설정됩니다.

그 결과, 접힘의 주름, 그림자, 그리고 이제는 *원근감 (perspective)*까지 오직 --x-coord--y-coord만을 사용하여 사실적으로(또는 적어도 충분히 사실적으로) 계산됩니다. 데모 우측 상단의 slideVars 토글을 사용하여 다양한 좌표 조합을 테스트하며 직접 확인해 볼 수 있습니다:

CodePen Embed Fallback

좌표가 사각형의 크기를 초과하여 효과가 깨지는 것을 방지하기 위한 안전장치(failsafe)를 구현하고 싶다면 min() 함수를 사용할 수 있습니다. 아래의 수정된 좌표 변수는 --y-coord를 불가능한 값인 999999999rem으로 설정하지만, 사각형의 높이로 제한(cap)합니다 (솔직히 말해서 실제로 이런 기능이 필요할 것 같지는 않지만 말입니다):

--x-coord: min(--square-width, 9rem);
--y-coord: min(--square-height, 999999999rem);

CodePen Embed Fallback

White paper with the top-right corner folded in.

결과적으로, 우리는 단순히 접힌 모서리(folded corner) 효과뿐만 아니라 단 두 개의 좌표만으로 효과를 생성하는 유틸리티를 갖게 되었습니다.

전체 코드:

:root {
  /* x축 좌표 */
  --x-coord: 9rem;
...

참고: 더 짧지만 가독성이 떨어지는 if() 함수로 컨테이너 스타일 쿼리(container style queries)를 교체할 수도 있습니다.

clip-path를 사용한 접힌 모서리 vs corner-shape를 사용한 접힌 모서리

Kitty Giraudel의 접힌 모서리는 모든 브라우저에서 작동하며, 더 다재다능한 모양 지정 기능인 clip-path를 사용하기 때문에 모양을 커스텀할 수 있는 방법이 더 많습니다. 또한, 이것이 무엇을 위한 것이든 간에 더 올바른 접근 방식이기도 합니다. 하지만 저의 corner-shape 방식은 더 깔끔하며 아마도 추가적인 커스텀이 필요하지 않을 것이지만, 현재로서는 Safari와 Firefox 지원이 부족합니다. 따라서 당장 접힌 모서리가 필요한 것이 아니라면, 다음 두 가지를 모두 북마크해 두는 것을 추천합니다:

AI 자동 생성 콘텐츠

본 콘텐츠는 CSS-Tricks의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0