개요
CSS 마스킹을 사용하면 카드에 노치를 추가하거나 모양이 있는 테두리를 만드는 등 요소를 맞춤 도형으로 클리핑할 수 있습니다. 복잡한 레이아웃을 위해 도형을 결합할 때는 요소에 포함된 콘텐츠 유형에 따라 마스킹 전략을 선택합니다.
| 마스킹 전략 | 지원 기기 | 텍스트 효과 |
|---|---|---|
| 직접 요소 SVG 마스킹 | 이미지, 아이콘, 장식용 도형, 복잡한 도형 | 권장하지 않음 (텍스트가 잘릴 수 있음) |
| 인접 요소 SVG 마스킹 | 텍스트가 포함된 카드, 중요한 콘텐츠 | 텍스트를 완전히 읽을 수 있음 |
| 순수 CSS 그라데이션 | 간단한 기하학적 도형 | 권장하지 않음 (텍스트가 잘릴 수 있음) |
구현
모양 컷아웃을 구현하려면 다음 단계를 따르세요.
SVG 마스크 사용
SVG 마스크를 사용하면 흰색 (표시) 및 검은색 (숨기기) 채우기를 사용하여 표시 영역에서 빼거나 더하는 도형을 정의할 수 있습니다.
휘도와 알파 마스킹: SVG 마스크는 기본적으로 휘도 (밝기) 모드로 설정되어 있으므로
fill="white"를 사용하여 영역을 표시하고fill="black"를 사용하여 영역을 잘라냅니다. 색상 대신 SVG의 투명도 (알파 채널)를 사용하려면 CSS에서mask-type: alpha;를 설정하거나 SVG<mask>요소에서mask-type="alpha"를 설정하면 됩니다.
직접 요소 SVG 마스킹
요소 내에 텍스트가 없는 경우 (예: 프로필 아바타, 제품 이미지, 일러스트레이션) SVG 마스크를 요소에 직접 적용할 수 있습니다.
SVG 마스크 내에서 maskContentUnits="objectBoundingBox"를 사용하면 마스크가 적용되는 모든 요소의 너비와 높이에 맞게 자동으로 조정됩니다.
<!-- 1. Define the mask in SVG (hidden from view) -->
<svg width="0" height="0" style="position: absolute;" aria-hidden="true">
<defs>
<!-- objectBoundingBox makes the mask scale from 0 to 1 along the element's borders -->
<mask id="splat-mask" maskContentUnits="objectBoundingBox">
<!-- Organic Bezier path defining an artistic paint splat shape -->
<path d="M 0.5 0.05 C 0.58 0.05, 0.58 0.21, 0.67 0.18 C 0.76 0.15, 0.79 0.08, 0.85 0.15 C 0.91 0.22, 0.83 0.32, 0.89 0.38 C 0.95 0.44, 1.03 0.45, 0.99 0.55 C 0.95 0.65, 0.82 0.62, 0.8 0.72 C 0.78 0.82, 0.89 0.92, 0.8 0.97 C 0.71 1.02, 0.64 0.88, 0.55 0.93 C 0.46 0.98, 0.44 1.06, 0.35 1.01 C 0.26 0.96, 0.31 0.81, 0.22 0.79 C 0.13 0.77, 0.01 0.88, 0.01 0.77 C 0.01 0.66, 0.16 0.62, 0.14 0.52 C 0.12 0.42, -0.02 0.39, 0.03 0.29 C 0.08 0.19, 0.23 0.27, 0.29 0.19 C 0.35 0.11, 0.3 0.01, 0.4 0.01 C 0.5 0.01, 0.42 0.05, 0.5 0.05 Z" fill="white" />
</mask>
</defs>
</svg>
<!-- 2. Apply the mask to the image element -->
<img src="avatar.jpg" alt="User Profile" class="shaped-avatar">
<style>
.shaped-avatar {
width: 200px;
height: 200px;
object-fit: cover;
/* Apply the SVG mask ID with standard and webkit-prefixed properties */
-webkit-mask-image: url(#splat-mask);
mask-image: url(#splat-mask);
}
</style>
인접 요소 SVG 마스킹
텍스트가 포함된 상위 요소가 아닌 인접한 요소에 마스크를 적용합니다. 이렇게 하면 텍스트가 잘리지 않고 읽을 수 있는 상태로 유지됩니다.
이 문제를 해결하려면 구성요소를 두 부분으로 구성된 레이아웃으로 구성합니다.
- 읽을 수 있는 모든 콘텐츠를 위한 안전하고 마스킹되지 않은 텍스트 컨테이너 (
.card-body) - 맞춤 SVG 마스크를 수신하는 빈 장식용
div(.card-accent)가 옆에 배치됩니다.
두 부분에 동일한 배경 색상을 할당하면 시각적으로 하나의 맞춤형 구성요소로 병합됩니다.
<!-- 1. Define the SVG mask (hidden from view) -->
<svg width="0" height="0" style="position: absolute;" aria-hidden="true">
<defs>
<!-- Use objectBoundingBox to make the mask scale with the element -->
<mask id="accent-stencil" maskContentUnits="objectBoundingBox">
<!-- Fill the entire area with white (fully visible) -->
<rect width="1" height="1" fill="white" />
<!-- Draw a black shape to cut out a concave curve. Extending the path to x=1.1 guarantees it fully clears the right edge, preventing subpixel lines -->
<path d="M 1.1,0 C 0.4,0.1 0.4,0.9 1.1,1 L 1.1,0 Z" fill="black" />
</mask>
</defs>
</svg>
<!-- 2. Create the unified card layout -->
<div class="unified-card">
<!-- The text-bearing element remains unmasked and perfectly rectangular -->
<div class="card-body">
<h3>Premium Membership</h3>
<p>Get exclusive weekly updates on modern web standards and premium UI designs.</p>
</div>
<!-- The empty accent element next to it is masked to form the custom shape -->
<div class="card-accent"></div>
</div>
<style>
.unified-card {
display: flex;
width: 400px;
}
.card-body {
flex: 1;
background-color: #1e293b; /* Elegant slate color */
color: #f8fafc;
padding: 24px;
border-top-left-radius: 16px;
border-bottom-left-radius: 16px;
}
.card-accent {
width: 60px;
background-color: #1e293b; /* Same background color so they merge visually without seams */
border-top-right-radius: 16px;
border-bottom-right-radius: 16px;
/* Reference the SVG mask */
-webkit-mask-image: url(#card-accent-mask);
mask-image: url(#card-accent-mask);
}
</style>
간단한 컷아웃에 단일 CSS 그라데이션 사용
반원형 상단 노치, 측면 들여쓰기, 직선 대각선 절단과 같은 간단한 기하학적 컷아웃만 필요한 경우 외부 SVG를 작성하거나 참조할 필요가 없습니다. 대신 mask-image 속성 내에서 직접 CSS 방사형 또는 선형 그래디언트를 정의할 수 있습니다.
<div class="gradient-masked-card">
<h3>Notched Coupon Card</h3>
<p>This card uses a pure CSS radial gradient to cut out a semi-circular notch along its top edge.</p>
</div>
<style>
.gradient-masked-card {
background: linear-gradient(135deg, #3b82f6, #1d4ed8);
color: white;
padding: 40px 24px 24px 24px; /* Extra top padding ensures content clears the notch */
border-radius: 16px;
text-align: center;
/* radial-gradient places a circle at 50% (horizontal center) and 0% (top edge), cutting out a 20px transparent notch */
-webkit-mask-image: radial-gradient(circle at 50% 0%, transparent 20px, black 21px);
mask-image: radial-gradient(circle at 50% 0%, transparent 20px, black 21px);
}
</style>
대체 전략
브라우저가 mask-image 또는 접두사가 붙은 버전을 지원하지 않는 경우:
- 모양이 있는 이미지: 요소가 점진적으로 저하되어 기본 대체 스타일이 적용된 일반 직사각형 요소로 표시됩니다.
- 모양이 있는 카드의 경우: 인접한 장식용
.card-accent요소는 마스크되지 않은 단색 직사각형으로 유지됩니다. 텍스트 컨테이너와 동일한 배경 색상을 공유하므로 전체 카드가 깔끔한 표준 직사각형 컨테이너로 렌더링됩니다. - 점진적 개선: 텍스트 레이어를 마스크 외부에 완전히 유지하면 이전 브라우저에서도 콘텐츠를 완전히 읽을 수 있고 구조화되며 액세스할 수 있습니다.