🎨 Frontend CSS5. 색·시각 효과06 — Background (image·clip·attachment·multiple)

06 — Background (image·clip·attachment·multiple)

한 줄 답: background한 요소에 N개의 배경 레이어를 쌓는 단축 속성이다 — 콤마로 구분된 image / position / size / repeat / origin / clip / attachment를 한 줄에. background-clip: text그라데이션 텍스트를 만드는 유일한 길이고, attachment: fixed모바일에서 성능 폭탄이라 거의 폐지되었다.


Why — 왜 배경이 8개 속성을 갖는가

배경은 표면적으로 색 하나 또는 이미지 하나지만, 실제로는 8개 차원의 조합이다:

차원속성결정하는 것
1background-color가장 아래 색
2background-image이미지/그라데이션 (N개)
3background-position시작 위치
4background-size크기
5background-repeat반복 방식
6background-origin위치 기준 박스 (padding/border/content-box)
7background-clip클리핑 박스 (border-box/padding-box/content-box/text)
8background-attachment스크롤 따라가기 (scroll/fixed/local)

게다가 각 이미지 레이어마다 이 8개를 다르게 줄 수 있다. 단축 속성 background는 이걸 한 줄에 표현하는 도구.


How — 다중 배경의 스택

먼저 적은 게 위에 그려진다. background-color는 항상 가장 아래.

background:
  url(/icon.svg)         center / 24px no-repeat,         /* 위 */
  linear-gradient(in oklch, rgba(0,0,0,0.5), transparent), /* 중간 */
  url(/photo.jpg)        center / cover,                  /* 아래 이미지 */
  oklch(20% 0.05 254);                                    /* 최하단 색 */

What — 핵심 패턴 6가지

1) 단축 속성의 문법

/* image position / size repeat attachment origin clip color */
background:
  url(/photo.jpg) center / cover no-repeat fixed border-box border-box,
  oklch(95% 0 0);

순서가 까다로워서 개별 속성을 분리해 쓰는 편이 안전:

.hero {
  background-color: oklch(95% 0 0);
  background-image: url(/photo.jpg);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

2) background-clip: text — 그라데이션 텍스트

.gradient-heading {
  background: linear-gradient(in oklch, oklch(60% 0.2 254), oklch(70% 0.2 340));
  -webkit-background-clip: text;       /* iOS Safari 필수 */
          background-clip: text;
  color: transparent;                   /* 글자 본래 색을 비워 배경이 보이게 */
}

text-shadow로는 불가능한 그라데이션 텍스트의 사실상 유일한 방법.

주의:

  • color: transparent 필요. color: oklch(... / 0)이나 -webkit-text-fill-color: transparent도 가능.
  • 접근성: 일부 스크린리더가 transparent 텍스트를 읽지 않음. aria-label로 명시 권장.
  • forced-colors 모드 (Windows 고대비): color: transparent가 안 보일 수 있음 → @media (forced-colors: active) { color: CanvasText; -webkit-background-clip: initial; }.

3) background-attachment: fixed — 폐지된 패럴럭스

/* 한때 유행했던 패럴럭스 */
.parallax {
  background: url(/photo.jpg) center / cover;
  background-attachment: fixed;
}

모바일에서 거의 작동하지 않는다:

  • iOS Safari: fixed를 무시하고 scroll처럼 동작.
  • 데스크톱: 매 스크롤 프레임마다 전체 viewport 재합성 → 60fps 깨짐 빈번.

대체 패턴: position: sticky + transform, 또는 scroll-driven animations.

background-attachment: local스크롤 가능 컨테이너 내부에서 스크롤 따라 배경도 이동 — 모바일에서도 동작, 카드 내부 시차 효과에 가끔 쓰임.

4) background-origin vs background-clip

.card {
  border: 8px dashed oklch(70% 0 0);
  padding: 24px;
  background: url(/photo.jpg) center / cover;
  background-origin: padding-box;  /* 이미지 *위치 기준*은 padding 내부 */
  background-clip: padding-box;    /* 이미지가 *잘리는 경계*도 padding 내부 */
}
속성기본값효과
background-originpadding-box이미지의 (0,0) 기준점
background-clipborder-box배경이 보이는 영역

border-box clip + padding-box origin이 기본 — 그래서 border 영역에도 배경이 보이지만 시작은 padding부터. dashed border가 투명한 사이로 배경을 보여주는 효과는 이 조합이 만든다.

5) cover vs contain — 사진 크기

.fill { background-size: cover; }    /* 전체 영역 채움, 일부 잘림 */
.fit  { background-size: contain; }  /* 전체 보임, 여백 가능 */
.exact { background-size: 200px 100px; }
.aspect { background-size: auto 100%; }  /* 높이 100%, 비율 유지 */

<img>background-size동작 모델은 거의 동일. 다만 <img>접근성·SEO에 유리하고 background장식에 유리. 사진이라면 <img>, 패턴/그라데이션이라면 background.

6) 패턴 만들기 — repeat + size

/* 도트 패턴 */
.dots {
  background:
    radial-gradient(circle at center, oklch(80% 0 0) 1.5px, transparent 2px) 0 0 / 16px 16px;
}
 
/* 격자 */
.grid {
  background:
    linear-gradient(to right, oklch(90% 0 0) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(to bottom, oklch(90% 0 0) 1px, transparent 1px) 0 0 / 24px 24px;
}
 
/* 스트라이프 */
.stripes {
  background: repeating-linear-gradient(
    45deg,
    oklch(95% 0 0), oklch(95% 0 0) 10px,
    oklch(90% 0 0) 10px, oklch(90% 0 0) 20px
  );
}

CSS-only 패턴은 SVG 이미지보다 가볍고 zoom-friendly. 디자인 시스템의 background 토큰으로 자주.


What-if — 잘못 쓰면

1) background-clip: text 자식 색 무시

<h1 class="gradient">Hello <span style="color: red">world</span></h1>
.gradient {
  background: linear-gradient(red, blue);
  background-clip: text;
  color: transparent;
}

spancolor: red무시된다 — background-clip: text는 부모 박스의 전체 텍스트에 적용. 자식 색을 다르게 하려면 자식도 별도 background-clip 처리 필요.

2) background: red, blue — 안 됨

/* 안 됨 — background는 색을 N개 못 받음 */
background: red, blue;
 
/* 됨 — 하나의 색 + N개 이미지(그라데이션 포함) */
background: linear-gradient(red, transparent), linear-gradient(blue, transparent), white;

background-color하나뿐. 여러 색을 layer 하려면 그라데이션으로 변환해야 한다.

3) background-position: fixed의 모바일 함정

위에서 본 fixed. 2024년 현재 모바일 패럴럭스는 polyfill 없이는 동작하지 않는다. 대체:

/* sticky 패럴럭스 */
.parallax-wrapper { position: relative; overflow: hidden; height: 100vh; }
.parallax-bg {
  position: sticky; top: 0;
  background: url(/photo.jpg) center / cover;
  height: 100vh;
}

또는 scroll-driven animation (animation-timeline: scroll()) — 모던 브라우저는 GPU 가속 패럴럭스 가능 → 06-motion.

4) 이미지 로딩 가시성

.hero { background: url(/photo.jpg) center / cover; }

background-image로 로딩한 이미지는 <img loading="lazy">처럼 lazy load 안 됨. 큰 hero 이미지를 background로 넣으면 FCP·LCP 지표가 손해. content image는 항상 <img> 사용, 진짜 장식만 background.

5) background-size: cover + 작은 이미지

작은 PNG에 cover를 주면 늘려서 흐려진다. SVG로 만들거나 적절한 해상도 + image-set()으로 1x/2x/3x 분기:

background-image: image-set(
  url(/photo.jpg)   1x,
  url(/photo@2x.jpg) 2x,
  url(/photo@3x.jpg) 3x
);

6) mask와의 비교

/* background-clip: text — 텍스트 모양으로 잘림 */
.gradient-text {
  background: linear-gradient(red, blue);
  background-clip: text;
  color: transparent;
}
 
/* mask — 임의 모양으로 잘림 */
.icon {
  background: currentColor;
  mask: url(/icon.svg) center / contain no-repeat;
  -webkit-mask: url(/icon.svg) center / contain no-repeat;
}

background-clip: text텍스트 한정. 더 복잡한 모양은 mask 또는 clip-path.


Insight — 다중 배경의 출현

“CSS3까지는 한 요소 = 한 배경이었다”

CSS1·2에서는 background-image하나뿐이었다. 그래서 1990년대 디자인은 겹친 효과를 위해 div를 N개 쌓는 식이었다 — 유명한 “nested div hell”. 2009년 CSS3 Backgrounds and Borders Level 3가 다중 배경을 도입했고, 한 요소에 N개 레이어가 가능해졌다.

흥미로운 점은 background-clip: text의 표준화 과정이다. 원래 -webkit- prefix로 Safari에만 있었고 2010년대 그라데이션 텍스트 기법으로 유행했지만, 공식 CSS Backgrounds 4 명세에는 늦게(2018) 들어왔다. 2024년 현재도 모든 브라우저가 -webkit-background-clip: text를 별칭으로 지원해야 하는 이유 — 너무 일찍 사실상 표준이 되어 교과서에 prefix가 박힌 사례.

또 하나의 반전: background-attachment: fixed는 의도적으로 모바일에서 disable됐다. iOS Safari는 배터리·성능 이유fixed를 의도적으로 scroll로 다운그레이드한다. 2012년부터 Apple의 공식 문서에 명시되어 있고, 15년이 지나도 바뀌지 않는다. 패럴럭스를 만들고 싶다면 다른 길을 찾아야 한다 — sticky, transform, 또는 scroll-driven animation.


요약 + Mermaid

  • background8차원 단축 속성, 콤마로 N개 레이어.
  • 먼저 적은 게 위, background-color는 최하단.
  • background-clip: text = 그라데이션 텍스트의 유일한 길 (단, color: transparent + a11y 주의).
  • background-attachment: fixed = 모바일에서 폐지 — sticky·scroll-driven으로 대체.
  • 패턴은 gradient + repeat + size 조합으로 SVG 없이 가능.
  • Content 이미지는 <img>, 진짜 장식만 background (LCP·a11y).

다음: 07-borders-and-outlines — border-image·conic-gradient border·focus ring.