WeniVooks

검색

아는 만큼 보이는 웹접근성 WCAG 2.2

가이드라인 1.1 텍스트 대안

텍스트가 아닌 모든 콘텐츠에는 그에 맞는 텍스트 설명을 제공해야 합니다. 이렇게 하면 사용자가 큰 글씨, 점자, 음성, 기호, 또는 더 쉬운 언어 등 필요한 다른 형식으로 내용을 변환할 수 있습니다.

1. 성공 기준 1.1.1 텍스트가 아닌 콘텐츠

(레벨 A)

모든 콘텐츠에는 그와 동일한 정보를 제공하는 텍스트 설명이 있어야 합니다.

<!-- 예시 1: 이미지에 대한 대체 텍스트 -->
<img src="weniv-logo.png" alt="위니브" />
 
<!-- 예시 2: 복잡한 차트나 그래프에 대한 설명 -->
<figure>
  <img src="sales-chart.png" alt="2024년 분기별 매출 차트" />
  <figcaption>
    이 차트는 2024년 각 분기별 매출을 보여줍니다. 1분기 100만원, 2분기 150만원,
    3분기 200만원, 4분기 180만원의 매출을 기록했습니다.
  </figcaption>
</figure>
<!-- 예시 1: 이미지에 대한 대체 텍스트 -->
<img src="weniv-logo.png" alt="위니브" />
 
<!-- 예시 2: 복잡한 차트나 그래프에 대한 설명 -->
<figure>
  <img src="sales-chart.png" alt="2024년 분기별 매출 차트" />
  <figcaption>
    이 차트는 2024년 각 분기별 매출을 보여줍니다. 1분기 100만원, 2분기 150만원,
    3분기 200만원, 4분기 180만원의 매출을 기록했습니다.
  </figcaption>
</figure>

단, 아래의 경우는 예외입니다.

  1. 컨트롤이나 입력을 위한 콘텐츠 (Controls, Input)

    콘텐츠가 버튼이나 입력을 받는 장치인 경우 콘텐츠를 설명하는 대체 텍스트보다는 그 기능이나 목적을 설명하는 이름이 더 중요합니다.

    <button aria-label="검색">
      <img src="search-icon.png" alt="" />
    </button>
    <button aria-label="검색">
      <img src="search-icon.png" alt="" />
    </button>
  2. 시간에 따라 변하는 미디어

    텍스트가 아닌 콘텐츠가 동영상이나 오디오처럼 시간에 따라 변하는 미디어인 경우, 콘텐츠의 전체 내용을 텍스트로 옮길 필요는 없습니다. 최소한 그 콘텐츠가 무엇인지 식별할 수 있는 설명만 제공하면 됩니다.

    미디어의 내용이 무엇인지 알 수 있게 해야 합니다. 추가로 미디어 자체에 대한 자세한 설명이 필요하면 1.2번 가이드를 참고하세요.

    <video controls>
      <source src="example-video.mp4" type="video/mp4" />
      <p>이 동영상은 새로운 제품의 기능을 설명하는 영상입니다.</p>
    </video>
    <video controls>
      <source src="example-video.mp4" type="video/mp4" />
      <p>이 동영상은 새로운 제품의 기능을 설명하는 영상입니다.</p>
    </video>
  3. 시험 또는 연습 문제

    시험이나 연습 문제의 경우, 텍스트로 내용을 자세히 설명하면 시험의 의미가 없어질 수 있습니다. 따라서 이런 경우에는 콘텐츠의 정확한 내용 대신 "이것은 수학 문제입니다" 또는 "이것은 청각 인지 테스트입니다"와 같이 해당 콘텐츠가 무엇인지 간단히 식별할 수 있는 정도의 설명만 제공합니다.

    <img src="math-problem.png" alt="수학 문제 이미지" />
    <p>이 문제는 수학 문제를 풀기 위한 시각적 정보입니다.</p>
    <img src="math-problem.png" alt="수학 문제 이미지" />
    <p>이 문제는 수학 문제를 풀기 위한 시각적 정보입니다.</p>
  4. 감각적 경험

    텍스트가 아닌 콘텐츠가 소리나 시각적 효과처럼 특정 감각을 자극하기 위한 것이라면, 간단한 설명을 제공하면 됩니다.

  5. CAPTCHA

    캡차는 보안상의 이유로 인해 해당 이미지에 대한 대체 텍스트를 그대로 제공하는 것이 아니라, 캡차의 목적이나 용도를 설명해주는 텍스트로 제공합니다. 그리고 다양한 장애를 가진 사람들도 이용할 수 있도록 다른 형태의 CAPTCHA도 제공해야 합니다.

    CAPTCHA
    • 코드 제공

      <!DOCTYPE html>
      <html lang="ko">
        <head>
          <meta charset="UTF-8" />
          <meta
            name="viewport"
            content="width=device-width, initial-scale=1.0"
          />
          <title>CAPTCHA 폼 예시</title>
          <style>
            body {
              font-family: Arial, sans-serif;
              background-color: #f0f0f0;
              display: flex;
              justify-content: center;
              align-items: center;
              height: 100vh;
              margin: 0;
            }
            .container {
              background-color: white;
              padding: 2rem;
              border-radius: 8px;
              box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
              max-width: 400px;
              width: 100%;
            }
            h2 {
              margin-top: 0;
              color: #333;
            }
            label {
              display: block;
              margin-bottom: 0.5rem;
              color: #666;
            }
            input[type='text'] {
              width: 100%;
              padding: 0.5rem;
              margin-bottom: 1rem;
              border: 1px solid #ddd;
              border-radius: 4px;
            }
            .captcha-description,
            .captcha-purpose {
              font-size: 0.9rem;
              color: #666;
              margin-bottom: 1rem;
            }
            #captcha-canvas {
              border: 1px solid #ddd;
              margin-bottom: 10px;
            }
            .button-group {
              display: flex;
              gap: 1rem;
              margin-bottom: 1rem;
            }
            button {
              flex: 1;
              padding: 0.5rem;
              border: none;
              border-radius: 4px;
              cursor: pointer;
              transition: background-color 0.3s;
            }
            button[type='button'] {
              background-color: #f0f0f0;
              color: #333;
            }
            button[type='button']:hover {
              background-color: #e0e0e0;
            }
            button[type='submit'] {
              background-color: #4caf50;
              color: white;
            }
            button[type='submit']:hover {
              background-color: #45a049;
            }
            #audio-captcha {
              width: 100%;
              margin-top: 1rem;
            }
          </style>
        </head>
        <body>
          <div class="container">
            <h2>CAPTCHA 확인</h2>
            <form onsubmit="return validateCaptcha(event)">
              <p id="captcha-purpose" class="captcha-purpose">
                이 CAPTCHA는 실제 사용자가 폼을 작성하고 있는지 확인하기 위한
                보안 절차입니다. 이는 자동화된 봇으로부터 웹사이트를 보호하고
                스팸을 방지하는 데 도움이 됩니다.
              </p>
              <p id="captcha-description" class="captcha-description">
                아래 이미지에 표시된 문자를 입력하세요. 시각 장애가 있거나
                이미지를 보기 어려운 경우, 오디오 CAPTCHA를 이용할 수 있습니다.
              </p>
              <canvas
                id="captcha-canvas"
                width="200"
                height="50"
                aria-label="시각적 CAPTCHA"
                role="img"
              ></canvas>
              <div class="button-group">
                <button
                  type="button"
                  onclick="refreshCaptcha()"
                  aria-label="새로운 시각적 CAPTCHA 생성"
                >
                  새로운 CAPTCHA 생성
                </button>
                <button
                  type="button"
                  onclick="toggleAudioCaptcha()"
                  aria-label="오디오 CAPTCHA 재생 또는 중지"
                >
                  오디오 CAPTCHA 재생 및 중지
                </button>
              </div>
              <audio id="audio-captcha" style="display: none">
                <source src="audio-captcha.mp3" type="audio/mpeg" />
                <source src="audio-captcha.ogg" type="audio/ogg" />
                오디오 CAPTCHA를 지원하지 않는 브라우저입니다.
              </audio>
              <label for="captcha">CAPTCHA 입력:</label>
              <input
                type="text"
                id="captcha"
                name="captcha"
                required
                aria-describedby="captcha-purpose captcha-description"
              />
              <button type="submit">제출</button>
            </form>
          </div>
          <script>
            let captchaText = '';
       
            function generateCaptcha() {
              const canvas = document.getElementById('captcha-canvas');
              const ctx = canvas.getContext('2d');
              ctx.clearRect(0, 0, canvas.width, canvas.height);
       
              captchaText = Math.random()
                .toString(36)
                .substring(2, 8)
                .toUpperCase();
       
              ctx.font = '30px Arial';
              ctx.fillStyle = '#333';
              ctx.fillText(captchaText, 40, 40);
       
              // 노이즈 추가
              for (let i = 0; i < 100; i++) {
                ctx.fillStyle = `rgba(${Math.random() * 255},${
                  Math.random() * 255
                },${Math.random() * 255},0.3)`;
                ctx.fillRect(
                  Math.random() * canvas.width,
                  Math.random() * canvas.height,
                  2,
                  2,
                );
              }
            }
       
            function refreshCaptcha() {
              generateCaptcha();
            }
       
            function toggleAudioCaptcha() {
              const audio = document.getElementById('audio-captcha');
              if (audio.paused) {
                audio.style.display = 'block';
                audio.play();
              } else {
                audio.pause();
                audio.currentTime = 0;
              }
            }
       
            function validateCaptcha(event) {
              event.preventDefault();
              const input = document.getElementById('captcha').value;
              if (input.toUpperCase() === captchaText) {
                alert('CAPTCHA 확인 성공!');
                refreshCaptcha();
                document.getElementById('captcha').value = '';
              } else {
                alert('CAPTCHA가 일치하지 않습니다. 다시 시도해주세요.');
              }
            }
       
            // 초기 CAPTCHA 생성
            generateCaptcha();
          </script>
        </body>
      </html>
      <!DOCTYPE html>
      <html lang="ko">
        <head>
          <meta charset="UTF-8" />
          <meta
            name="viewport"
            content="width=device-width, initial-scale=1.0"
          />
          <title>CAPTCHA 폼 예시</title>
          <style>
            body {
              font-family: Arial, sans-serif;
              background-color: #f0f0f0;
              display: flex;
              justify-content: center;
              align-items: center;
              height: 100vh;
              margin: 0;
            }
            .container {
              background-color: white;
              padding: 2rem;
              border-radius: 8px;
              box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
              max-width: 400px;
              width: 100%;
            }
            h2 {
              margin-top: 0;
              color: #333;
            }
            label {
              display: block;
              margin-bottom: 0.5rem;
              color: #666;
            }
            input[type='text'] {
              width: 100%;
              padding: 0.5rem;
              margin-bottom: 1rem;
              border: 1px solid #ddd;
              border-radius: 4px;
            }
            .captcha-description,
            .captcha-purpose {
              font-size: 0.9rem;
              color: #666;
              margin-bottom: 1rem;
            }
            #captcha-canvas {
              border: 1px solid #ddd;
              margin-bottom: 10px;
            }
            .button-group {
              display: flex;
              gap: 1rem;
              margin-bottom: 1rem;
            }
            button {
              flex: 1;
              padding: 0.5rem;
              border: none;
              border-radius: 4px;
              cursor: pointer;
              transition: background-color 0.3s;
            }
            button[type='button'] {
              background-color: #f0f0f0;
              color: #333;
            }
            button[type='button']:hover {
              background-color: #e0e0e0;
            }
            button[type='submit'] {
              background-color: #4caf50;
              color: white;
            }
            button[type='submit']:hover {
              background-color: #45a049;
            }
            #audio-captcha {
              width: 100%;
              margin-top: 1rem;
            }
          </style>
        </head>
        <body>
          <div class="container">
            <h2>CAPTCHA 확인</h2>
            <form onsubmit="return validateCaptcha(event)">
              <p id="captcha-purpose" class="captcha-purpose">
                이 CAPTCHA는 실제 사용자가 폼을 작성하고 있는지 확인하기 위한
                보안 절차입니다. 이는 자동화된 봇으로부터 웹사이트를 보호하고
                스팸을 방지하는 데 도움이 됩니다.
              </p>
              <p id="captcha-description" class="captcha-description">
                아래 이미지에 표시된 문자를 입력하세요. 시각 장애가 있거나
                이미지를 보기 어려운 경우, 오디오 CAPTCHA를 이용할 수 있습니다.
              </p>
              <canvas
                id="captcha-canvas"
                width="200"
                height="50"
                aria-label="시각적 CAPTCHA"
                role="img"
              ></canvas>
              <div class="button-group">
                <button
                  type="button"
                  onclick="refreshCaptcha()"
                  aria-label="새로운 시각적 CAPTCHA 생성"
                >
                  새로운 CAPTCHA 생성
                </button>
                <button
                  type="button"
                  onclick="toggleAudioCaptcha()"
                  aria-label="오디오 CAPTCHA 재생 또는 중지"
                >
                  오디오 CAPTCHA 재생 및 중지
                </button>
              </div>
              <audio id="audio-captcha" style="display: none">
                <source src="audio-captcha.mp3" type="audio/mpeg" />
                <source src="audio-captcha.ogg" type="audio/ogg" />
                오디오 CAPTCHA를 지원하지 않는 브라우저입니다.
              </audio>
              <label for="captcha">CAPTCHA 입력:</label>
              <input
                type="text"
                id="captcha"
                name="captcha"
                required
                aria-describedby="captcha-purpose captcha-description"
              />
              <button type="submit">제출</button>
            </form>
          </div>
          <script>
            let captchaText = '';
       
            function generateCaptcha() {
              const canvas = document.getElementById('captcha-canvas');
              const ctx = canvas.getContext('2d');
              ctx.clearRect(0, 0, canvas.width, canvas.height);
       
              captchaText = Math.random()
                .toString(36)
                .substring(2, 8)
                .toUpperCase();
       
              ctx.font = '30px Arial';
              ctx.fillStyle = '#333';
              ctx.fillText(captchaText, 40, 40);
       
              // 노이즈 추가
              for (let i = 0; i < 100; i++) {
                ctx.fillStyle = `rgba(${Math.random() * 255},${
                  Math.random() * 255
                },${Math.random() * 255},0.3)`;
                ctx.fillRect(
                  Math.random() * canvas.width,
                  Math.random() * canvas.height,
                  2,
                  2,
                );
              }
            }
       
            function refreshCaptcha() {
              generateCaptcha();
            }
       
            function toggleAudioCaptcha() {
              const audio = document.getElementById('audio-captcha');
              if (audio.paused) {
                audio.style.display = 'block';
                audio.play();
              } else {
                audio.pause();
                audio.currentTime = 0;
              }
            }
       
            function validateCaptcha(event) {
              event.preventDefault();
              const input = document.getElementById('captcha').value;
              if (input.toUpperCase() === captchaText) {
                alert('CAPTCHA 확인 성공!');
                refreshCaptcha();
                document.getElementById('captcha').value = '';
              } else {
                alert('CAPTCHA가 일치하지 않습니다. 다시 시도해주세요.');
              }
            }
       
            // 초기 CAPTCHA 생성
            generateCaptcha();
          </script>
        </body>
      </html>
  6. 장식, 서식, 보이지 않는 콘텐츠

    텍스트가 아닌 콘텐츠가 단순 장식이거나 화면 서식에만 사용되거나 사용자에게 보이지 않는 경우, 보조 기술이 이를 무시할 수 있도록 설정해야 합니다. 아래 코드는 alt 속성은 비워져 있고, role="presentation"을 사용하여 보조 기술이 이 이미지를 무시할 수 있도록 설정되었습니다.

    <img src="decorative-line.png" alt="" role="presentation" />
    <img src="decorative-line.png" alt="" role="presentation" />

    role="presentation" 속성은 HTML 요소가 순수하게 장식적인 목적으로 사용되며 의미적인 내용을 포함하지 않음을 나타냅니다

2.1 인식 가능성 Perceivable 이란?2.3 가이드라인 1.2 시간 기반 미디어