Masking/Clipping

김동현·2026년 3월 21일

mdn 학습 번역 - CSS

목록 보기
122/190

안녕하세요! 프론트엔드 강사입니다. 이번에는 웹 디자인을 한 차원 끌어올릴 수 있는 마법 같은 기술, CSS 클리핑(Clipping)에 대해 함께 알아보려고 해요.

지금까지 웹에서 요소들은 항상 네모 반듯한 직사각형 형태여야만 한다고 생각하셨나요? 오늘 배우게 될 clip-path를 사용하면 그런 고정관념을 완전히 깰 수 있답니다! 공식 문서의 내용을 바탕으로 제가 실무에서 자주 쓰는 팁들까지 팍팍 담아서 친절하게 번역하고 설명해 드릴게요. 자, 준비되셨죠? 시작해 봅시다!


CSS 클리핑 소개 (Introduction to CSS clipping)

CSS 클리핑(clipping)을 사용하면 요소의 보이는(visible) 부분을 직접 정의하고 나머지 부분은 숨길 수 있습니다. 즉, 특정 도형이나 영역 안으로 요소의 콘텐츠를 효과적으로 "잘라내는(clipping)" 것이죠. 클리핑을 활용하면 요소들이 직사각형으로만 렌더링되는 한계에서 벗어나 시각적으로 훨씬 매력적이고 다채로운 방식으로 디자인될 수 있습니다. 이 가이드에서는 몇 가지 예제와 함께 clip-path 속성에 대해 깊이 탐구해 보겠습니다.


CSS 클리핑이란? (CSS clipping)

클리핑은 요소의 특정 섹션을 잘라내어(숨기고), 개발자가 정의한 경로(path) 내부에 위치한 요소의 영역만 화면에 표시하는 CSS 기술입니다. 클립 영역은 벡터(vector) 경로에 의해 생성되며, 이 경로 안에 있는 모든 것은 보이고 경로 바깥에 있는 영역은 모두 숨겨집니다.

clip-path 속성 (The clip-path property)

clip-path 속성은 클리핑을 실제로 적용하는 속성입니다. 이 속성이 받는 값은 요소에서 계속 '보여야 할' 영역을 정의하는 벡터 경로입니다. 이 경로는 박스(boxes) 영역을 사용하거나, SVG <clipPath>에 대한 참조(reference)를 사용하거나, CSS 도형 및 경로(shapes and paths) 함수를 사용하여 정의할 수 있습니다.

다음 예제에서는 클리핑 경로로 polygon() 함수를 사용하여 파란색 정사각형 <div>를 다이아몬드(마름모) 모양으로 잘라냅니다.

<div class="diamond"></div>
.diamond {
  height: 200px;
  width: 200px;
  background-color: blue;

  clip-path: polygon(0 50%, 50% 100%, 100% 50%, 50% 0);
}

👨‍🏫 강사의 팁:
처음 polygon() 안의 좌표 숫자를 보면 "이걸 어떻게 머릿속으로 계산하지?" 싶으실 거예요. 실무에서는 숫자를 일일이 찍어보기보다는 Clippy 같은 웹 제너레이터를 적극 활용합니다. 마우스로 점을 찍으면 코드가 자동으로 만들어져서 생산성이 훨씬 올라가요!

clip-path 속성의 값들 (Values of the clip-path property)

요소를 시각적으로 자르기 위해, clip-path 속성은 <geometry-box>, 클립 소스인 <clipPath>를 가리키는 url, 또는 도형 함수(shape function)로 만들어진 <basic-shape> 중 하나로 설정됩니다.


기하학적 박스 (Geometry boxes)

clip-path는 잘려진 영역 밖의 모든 것을 숨깁니다. 가장 기본적인 클리핑은 기하학적 박스(geometry box)를 통해 이루어집니다. 요소의 마진(margin), 테두리(border), 패딩(padding) 또는 콘텐츠(content) 영역을 기준으로 요소를 자를 수 있죠.

이러한 시각적 박스 값들이 내는 효과는 border-color를 투명(transparent)하게 설정하고 background-origin을 원하는 시각적 박스로 설정하는 등 다른 CSS 속성들을 통해서도 달성할 수 있습니다. 우리가 이 값들을 주로 살펴보는 이유는, 나중에 배울 도형 함수(shape functions)와 결합하여 도형 클립 경로의 기준점(origin)을 정의하는 데 사용되기 때문입니다.

CSS 도형에서 사용되는 기준 박스(reference box) 이해하기clip-path를 사용할 때, 특히 기본 도형(basic shapes)을 다룰 때 매우 중요합니다. 이 기준 박스가 도형의 좌표계(coordinate system)를 정의하기 때문입니다.

시각적 박스 값 (Visual box values)

아래의 라이브 예제는 요소에 적용된 clip-path 속성의 다양한 시각적 박스 값들을 CSS background-origin 속성과 비교하며 보여줍니다. <blockquote> 요소에 border, background-color, background-image, 그리고 padding이 적용되어 있습니다. 라디오 버튼을 선택하여 --value를 다른 <geometry-box> 값으로 업데이트하면, 해결된(resolved) background-originclip-path 값이 어떻게 적용되는지 확인할 수 있습니다.

body {
  display: flex;
  flex-flow: row wrap;
  place-content: center;
}
blockquote {
  float: left;
  font-size: 1.2rem;
}
q {
  color: white;
  font-family: sans-serif;
  display: block;
  margin-bottom: 0.5em;
}
p {
  margin: 0;
  line-height: 1.6;
}

body {
  --value: initial;
}
body:has([value="border-box"]:checked) {
  --value: border-box;
}
body:has([value="padding-box"]:checked) {
  --value: padding-box;
}
body:has([value="content-box"]:checked) {
  --value: content-box;
}
body:has([type="checkbox"]:checked) blockquote {
  border-radius: 70px;
}
blockquote {
  width: 210px;
  padding: 20px;
  margin: 20px;
  border: 20px dashed #dedede;
  background-color: #ededed;
  background-image: linear-gradient(rebeccapurple, magenta);
  background-repeat: no-repeat;
}

.clippath {
  background-origin: var(--value);
  clip-path: var(--value);
}

.box-model {
  background-origin: var(--value);
}
<blockquote class="clippath">
  <q
    >I've learned that people will forget what you said, people will forget what
    you did, but people will never forget how you made them feel.</q
  >
  <cite>&mdash; Maya Angelou</cite>
</blockquote>
<blockquote class="box-model">
  <q
    >I've learned that people will forget what you said, people will forget what
    you did, but people will never forget how you made them feel.</q
  >
  <cite>&mdash; Maya Angelou</cite>
</blockquote>

<fieldset>
  <legend>Select the geometry box value:</legend>
  <p>
    <label
      ><input type="radio" name="gb" value="border-box" /> border-box</label
    >
  </p>
  <p>
    <label
      ><input type="radio" name="gb" value="padding-box" /> padding-box</label
    >
  </p>
  <p>
    <label
      ><input type="radio" name="gb" value="content-box" /> content-box</label
    >
  </p>
  <p>
    <label
      ><input type="radio" name="gb" value="initial" checked /> initial</label
    >
  </p>
</fieldset>
<p>
  <label><input type="checkbox" /> Change the border radius</label>
</p>

<geometry> 박스가 <basic-shape>와 결합되어 지정될 때, 이 값은 기본 도형의 '기준 박스(reference box)'를 정의합니다. 만약 단독으로 지정된다면, 이는 지정된 박스의 가장자리(가령 border-radius와 같은 모서리 둥글기 쉐이핑을 포함하여) 자체가 클리핑 경로가 되게 만듭니다.

도형의 기준점 (Shape origin)

이전 예제를 보면 "어차피 background-origin을 대신 쓸 수 있는데 <geometry-box> 값이 쓸모없는 거 아닌가?"라고 생각하실 수 있습니다. 네, 그렇게 쓸 수 있습니다.

하지만 기본 도형(basic shapes)을 사용해 클리핑을 할 때, <geometry-box><basic-shape>와 함께 clip-path의 값으로 포함되면, 해당 도형의 기준 박스(또는 기준점, origin)를 정의하는 아주 중요한 역할을 합니다. 이전에 살펴본 두 가지 예제를 합쳐보면 이를 쉽게 증명할 수 있죠.

👨‍🏫 강사의 팁:
쉽게 말해서 clip-path: polygon(...) padding-box; 라고 쓰면, 폴리곤 좌표의 0%, 0% 위치가 테두리 바깥이 아니라 '패딩이 시작되는 지점'으로 옮겨진다는 뜻이에요. 정교한 클리핑을 할 때 기준점이 어딘지 명확히 해주는 것이 뼈대가 됩니다.

<blockquote class="clippath">
  <q
    >I've learned that people will forget what you said, people will forget what
    you did, but people will never forget how you made them feel.</q
  >
  <cite>&mdash; Maya Angelou</cite>
</blockquote>
<fieldset>
  <legend>Select the origin of the clip path shape:</legend>
  <p>
    <label
      ><input type="radio" name="gb" value="border-box" checked />
      border-box</label
    >
  </p>
  <p>
    <label
      ><input type="radio" name="gb" value="padding-box" /> padding-box</label
    >
  </p>
  <p>
    <label
      ><input type="radio" name="gb" value="content-box" /> content-box</label
    >
  </p>
</fieldset>
blockquote {
  font-size: 1.2rem;
}
q {
  color: white;
  font-family: sans-serif;
  display: block;
  margin-bottom: 0.5em;
}
p {
  margin: 0;
  line-height: 1.6;
}

body {
  --value: "";
}
body:has([value="border-box"]:checked) {
  --value: border-box;
}
body:has([value="padding-box"]:checked) {
  --value: padding-box;
}
body:has([value="content-box"]:checked) {
  --value: content-box;
}
blockquote {
  width: 210px;
  padding: 20px;
  margin: 20px;
  border: 20px dashed #dedede;
  background-color: #ededed;
  background-image: linear-gradient(rebeccapurple, magenta);
  background-repeat: no-repeat;
  background-origin: border-box;
  clip-path: var(--value) polygon(0 50%, 50% 100%, 100% 50%, 50% 0);
}

다른 예제를 보고 싶다면 clip-path 도형 및 기하학적 박스(shapes and geometry boxes) 문서를 참고해 보세요.

심지어 clip-path: margin-box 같은 값도 유용할 수 있습니다. 마진 박스(margin-box) 가장자리에 클립 경로의 가장자리를 배치해서 창의적인 시각 효과를 만드는 것 외에도, clip-pathnone이 아닌 어떤 계산된 값(computed value)이 적용되면, CSS opacity1 이외의 값일 때 작동하는 것과 동일한 방식으로 새로운 쌓임 문맥(stacking context)을 생성합니다.


기본 도형으로 자르기 (Clipping to basic shapes)

clip-path 속성이 <basic-shape> 값을 지원하게 되면서 요소를 자유자재로 다듬을 수 있는 아주 강력한 방법이 생겼습니다. 다양한 도형 함수를 통해 정밀한 클리핑 영역을 정의할 수 있으며, 요소를 독특한 형태로 깎아낼 수(sculpting) 있죠.

기본 도형 함수들에는 다음이 포함됩니다:

이러한 도형들의 크기와 위치는 <geometry-box> 값에 의해 정의됩니다. 만약 clip-path 값에 <geometry-box> 컴포넌트 없이 도형만 포함되어 있다면, 기본적으로 기준 박스로 border-box가 사용됩니다.

이 함수들 중 일부는 단순하게 미리 정의된 클리핑 옵션만 제공하는 것처럼 보일 수 있습니다. 마치 border-radius로 만들 수 있는 효과를 그대로 복제하는 것처럼 보일 수도 있죠. 하지만 이전 예제에서 시각적 박스 값으로 border-radius 속성을 켜고 꺼보셨다면 CSS 클리핑의 진정한 힘을 눈치채셨을 겁니다.

도형(Shapes)은 훨씬 더 강력한 제어력을 제공합니다. 예를 들어, inset()을 사용하면 픽셀 단위로 정확한 여백을 가진 직사각형으로 자를 수 있습니다. 진짜 강력함은 사용자 정의 다중 포인트 도형을 만들 수 있게 해주는 path(), shape(), 그리고 polygon()에서 발휘됩니다.

다각형(Polygon) 만들기 (Creating polygons)

polygon()을 사용하면, 도형의 꼭짓점(vertex)을 나타내는 좌표 쌍(pairs of coordinates)들을 정의해서 별 모양이나 추상적인 도형처럼 아주 복잡한 형태를 만들 수 있습니다. 이 좌표들은 직선으로 서로 연결되는 벡터 점(vector points)을 정의합니다.

여기서 polygon() 함수를 사용해 별(star) 모양을 만들어보겠습니다.

<div class="star"></div>
.star {
  width: 200px;
  height: 200px;
  background: linear-gradient(rebeccapurple, magenta) blue;
  clip-path: polygon(
    50% 0%,
    61% 35%,
    100% 35%,
    68% 57%,
    79% 91%,
    50% 70%,
    21% 91%,
    32% 57%,
    0% 35%,
    39% 35%,
    50% 0%
  );
}

애니메이션 (Animation)

잘린 도형의 서로 다른 상태(states)에서 벡터 포인트(좌표)의 개수가 완벽히 동일하다면, 클리핑 된 도형에 애니메이션이나 트랜지션을 적용할 수 있습니다!

👨‍🏫 강사의 팁:
정말 중요한 조건이에요. 시작할 때 polygon의 점이 5개였다면, 끝날 때도 점이 5개여야 부드러운 스르륵 애니메이션(모핑, morphing)이 가능합니다. 점 개수가 다르면 중간 과정 없이 뚝 끊기며 바뀌게 되니 꼭 주의하세요!

<div class="star"></div>
@keyframes morphStar {
  from {
    clip-path: polygon(
      50% 0%,
      61% 35%,
      100% 35%,
      68% 57%,
      79% 91%,
      50% 70%,
      21% 91%,
      32% 57%,
      0% 35%,
      39% 35%,
      50% 0%
    );
  }
  to {
    clip-path: polygon(
      50% 10%,
      65% 30%,
      90% 20%,
      75% 60%,
      85% 95%,
      50% 80%,
      15% 95%,
      25% 60%,
      10% 20%,
      35% 30%,
      50% 10%
    );
  }
}

.star {
  animation: morphStar alternate 3s infinite ease-in-out;
}

SVG를 소스로 사용하기 (SVG as source)

path() 함수의 매개변수로 복잡한 SVG d 속성 문자열을 직접 넘기는 대신, clip-path 속성의 값으로 HTML 내의 SVG <clipPath> 요소를 직접 참조할 수도 있습니다.

<div class="heart"></div>
<svg height="0" width="0">
  <clipPath id="heart">
    <path
      d="M20,70 A40,40,0,0,1,100,70 A40,40,0,0,1,180,70 Q180,130,100,190 Q20,130,20,70 Z" />
  </clipPath>
</svg>

<clipPath>id 값을 CSS url() 함수의 파라미터로 넣어주면 끝입니다.

.heart {
  width: 200px;
  height: 200px;
  background: linear-gradient(rebeccapurple, magenta) blue;
  clip-path: url("#heart");
}

path() 함수 (The path() function)

곡선 (Curved lines)

직선만 그릴 수 있는 건 아닙니다. path() 함수를 사용하면 곡선도 그릴 수 있습니다. 이 예제에서는 path() 함수를 사용해 하트(heart) 모양을 만들어보겠습니다. path() 함수는 SVG를 그릴 때 사용하는 명령어를 그대로 받아들일 수 있습니다.

<div class="heart"></div>
.heart {
  width: 200px;
  height: 200px;
  background: linear-gradient(rebeccapurple, magenta) blue;
  clip-path: path(
    "M20,70 A40,40,0,0,1,100,70 A40,40,0,0,1,180,70 Q180,130,100,190 Q20,130,20,70 Z"
  );
}

도형 함수 (Shape function)

사실 순수 SVG 경로(path) 문법은 사람이 직관적으로 읽고 이해하기 쉽지 않습니다. 이런 이유로 CSS는 shape() 함수도 함께 제공합니다. shape() 함수 역시 경로 그리기 지시사항을 받지만, 사람이 훨씬 더 읽기 쉬운 문법(human-readable syntax)을 씁니다. 더 선언적인 형태의 CSS 코드로 앞서 만든 하트를 다시 만들어 볼 수 있습니다.

:root {
  --m: 10;
}
.heart {
  width: calc(20px * var(--m));
  height: calc(20px * var(--m));
  display: inline-block;
  background: linear-gradient(rebeccapurple, magenta) blue;
  clip-path: border-box
    shape(
      from calc(2px * var(--m)) calc(7px * var(--m)),
      arc to calc(10px * var(--m)) calc(7px * var(--m)) of 1% cw,
      arc to calc(18px * var(--m)) calc(7px * var(--m)) of 1% cw,
      curve to calc(10px * var(--m)) calc(19px * var(--m)) with
        calc(18px * var(--m)) calc(13px * var(--m)),
      curve to calc(2px * var(--m)) calc(7px * var(--m)) with
        calc(2px * var(--m)) calc(13px * var(--m))
    );
}
.small {
  --m: 4;
}

.medium {
  --m: 8;
}

.large {
  --m: 12;
}
<div class="heart small"></div>
<div class="heart medium"></div>
<div class="heart large"></div>

shape() 함수가 가진 진짜 장점은 단순한 좌표 점뿐만 아니라 CSS 값과 단위를 모두 허용한다는 점입니다 (반면 path()는 좌표값으로만 제한됩니다). 즉, calc()와 같은 CSS 수학 함수도 쓸 수 있죠! 위 코드처럼 CSS 변수(variables)를 잘 섞어 활용하면, 단 하나의 코드로 렌더링되는 크기가 각기 다른 여러 개의 도형(과 요소 박스)을 유연하게 찍어낼 수 있습니다.


자른 도형 주위로 텍스트 감싸기 (Wrapping text around your clipped shapes)

clip-path로 깎여나간 요소도 사실 브라우저 내부적으로는 여전히 '직사각형 박스(rectangular boxed)' 형태입니다. 클리핑은 요소가 박스처럼 보이지 않게 가려줄 뿐, 요소 자체가 가지는 박스 모델의 본질은 그대로 유지됩니다.

따라서 우리가 만든 다각형(혹은 사각형) 모양 그대로 주변에 인라인 콘텐츠(텍스트 등)를 감싸고 싶다면, shape-outside 속성을 함께 사용해야 합니다.
기본적으로 인라인 콘텐츠는 요소의 마진 박스(margin box) 주위를 감쌉니다. 하지만 shape-outside를 사용하면 이 텍스트 래핑 방식을 커스터마이징 할 수 있죠! 잘라낸 경로(clip path)와 똑같은 모양을 shape-outside에 넣어주면, 텍스트가 직사각형 박스 경계가 아닌 잘린 도형의 윤곽을 따라서 아름답게 흐르게 됩니다.

아래 예제는 두 개의 클리핑 된 삼각형 요소와, 그 주변을 부드럽게 감싸 흐르는 텍스트를 보여줍니다.

<div class="leftTriangle"></div>
<div class="rightTriangle"></div>
<blockquote>
  <q>
    I've learned that people will forget what you said, people will forget what
    you did, but people will never forget how you made them feel.</q
  >
  <cite>&mdash; Maya Angelou</cite>
</blockquote>
:root {
  --m: 10;
  font-size: calc(3px * var(--m));
}
div {
  width: calc(0.75em * var(--m));
  height: calc(0.75em * var(--m));
  display: inline-block;
  background: linear-gradient(rebeccapurple, magenta) blue;
}
cite {
  display: block;
  text-align: right;
}

클립 도형 모양으로 텍스트를 감싸려면, clip-pathshape-outside 속성에 완전히 동일한 도형을 적용하는 것 외에도, 잘린 요소가 콘텐츠와 동일한 라인에 배치될 수 있도록 반드시 요소를 띄워야(float) 합니다. (float: leftfloat: right 사용)

.leftTriangle {
  clip-path: polygon(0 0, 0 100%, 100% 0);
  shape-outside: polygon(0 0, 0 100%, 100% 0);
  float: left;
}
.rightTriangle {
  clip-path: polygon(100% 0, 100% 100%, 0 100%);
  shape-outside: polygon(100% 0, 100% 100%, 0 100%);
  float: right;
}

👨‍🏫 강사의 팁:
shape-outsideclip-path의 조합은 매거진 스타일(에디토리얼 디자인)의 웹 레이아웃을 만들 때 진짜 감탄이 나오는 기술이에요! 원형이나 사선 이미지 옆으로 텍스트가 자연스럽게 흘러가게 만들면 사이트가 한층 고급스러워 보인답니다.


함께 보기 (See also)

더 자세한 내용을 탐구하고 싶으시다면 아래 링크들을 참조해 보세요.


자, 여기까지 CSS 클리핑의 기본을 함께 살펴보았는데요! 혹시 clip-path를 활용해서 직접 만들어보고 싶은 특별한 모양이나 애니메이션 효과가 있으신가요? 말씀해 주시면 코드를 어떻게 시작해야 할지 가이드해 드릴 수 있습니다!

profile
프론트에_가까운_풀스택_개발자

0개의 댓글