CSS 불투명도: 투명 작동 방식 및 다른 것을 사용하는 경우

불투명도는 요소와 그 안에 있는 모든 것을 하나의 그림으로 희미하게 만듭니다. 페이드와 숨겨진 캡션에는 적합하지만 투명한 배경만 원할 경우에는 잘못된 것입니다.

영문 원문 보기

CSS opacity는 0(보이지 않음)에서 1(단색)까지 요소의 투명도를 설정합니다. opacity: 0.5는 반투명하게 만듭니다. 전체 요소에 적용됩니다. 배경, 테두리, 텍스트 및 하위 요소가 함께 페이드됩니다.

배경만 흐리게 하려면 알파 값이 있는 색상을 대신 사용하세요.

슬라이더를 이동합니다. 두 카드 모두 동일한 번호를 가지며 두 가지 다른 방식으로 적용됩니다.

실행 예제직접 써 보고 코드를 복사하세요
링크로 공유하기
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>opacity vs background alpha</title>
<style>
  body {
    margin: 0; padding: 14px; box-sizing: border-box; min-height: 100vh;
    font-family: system-ui, sans-serif; color: #1d2330;
    /* a striped backdrop so you can see what shows through */
    background: repeating-linear-gradient(45deg, #2563eb 0 14px, #f59e0b 14px 28px);
  }
  .controls {
    background: #fff; border-radius: 10px; padding: 10px 12px; margin-bottom: 14px;
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 14px;
  }
  .controls input { flex: 1; min-width: 140px; }
  .row { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; }
  .card { border-radius: 12px; padding: 14px 16px; }
  .card h3 { margin: 0 0 6px; font-size: 16px; }
  .card p { margin: 0 0 8px; font-size: 14px; line-height: 1.4; }
  .card code { font-size: 13px; background: #eef1f5; padding: 1px 4px; border-radius: 4px; }

  /* A: opacity fades the whole card, text and children included */
  #a { background: #fff; opacity: var(--v); }

  /* B: only the background color is see-through; the text stays solid */
  #b { background: rgb(255 255 255 / var(--v)); }
</style>
</head>
<body style="--v: 0.5">
<div class="controls">
  <label for="v">Transparency</label>
  <input id="v" type="range" min="0" max="1" step="0.05" value="0.5">
  <output id="out">0.5</output>
</div>
<div class="row">
  <div class="card" id="a">
    <h3>opacity</h3>
    <p>The text fades with the card.</p>
    <code id="ca">opacity: 0.5</code>
  </div>
  <div class="card" id="b">
    <h3>background alpha</h3>
    <p>Only the white fill fades.</p>
    <code id="cb">rgb(255 255 255 / 0.5)</code>
  </div>
</div>

<script>
  const slider = document.getElementById('v');
  slider.addEventListener('input', () => {
    const v = slider.value;
    document.body.style.setProperty('--v', v);  // both cards read the same value
    document.getElementById('out').textContent = v;
    document.getElementById('ca').textContent = 'opacity: ' + v;
    document.getElementById('cb').textContent = 'rgb(255 255 255 / ' + v + ')';
  });
</script>
</body>
</html>
슬라이더 1개, 카드 2개. 왼쪽 카드는 불투명도를 사용하고 오른쪽 카드는 배경색에 알파 값을 사용합니다.

값: 0~1 또는 백분율

opacity는 하나의 숫자를 사용합니다. 0는 완전히 투명하고, 1는 완전히 불투명하며, 그 사이의 모든 부분은 부분적으로 투명합니다. 백분율도 작동하므로 opacity: 50%는 opacity: 0.5와 같습니다.

.faded  { opacity: 0.5; }
.ghost  { opacity: 20%; }
.solid  { opacity: 1; }   /* the default */

범위 밖의 값은 고정됩니다. 1.5는 1처럼 작동하고 -1는 0처럼 작동합니다. HTML에는 요소에 대한 opacity 속성이 없으므로 인라인으로 style="opacity: 0.5"를 작성합니다.

텍스트도 희미해지는 이유

브라우저는 요소와 모든 하위 요소를 하나의 그림으로 그린 다음 해당 그림을 페이드합니다. 이것이 카드의 제목이 흰색 채우기와 함께 투명하게 변하는 이유입니다.

불투명도는 카드 전체를 희미하게 만듭니다. 알파 색상은 텍스트 뒤의 채우기만 희미해집니다.
불투명도는 카드 전체를 희미하게 만듭니다. 알파 색상은 텍스트 뒤의 채우기만 희미해집니다.

목표가 읽을 수 있는 텍스트가 포함된 사진 위의 투명 패널인 경우 투명도를 색상으로 이동합니다.

.panel { background: rgb(255 255 255 / 0.6); }   /* same as rgba(255, 255, 255, 0.6) */
.dark  { background: hsl(220 30% 10% / 60%); }
.hex   { background: #ffffff99; }                /* last two digits are the alpha */
.mix   { background: color-mix(in srgb, white 60%, transparent); }

네 개 모두 배경만 페이드됩니다. 테두리, 텍스트 및 그림자에도 동일한 아이디어가 적용됩니다. 해당 색상에 알파 값을 지정합니다. 별도의 배경 불투명도 속성이 존재하지 않기 때문에 이는 "CSS의 배경 불투명도"에 대한 답변이기도 합니다.

불투명도: 0 대 가시성: 숨김 대 표시: 없음

세 가지 모두 요소가 보기에서 사라지도록 합니다. 그들은 남겨진 것이 다릅니다. 아래 세 개의 버튼을 숨긴 다음 해당 위치를 클릭하고 여기서 시작 버튼에서 Tab 키를 누르세요.

실행 예제직접 써 보고 코드를 복사하세요
링크로 공유하기
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>opacity: 0 vs visibility: hidden vs display: none</title>
<style>
  body { margin: 0; padding: 14px; font-family: system-ui, sans-serif; color: #1d2330; background: #f4f5f7; }
  .bar { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
  .bar button { font: inherit; font-size: 14px; padding: 8px 12px; border-radius: 8px; border: 1px solid #c9cdd4; background: #fff; cursor: pointer; }
  .row {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    background: #fff; border-radius: 10px; padding: 10px 12px; margin-bottom: 8px;
  }
  .row code { width: 150px; font-size: 13px; font-weight: 600; }
  .t { font: inherit; font-size: 14px; padding: 7px 12px; border-radius: 8px; border: 0; background: #2563eb; color: #fff; cursor: pointer; }
  .next { font-size: 13px; padding: 6px 10px; border-radius: 6px; background: #e8ebf0; }
  .status { flex-basis: 100%; font-size: 13px; color: #5b6270; min-height: 1.2em; }

  /* the three ways to hide, switched on by the "hidden" class on body */
  .hidden #op  { opacity: 0; }
  .hidden #vis { visibility: hidden; }
  .hidden #dis { display: none; }
</style>
</head>
<body>
<div class="bar">
  <button id="toggle">Hide the blue buttons</button>
  <button id="start">Start here, then press Tab</button>
</div>

<div class="row" data-name="opacity: 0"><code>opacity: 0</code><button class="t" id="op">Click me</button><span class="next">next item</span><div class="status"></div></div>
<div class="row" data-name="visibility: hidden"><code>visibility: hidden</code><button class="t" id="vis">Click me</button><span class="next">next item</span><div class="status"></div></div>
<div class="row" data-name="display: none"><code>display: none</code><button class="t" id="dis">Click me</button><span class="next">next item</span><div class="status"></div></div>

<script>
  const toggle = document.getElementById('toggle');
  toggle.addEventListener('click', () => {
    const on = document.body.classList.toggle('hidden');
    toggle.textContent = on ? 'Show the blue buttons' : 'Hide the blue buttons';
    document.querySelectorAll('.status').forEach((s) => (s.textContent = on
      ? 'Hidden. Click where the button was, or press Tab.' : ''));
  });

  document.querySelectorAll('.row').forEach((row) => {
    const status = row.querySelector('.status');
    const btn = row.querySelector('.t');
    // a click that reaches the button
    btn.addEventListener('click', (e) => {
      e.stopPropagation();
      status.textContent = 'The button got the click.';
    });
    // a click anywhere else in the row, including the empty spot
    row.addEventListener('click', () => {
      status.textContent = 'The click hit the empty row. The button did not get it.';
    });
    btn.addEventListener('focus', () => {
      status.textContent = 'Tab stopped on this button.';
    });
  });
</script>
</body>
</html>
버튼을 숨긴 다음 빈 곳을 클릭하고 Tab 키를 누르세요. 행은 클릭 또는 탭이 도달한 범위를 보고합니다.
opacity: 0 visibility: hidden display: none
공간을 유지합니다 예 예 아니요
클릭과 탭을 얻습니다 예 아니요 아니요
Tab 키가 거기서 멈춥니다. 예 아니요 아니요
스크린 리더가 도달합니다. 예 아니요 아니요
전환으로 희미해질 수 있음 예 온/오프 단계로만 사용 가능 아니요
불투명도만: 0은 페이지에 살아있는 보이지 않는 버튼을 남깁니다.
불투명도만: 0은 페이지에 살아있는 보이지 않는 버튼을 남깁니다.

페이드의 시작이나 끝을 위해 opacity: 0를 사용하세요. 공간이 유지되어야 하지만 아무것도 응답하지 않아야 하는 경우 visibility: hidden를 사용하십시오. 요소가 페이지에서 완전히 사라져야 하는 경우 display: none를 사용하세요.

전환과 함께 페이드 인 및 아웃

opacity는 두 값 사이에서 원활하게 애니메이션을 적용합니다. transition를 요소의 일반 상태에 놓고 마우스를 올리거나 클래스를 사용하여 값을 변경합니다.

.toast {
  opacity: 0;
  visibility: hidden;
  transition: opacity .3s, visibility .3s;
}
.toast.show {
  opacity: 1;
  visibility: visible;
}

visibility와 opacity를 페어링하면 클릭 문제가 해결됩니다. visibility는 한 단계로 전환되며 브라우저는 전체 전환 동안 이를 표시하므로 페이드는 여전히 양방향으로 재생됩니다. CSS 호버 전환은 전환 규칙이 이동하는 위치를 다룹니다.

불투명도는 스태킹 컨텍스트를 생성합니다.

1 아래의 모든 opacity, 심지어 0.99도 요소를 새로운 스태킹 컨텍스트로 만듭니다. 그 자식은 그들 사이에만 계층화됩니다. 자녀의 z-index: 999는 더 이상 부모 외부의 어떤 것 위로 들어올릴 수 없습니다.

부모가 불투명한 경우 자식의 Z-색인은 부모 내부에서만 계산됩니다.
부모가 불투명한 경우 자식의 Z-색인은 부모 내부에서만 계산됩니다.

페이드를 추가한 후 드롭다운이나 도구 설명이 이웃 뒤로 미끄러지는 경우가 바로 이것이 이유입니다. CSS z-index는 스태킹 컨텍스트를 전체적으로 설명합니다.

마우스를 올리면 이미지 불투명도

마우스를 올리면 사진이 어두워지는 것은 한 줄에 전환이 추가된 것입니다. 이미지 뒤의 어두운 배경은 흐린 버전을 퇴색시키는 대신 더 어둡게 만듭니다. 아래의 완성된 타일은 이미지를 낮추고 캡션을 높입니다.

실행 예제직접 써 보고 코드를 복사하세요
링크로 공유하기
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Image caption that fades in on hover</title>
<style>
  body { margin: 0; padding: 14px; font-family: system-ui, sans-serif; background: #f4f5f7; }
  .hint { margin: 0 0 10px; font-size: 14px; color: #5b6270; }
  .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }

  .tile {
    position: relative; margin: 0; border-radius: 12px; overflow: hidden;
    background: #111;  /* shows through when the image fades */
    aspect-ratio: 4 / 3;
  }
  .tile svg { display: block; width: 100%; height: 100%; transition: opacity .3s; }
  .tile figcaption {
    position: absolute; left: 0; right: 0; bottom: 0; padding: 10px 12px;
    color: #fff; font-size: 14px; line-height: 1.35;
    background: rgb(0 0 0 / .55);  /* see-through fill, solid text */
    opacity: 0;                    /* hidden, but still read by screen readers */
    transition: opacity .3s;
  }
  .tile figcaption b { display: block; font-size: 15px; }

  /* mouse over the tile, or keyboard focus on it */
  .tile:hover figcaption, .tile:focus-visible figcaption { opacity: 1; }
  .tile:hover svg, .tile:focus-visible svg { opacity: .7; }
  .tile:focus-visible { outline: 3px solid #2563eb; outline-offset: 2px; }

  /* touch screens have no hover: show the captions all the time */
  @media (hover: none) {
    .tile figcaption { opacity: 1; }
  }
  /* respect the "reduce motion" setting: switch instantly */
  @media (prefers-reduced-motion: reduce) {
    .tile svg, .tile figcaption { transition: none; }
  }
</style>
</head>
<body>
<p class="hint">Hover a picture, or press Tab to move between them.</p>
<div class="grid">
  <figure class="tile" tabindex="0">
    <svg viewBox="0 0 120 90" preserveAspectRatio="xMidYMid slice" aria-hidden="true">
      <rect width="120" height="90" fill="#7dd3fc"/><circle cx="92" cy="22" r="10" fill="#fde047"/>
      <path d="M0 90 L38 40 L62 70 L84 48 L120 90Z" fill="#166534"/>
    </svg>
    <figcaption><b>Ridge</b>Morning light over the pass.</figcaption>
  </figure>
  <figure class="tile" tabindex="0">
    <svg viewBox="0 0 120 90" preserveAspectRatio="xMidYMid slice" aria-hidden="true">
      <rect width="120" height="90" fill="#fb923c"/><circle cx="60" cy="58" r="20" fill="#fef08a"/>
      <rect y="62" width="120" height="28" fill="#1e3a8a"/>
    </svg>
    <figcaption><b>Harbour</b>Sunset from the pier.</figcaption>
  </figure>
  <figure class="tile" tabindex="0">
    <svg viewBox="0 0 120 90" preserveAspectRatio="xMidYMid slice" aria-hidden="true">
      <rect width="120" height="90" fill="#bbf7d0"/>
      <rect x="18" y="30" width="14" height="60" fill="#78350f"/><circle cx="25" cy="30" r="18" fill="#15803d"/>
      <rect x="74" y="40" width="12" height="50" fill="#78350f"/><circle cx="80" cy="40" r="15" fill="#16a34a"/>
    </svg>
    <figcaption><b>Orchard</b>Two trees, late spring.</figcaption>
  </figure>
</div>
</body>
</html>
타일이나 탭으로 마우스를 가져가세요. 캡션이 페이드 인됩니다. "모션 감소"를 선택하면 즉시 전환되며 터치 스크린에서는 항상 표시됩니다.
  • 호버 및 키보드: 동일한 규칙에는 :hover 및 :focus-visible가 나열되며 각 타일에는 tabindex="0"가 있습니다.
  • 캡션 채우기: 캡션 뒤에 rgb(0 0 0 / .55)가 있어 채우기가 투명해 보이지만 흰색 텍스트는 그대로 유지됩니다.
  • 터치 스크린: @media (hover: none)는 손가락으로 호버링할 수 없기 때문에 항상 캡션을 표시합니다.
  • 모션 감소: @media (prefers-reduced-motion: reduce)는 전환을 끕니다.

opacity: 0의 캡션은 갤러리에 적합한 스크린 리더로 여전히 읽혀집니다. 전체 그리드를 보려면 HTML 이미지 갤러리를 참조하세요.

작동하지 않을 때

당신이 보는 것 원인 수정
텍스트가 배경과 함께 희미해집니다. opacity는 요소와 모든 하위 항목을 페이드합니다. 대신 background에서 알파 색상을 사용하세요.
보이지 않는 요소가 여전히 클릭을 포착합니다. opacity: 0는 클릭 가능하고 집중 가능하도록 유지합니다. visibility: hidden 또는 pointer-events: none 추가
opacity: 1를 사용해도 아이는 계속 희미해집니다 부모는 하나의 그룹으로 페이드됩니다. 자식을 부모 밖으로 이동하거나 부모의 배경만 흐리게 합니다.
요소를 표시할 때 페이드가 재생되지 않습니다. 전환되지 않는 display: none에서 시작됩니다. opacity: 0 및 visibility: hidden로 숨기기
페이드를 추가한 후 드롭다운이 다른 콘텐츠 뒤로 슬라이드됩니다. 1 미만의 불투명도는 스태킹 컨텍스트를 생성합니다. 페이드된 상위 요소에 z-index를 배치하거나 다른 요소를 페이드합니다.

display: none 사례의 경우 최신 CSS는 @starting-style 및 transition-behavior: allow-discrete를 추가하여 애니메이션을 적용합니다. 위의 visibility 페어링은 이들 없이도 작동합니다.

링크로 공유하세요

페이드는 설명하는 것보다 보여주는 것이 더 쉽습니다. 스크린샷은 한 프레임을 포착하고 .html 첨부 파일은 전화기에서 일반 코드로 열릴 수 있습니다.

작업 버전을 보내려면 페이지를 NOS 문서에 붙여넣고 공유 링크 만들기를 선택하세요. 링크할 HTML이 이를 안내합니다. 페이지는 작성된 대로 렌더링되고 해당 스크립트가 실행되므로 페이지를 받는 사람은 슬라이더를 끌고 타일 자체를 가리킬 수 있습니다.

나중에 코드를 변경하면 동일한 링크에 새 버전이 표시됩니다.

자주 묻는 질문

CSS 불투명도는 어떤 값을 취합니까?

0~1 사이의 숫자 또는 0%~100% 사이의 백분율입니다. 0은 완전 투명, 1은 완전 불투명, 0.5 또는 50%는 절반입니다. 범위를 벗어난 값은 오류가 아닙니다. 브라우저는 이를 0 또는 1로 고정합니다.

HTML에 불투명도 속성이 있나요?

HTML 요소에는 해당되지 않습니다. 스타일시트나 인라인(예: <div style="opacity: 0.5">)에서 CSS를 사용하여 설정하세요. SVG 요소는 다릅니다. 불투명도, 채우기 불투명도 및 획 불투명도를 속성으로 허용합니다.

CSS에서 배경만 투명하게 만들려면 어떻게 해야 합니까?

불투명도를 사용하는 대신 배경색에 투명도를 넣습니다. background: rgb(255 255 255 / 0.5), rgba(255, 255, 255, 0.5), hsl(0 0% 100% / 50%) 또는 #ffffff80과 같은 8자리 16진수는 모두 텍스트가 단색으로 유지되는 동안 반투명 흰색 채우기를 제공합니다.

opacity: 0인 요소를 여전히 클릭할 수 있나요?

그렇습니다. 보이지는 않지만 여전히 레이아웃에 있고, 여전히 클릭을 받고, 여전히 키보드 포커스를 받고, 스크린 리더가 계속 접근할 수 있습니다. 포인터 이벤트 추가: 없음을 사용하여 클릭을 중지하거나 가시성: 숨김을 사용하여 클릭, 포커스 및 화면 판독기를 함께 사용하지 않습니다.

하위 요소가 상위 요소보다 더 불투명할 수 있나요?

아니요. 부모와 그 자식은 함께 칠해진 다음 하나의 그룹으로 희미해집니다. 불투명도 설정: 하위 항목에 대해 1을 지정하면 불투명도가 처음부터 상속되지 않기 때문에 추가 작업이 수행되지 않습니다. 아이는 이미 희미한 그룹 내에서 1에 있습니다.

함께 읽어 보기