Advanced styling effects

김동현·2026년 3월 18일

mdn 학습 번역 - CSS

목록 보기
15/190

안녕하세요! CSS 기초의 마지막을 장식할 고급 스타일링 효과(Advanced styling effects) 레슨에 오신 것을 환영합니다.

지금까지 배운 CSS 지식만으로도 훌륭한 웹사이트를 만들 수 있지만, 가끔은 디자인에 조금 더 '마법' 같은 효과를 불어넣고 싶을 때가 있죠. 박스에 그림자를 넣거나, 이미지에 포토샵 같은 필터를 씌우거나, 텍스트 모양대로 배경 이미지를 오려내는 등 시각적으로 즐거운 기법들을 배울 차례입니다. 실무에서도 은근히 자주 쓰이는 유용한 스킬들이니 재밌게 즐겨보세요!


고급 스타일링 효과 (Advanced styling effects)

이전 페이지 (Test your skills: Box model) | 개요: CSS 스타일링 기초

이 글은 여러 가지 흥미로운 고급 스타일링 기능들을 소개하는 일종의 '마술 상자' 같은 역할을 합니다. 박스 그림자(box shadows), 혼합 모드(blend modes), 필터(filters) 등에 대해 알아볼 것입니다.

사전 준비 지식:HTML 기초 지식 (HTML 소개 학습 권장)과 CSS 작동 방식에 대한 이해 (CSS 스타일링 기초 학습 권장).
학습 목표:
  • 최신 브라우저에서 사용할 수 있는 고급 스타일링 효과들을 어떻게 사용하는지 감 잡기.

박스 그림자 (Box shadows)

box-shadow 속성을 사용하면 요소의 상자(box)에 하나 이상의 그림자를 적용할 수 있습니다. 텍스트 그림자(text-shadow)와 마찬가지로 박스 그림자는 IE9+ 및 Edge를 포함하여 거의 모든 브라우저에서 아주 잘 지원됩니다. 구형 IE 버전을 사용하는 사용자들은 그림자 효과를 볼 수 없겠지만, 그림자가 없어도 콘텐츠를 읽고 사용하는 데 문제가 없도록(우아한 저하, Graceful degradation) 디자인을 잘 확인하기만 하면 됩니다.

간단한 박스 그림자 (A simple box shadow)

가장 간단한 예제로 시작해 볼까요? 먼저 HTML을 준비합니다.

<article class="simple">
  <p>
    <strong>Warning</strong>: The thermostat on the cosmic transcender has
    reached a critical level.
  </p>
</article>

이제 CSS를 추가합니다.

p {
  margin: 0;
}

article {
  max-width: 500px;
  padding: 10px;
  background-color: red;
  background-image: linear-gradient(to bottom, transparent, rgb(0 0 0 / 25%));
}

.simple {
  box-shadow: 5px 5px 5px rgb(0 0 0 / 70%);
}

이 코드를 적용하면 아래와 같은 결과가 나옵니다.

box-shadow 속성값 안에 4개의 항목이 들어있는 것을 볼 수 있습니다. 순서대로 설명해 드릴게요.

  1. 첫 번째 길이 값은 가로(수평) 오프셋(horizontal offset)입니다. 양수이면 그림자가 원래 상자에서 오른쪽으로 밀려나고, 음수이면 왼쪽으로 밀려납니다.
  2. 두 번째 길이 값은 세로(수직) 오프셋(vertical offset)입니다. 양수이면 그림자가 아래쪽으로 내려가고, 음수이면 위쪽으로 올라갑니다.
  3. 세 번째 길이 값은 흐림 반경(blur radius)입니다. 그림자가 얼마나 뿌옇게(흐리게) 번질지 그 양을 결정합니다. 값이 클수록 더 부드럽고 넓게 퍼지는 그림자가 됩니다.
  4. 마지막 색상 값은 그림자의 기본 색상(base color)입니다. 보통 rgbargb(... / ...)를 사용하여 반투명한 검은색을 많이 사용합니다.

이 값들을 정의할 때 상황에 맞는 적절한 길이 단위(px, rem 등)와 색상 단위를 자유롭게 사용할 수 있습니다.

💡 강사의 실무 팁!
"입체감 넘치는 깔끔한 그림자"를 만들고 싶다면 흐림 반경(3번째 값)을 오프셋(1, 2번째 값)보다 2배 정도 크게 줘보세요. box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.1); 처럼 투명도를 확 낮추면 요즘 유행하는 모던하고 부드러운 UI 느낌을 낼 수 있답니다!

여러 겹의 박스 그림자 (Multiple box shadows)

하나의 box-shadow 선언 안에 여러 개의 그림자를 겹쳐서 적용할 수도 있습니다. 각 그림자의 설정값을 쉼표(,)로 구분해서 적어주기만 하면 됩니다.

.multiple {
  box-shadow:
    1px 1px 1px black,
    2px 2px 1px black,
    3px 3px 1px red,
    4px 4px 1px red,
    5px 5px 1px black,
    6px 6px 1px black;
}

이 코드를 적용하면 다음과 같은 결과가 나옵니다. 겹겹이 쌓인 그림자 효과를 볼 수 있죠!

우리는 여기서 여러 가지 색상의 레이어를 겹쳐서 입체적인 박스를 만드는 재밌는 효과를 연출해 보았습니다. 하지만 이 기법을 사용하면 다중 광원(여러 개의 조명)이 비추는 것 같은 매우 현실적인 그림자를 표현하는 등 원하는 어떤 방식으로든 다양하게 응용할 수 있습니다.

기타 박스 그림자 기능 (Other box shadow features)

text-shadow와 달리, box-shadow에는 inset이라는 특별한 키워드를 사용할 수 있습니다. 이 키워드를 그림자 선언 맨 앞에 붙이면, 그림자가 상자 바깥으로 퍼지는 대신 상자 안쪽으로(inner shadow) 드리워지게 됩니다. 어떻게 작동하는지 한번 볼까요?

이번에는 다음과 같은 간단한 HTML을 사용합니다.

<button>Press me!</button>

그리고 다음 CSS를 적용해 봅니다.

button {
  width: 150px;
  font-size: 1.1rem;
  line-height: 2;
  border-radius: 10px;
  border: none;
  background-image: linear-gradient(to bottom right, #777777, #dddddd);
  box-shadow:
    1px 1px 1px black,
    inset 2px 3px 5px rgb(0 0 0 / 30%),
    inset -2px -3px 5px rgb(255 255 255 / 50%);
}

button:focus,
button:hover {
  background-image: linear-gradient(to bottom right, #888888, #eeeeee);
}

button:active {
  box-shadow:
    inset 2px 2px 1px black,
    inset 2px 3px 5px rgb(0 0 0 / 30%),
    inset -2px -3px 5px rgb(255 255 255 / 50%);
}

이 코드를 적용하면 이렇게 꽤 그럴싸한 버튼이 만들어집니다. 마우스로 클릭해 보세요!

우리는 버튼 스타일과 함께 focus, hover, active(클릭되는 순간) 상태를 설정했습니다. 버튼의 기본 상태에는 평범한 검은색 바깥 그림자 하나와, 밝은색/어두운색의 안쪽(inset) 그림자 두 개를 서로 반대쪽 모서리에 배치해서 볼록하게 튀어나온 듯한 음영 효과를 주었습니다.

버튼을 누르는 순간(active 상태), 첫 번째 바깥쪽 그림자(1px 1px 1px black)를 아주 어두운 안쪽 그림자(inset 2px 2px 1px black)로 쓱 바꿔버렸습니다. 그 결과 버튼이 실제로 꾹 눌려 들어가는 듯한 멋진 시각적 효과를 연출하게 된 것이죠!

📝 참고사항 (Note):
box-shadow 값에 설정할 수 있는 항목이 하나 더 있습니다. 바로 색상 값 직전에 선택적으로 넣을 수 있는 확산 반경(spread radius)입니다. (오프셋 2개, 흐림 반경 1개 다음에 나오는 4번째 숫자 값입니다.) 이 값을 양수로 주면 그림자 자체가 원래 박스보다 더 크고 넓게 퍼져 나가고, 음수로 주면 그림자가 원래 상자보다 쪼그라듭니다. 아주 자주 쓰이지는 않지만 알아두면 유용합니다.


필터 (Filters)

CSS만으로 이미지의 구도 자체를 바꿀 수는 없지만, 꽤 창의적인 시각적 조작은 가능합니다. 디자인에 흥미로움을 더해줄 수 있는 아주 멋진 속성이 바로 filter 속성입니다. 이 속성을 사용하면 브라우저 안에서, CSS 코드만으로 포토샵 스타일의 이미지 필터를 바로 적용할 수 있습니다.

아래 예제에서는 두 가지 다른 필터 값을 사용해 보았습니다. 첫 번째 이미지는 blur() 필터를 적용했습니다. 이 함수 안에 픽셀(px) 값을 전달해서 이미지를 얼마나 뿌옇게 흐릴지 정할 수 있습니다.

두 번째 이미지는 grayscale()(흑백) 필터를 적용했습니다. 백분율(%) 값을 사용해서 이미지에서 색상을 어느 정도 빼낼지 설정할 수 있죠. (100%면 완전한 흑백이 됩니다.)

<div class="wrapper">
  <div class="box">
    <img
      alt="balloons"
      class="blur"
      src="[https://mdn.github.io/shared-assets/images/examples/balloons.jpg](https://mdn.github.io/shared-assets/images/examples/balloons.jpg)" />
  </div>
  <div class="box">
    <img
      alt="balloons"
      class="grayscale"
      src="[https://mdn.github.io/shared-assets/images/examples/balloons.jpg](https://mdn.github.io/shared-assets/images/examples/balloons.jpg)" />
  </div>
</div>
img {
  height: 100%;
  width: 100%;
  display: block;
  object-fit: cover;
}

.blur {
  filter: blur(10px);
}

.grayscale {
  filter: grayscale(60%);
}

위 코드에서 백분율과 픽셀 값을 이리저리 바꿔보면서 이미지가 어떻게 변하는지 확인해 보세요. 아예 다른 함수로 바꿔볼 수도 있습니다. contrast(200%)(대비 2배 증가), invert(100%)(색상 반전), hue-rotate(20deg)(색조 20도 회전) 같은 값들을 넣어보세요. 시도해 볼 수 있는 훨씬 더 다양한 옵션들이 궁금하다면 MDN의 filter 페이지를 확인해 보시기 바랍니다.

💡 강사의 실무 팁!
filter 속성은 이미지(img) 태그에만 쓸 수 있는 게 아닙니다! 어떤 HTML 요소(div, p, button 등)에든 적용할 수 있어요.
예를 들어 다른 요소가 사용 가능한 box-shadowtext-shadow와 매우 비슷한 역할을 하는 drop-shadow() 필터도 있습니다. 이 둘의 결정적인 차이점을 아는 것이 중요합니다.

  • box-shadow는 그저 박스의 네모난 외곽선(또는 border-radius를 준 둥근 선)을 따라 무식하게 그림자를 칠합니다. 투명한 배경을 가진 PNG 이미지나 테두리가 점선(dashed)인 박스에 적용하면, 내용물이 투명해도 그냥 전체를 네모나게 덮는 그림자가 생기죠.
  • 반면에 filter: drop-shadow()는 박스 안의 실제 불투명한 픽셀 형태(글자, 투명한 배경이 뚫린 이미지, 점선 테두리의 선 자체 등)를 인식해서 그 모양 그대로 그림자를 똑똑하게 그려줍니다!

아래 예제에서 필터(drop-shadow)를 적용한 요소와 박스 그림자(box-shadow)를 적용한 요소를 비교해 보겠습니다. 드롭 섀도 필터는 텍스트 글자의 형태와 점선 테두리(dashes)의 모양을 그대로 따라가며 그림자가 그려졌지만, 박스 그림자는 그저 요소의 사각형 외곽을 따라 투박하게 그려진 것을 볼 수 있습니다.

<p class="filter">Filter</p>
<p class="box-shadow">Box shadow</p>
body {
  font-family: sans-serif;
}
p {
  margin: 1em 2em;
  padding: 20px;
  width: 100px;
  display: inline-block;
  border: 5px dashed red;
}

.filter {
  filter: drop-shadow(5px 5px 1px rgb(0 0 0 / 70%));
}

.box-shadow {
  box-shadow: 5px 5px 1px rgb(0 0 0 / 70%);
}

[Image comparing CSS box-shadow vs filter drop-shadow behavior on transparent elements]


혼합 모드 (Blend modes)

CSS 혼합 모드(Blend modes)를 사용하면 두 요소가 겹칠 때 그 요소들을 어떻게 섞어서 보여줄지 혼합 효과를 지정할 수 있습니다. 겹쳐진 영역의 최종 픽셀 색상은 위쪽 레이어 픽셀의 색상과 그 아래쪽 레이어 픽셀의 색상을 수학적으로 조합한 결과가 됩니다. 혼합 모드 역시 포토샵 같은 그래픽 작업 프로그램 사용자들에게는 매우 친숙한 기능이죠! (Multiply, Screen, Overlay 같은 것들 말입니다.)

CSS에서 혼합 모드를 사용하는 속성은 두 가지가 있습니다.

  • background-blend-mode: 단일 요소에 설정된 여러 개의 배경 이미지와 배경 색상(background-color)을 서로 혼합합니다.
  • mix-blend-mode: 이 속성이 적용된 요소 전체(배경, 콘텐츠 모두 포함)를 그 요소 아래에 겹쳐진 다른 요소들과 혼합합니다.

background-blend-mode

이번에도 예제를 보면서 이해해 봅시다. 먼저 background-blend-mode입니다. 간단한 <div> 두 개를 나란히 두고, 혼합 전 원본과 혼합 후의 모습을 비교해 보겠습니다.

<div></div>
<div class="multiply"></div>

이제 CSS를 작성합니다. <div>에 배경 이미지 하나를 깔고, 동시에 초록색 배경색(green)도 넣어줍니다.

div {
  width: 250px;
  height: 130px;
  padding: 10px;
  margin: 10px;
  display: inline-block;
  background: url("colorful-heart.png") no-repeat center 20px;
  background-color: green;
}

.multiply {
  background-blend-mode: multiply;
}

결과는 다음과 같습니다. 왼쪽이 혼합 전 원본이고, 오른쪽이 multiply(곱하기) 혼합 모드를 적용한 결과입니다. 하트 이미지와 초록색 배경색이 자연스럽게 섞인 것을 볼 수 있습니다.

mix-blend-mode

이제 mix-blend-mode를 살펴보겠습니다. 똑같은 두 개의 <div>(하트 이미지가 있는)를 준비했는데, 이번에는 그 아래에 보라색(purple) 배경을 가진 단순한 <div>를 깔아두었습니다. 위쪽 요소와 아래쪽 요소가 어떻게 혼합되는지 보여드리기 위해서죠.

<article>
  No mix blend mode
  <div class="multiply-mix"></div>
  <div></div>
</article>

<article>
  Multiply mix
  <div class="multiply-mix"></div>
  <div></div>
</article>

CSS는 다음과 같습니다. 첫 번째 div(하트)를 두 번째 div(보라색 배경) 위로 겹치게 포지셔닝(Position)했습니다.

article {
  width: 280px;
  height: 180px;
  margin: 10px;
  position: relative;
  display: inline-block;
}

div {
  width: 250px;
  height: 130px;
  padding: 10px;
  margin: 10px;
}

article div:first-child {
  position: absolute;
  top: 10px;
  left: 0;
  background: url("colorful-heart.png") no-repeat center 20px;
  background-color: green;
}

article div:last-child {
  background-color: purple;
  position: absolute;
  bottom: -10px;
  right: 0;
  z-index: -1;
}

.multiply-mix {
  mix-blend-mode: multiply;
}

결과는 이렇게 나옵니다! 오른쪽 예제를 보세요. mix-blend-mode: multiply는 자신의 배경 이미지와 배경색을 섞을 뿐만 아니라, 자기보다 아래에 깔려 있는 보라색

의 색상까지 통째로 섞어버린 것을 확인할 수 있습니다.

📝 참고사항 (Note):
위 코드에서 사용된 position, top, bottom, z-index 같은 레이아웃 속성들을 당장 이해하지 못해도 걱정하지 마세요. 이 내용들은 CSS 레이아웃(CSS Layout) 모듈에서 아주 상세하게 다룰 예정입니다!


CSS 도형 (CSS shapes)

CSS의 모든 요소가 네모 반듯한 상자(box)이고 물리적인 이미지 파일들도 다 네모나지만, CSS Shapes를 사용하면 텍스트(콘텐츠)가 네모가 아닌 다른 모양을 따라 흐르도록 만들 수 있습니다.

CSS Shapes 스펙은 텍스트가 네모 반듯하지 않은 모양을 감싸며 흐르게(wrapping) 해줍니다. 특히 이미지 주변에 빈 여백(white-space)이 많고, 그 여백을 따라 텍스트가 둥글게 흘러가게 만들고 싶을 때 매우 유용합니다.

아래 이미지를 보면 기분 좋은 동그란 풍선 그림이 있습니다. 이 이미지 파일 자체는 사실 네모난 형태입니다. 하지만 이미지를 float시키고(CSS Shape은 float된 요소에만 적용됩니다!) shape-outside 속성의 값으로 circle(50%)를 주면, 텍스트가 풍선의 둥근 테두리 선을 따라 자연스럽게 구불구불 흘러내려가는 효과를 낼 수 있습니다.

<div class="wrapper">
  <img
    alt="balloon"
    src="[https://mdn.github.io/shared-assets/images/examples/round-balloon.png](https://mdn.github.io/shared-assets/images/examples/round-balloon.png)" />
  <p>
    One November night in the year 1782, so the story runs, two brothers sat
    over their winter fire in the little French town of Annonay, watching the
    grey smoke-wreaths from the hearth curl up the wide chimney. Their names
    were Stephen and Joseph Montgolfier, they were papermakers by trade... (생략)
  </p>
</div>
body {
  font-family: sans-serif;
}
img {
  float: left;
  shape-outside: circle(50%);
}

이 예제에서 모양(shape)은 원본 이미지 파일 안의 내용물(풍선)을 스스로 인식해서 반응한 것이 아닙니다. circle() 함수가 이미지 파일 정중앙에 컴퍼스 핀을 꽂고 이미지 안에 쏙 들어가는 완벽한 동그라미를 가상으로 그렸을 뿐입니다. 텍스트는 그 가상의 동그라미를 따라 흘러간 것이죠.

📝 참고사항 (Note):
Firefox 브라우저를 쓰신다면 개발자 도구(DevTools)의 Shapes Inspector를 사용해서 이렇게 만들어진 가상의 Shape 모양을 시각적으로 확인하고 수정해 볼 수 있습니다.

circle() 함수는 사용할 수 있는 여러 기본 도형 중 하나일 뿐이며, 다각형(polygon)을 그리는 등 훨씬 더 복잡한 모양을 그리는 다양한 방법들이 존재합니다.


-webkit-background-clip: text

마지막으로 가볍게 소개해 드릴 기능은 background-clip 속성의 text 값입니다. 이건 정식 표준은 아니지만, 개발자들 사이에서 워낙 인기가 많고 널리 쓰이다 보니 대부분의 브라우저가 지원하게 된 약간 변칙적인 기능입니다.

이 기능을 비표준 속성인 -webkit-text-fill-color: transparent;와 짝꿍으로 함께 사용하면, 배경 이미지를 글자 모양 그대로 오려낼 수 있습니다! 정말 화려하고 예쁜 타이포그래피 효과를 낼 수 있죠. 이 조합을 쓸 때는 Chrome 계열 브라우저가 아니더라도 반드시 -webkit-이라는 벤더 프리픽스(vendor prefix, 브라우저 제조사 접두사)를 붙여주어야 제대로 동작합니다.

아래 라이브 예제에서 어떻게 작동하는지 직접 확인해 보세요.

<h2>WOW</h2>
<h2 class="text-clip">WOW</h2>
body {
  font-family: "impact", sans-serif;
}

h2 {
  width: 250px;
  height: 250px;
  text-align: center;
  line-height: 250px;
  font-size: 50px;
}

h2 {
  color: white;
  display: inline-block;
  background: url("colorful-heart.png") no-repeat center;
}

.text-clip {
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

그런데 왜 크롬도 아닌 다른 브라우저들(Firefox, Safari 등)까지 굳이 -webkit- 프리픽스가 붙은 코드를 지원하게 된 걸까요? 브라우저 호환성 때문입니다. 너무나 많은 웹 개발자들이 이 기능을 쓰면서 코드에 -webkit- 프리픽스만 달아놓다 보니, 다른 브라우저로 그 사이트를 열면 스타일이 다 깨져서 마치 브라우저가 고장 난 것처럼 보였던 겁니다(실제로는 표준을 안 지킨 개발자 탓인데 말이죠). 결국 어쩔 수 없이 다른 브라우저들도 이 비표준 코드를 강제로 지원하게 되었습니다.

💡 강사의 실무 팁!
비표준 기능이나 프리픽스가 필요한 기능을 실무에 적용할 때는 항상 폴백(Fallback, 대체 수단)을 마련해 두는 습관을 들여야 합니다. 만약 이 배경 오려내기 기능이 지원되지 않는 구형 브라우저에서 글자 색상을 transparent(투명)로 줘버렸다면, 사용자는 글자를 아예 읽을 수 없게 되겠죠! 항상 모든 환경을 고려하는 멋진 개발자가 되시길 바랍니다!


요약 (Summary)

이번 글이 꽤 재미있으셨길 바랍니다! 반짝거리고 예쁜 마법 같은 장난감(?)들을 가지고 노는 건 언제나 즐겁잖아요. 최신 모던 브라우저들이 점점 더 강력하고 흥미로운 스타일링 도구들을 제공하고 있다는 사실도 알게 되셨을 겁니다.

지금까지 배운 내용들을 바탕으로, 나중에 여러분만의 멋진 웹 포트폴리오를 디자인할 때 이 기법들을 마음껏 활용해 보세요!

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

0개의 댓글