접근성 고려사항

CMS 기반 웹사이트의 접근성은 콘텐츠를 적절하게 모델링하고, 접근성 있는 템플릿 생성, 그리고 가독성과 접근성 가이드라인을 염두에 둔 접근성 있는 콘텐츠 작성의 문제입니다.

Wagtail은 일반적으로 개발자가 콘텐츠 모델링과 프론트엔드 마크업을 제어할 수 있게 하지만, 그럼에도 불구하고 알아야 할 몇 가지 영역이 있으며, 작성자가 가독성 모범 사례를 인식하도록 돕는 방법이 있습니다. 여기서 다루는 것보다 접근성 있는 웹사이트를 구축하는 데 더 많은 내용이 있습니다 - 자세한 정보는 접근성 리소스 목록을 참조하세요.

콘텐츠 모델링

사이트의 모델을 정의하는 과정에서 특별히 주의해야 할 영역은 다음과 같습니다:

이미지의 대체 텍스트

이미지가 사용되는 모든 곳에서, 콘텐츠 편집자는 이미지를 장식용으로 표시하거나 상황에 맞는 텍스트 대안을 제공할 수 있어야 합니다. 리치 텍스트 편집기의 이미지 임베드는 이 기능을 지원합니다. Wagtail 6.3에서는 StreamField 내 이미지를 위해 이 기능을 제공하는 ImageBlock이 추가되었습니다.

Wagtail 6.3은 또한 Wagtail 이미지 모델과 wagtail.images.models.AbstractImage 를 상속하는 사용자 정의 이미지 모델에 선택적 description 필드를 추가했습니다. 이 필드의 텍스트는 리치 텍스트나 ImageBlock에서 이미지를 삽입할 때 기본 대체 텍스트로 제공됩니다. description 필드가 비어 있으면 대신 title 필드가 사용됩니다. 이 동작을 사용자 정의하려면 이미지 모델에서 default_alt_text 속성을 재정의하세요.

참고

중요한 고려사항

  • 대체 텍스트는 이미지가 표시되는 컨텍스트를 기반으로 작성되어야 합니다.

  • 대체 텍스트 필드를 지정할 때, 편집자가 장식용 이미지에 대체 텍스트를 작성하지 않도록 선택할 수 있게 필드를 선택적으로 만드세요. 이미지는 경우에 따라 장식용일 수도 있고 아닐 수도 있습니다. 예를 들어, 페이지 목록의 썸네일은 종종 장식용으로 간주될 수 있습니다.

  • 대체 텍스트의 내용이 이미 페이지의 다른 부분에 있다면, 이상적으로는 이미지가 동일한 내용을 반복하지 않아야 합니다.

  • 적절한 지침으로 help_text 를 제공하는 데 시간을 투자하세요. 예를 들어, 대체 텍스트에 관한 확립된 리소스에 링크하는 것이 좋습니다.

임베드 제목

누락된 임베드 제목은 Wagtail 웹사이트의 접근성 감사에서 흔히 발견되는 실패 사례입니다. 일부 경우에는 Wagtail 임베드의 iframe에 title 속성이 설정되지 않습니다. 이는 종종 OEmbed 제공자의 문제입니다. 이는 스크린 리더 사용자에게 매우 문제가 됩니다. 그들은 임베드가 무엇인지, 그리고 상호 작용해야 하는지 여부를 이해하기 위해 제목에 의존합니다.

웹사이트가 제목이 누락된 임베드에 의존하는 경우, 다음 중 하나를 수행하세요:

  • OEmbed title 필드를 iframetitle 로 추가합니다.

  • 임베드에 사용자 정의 필수 제목 필드를 추가하고, 이를 iframetitle 로 추가합니다.

사용 가능한 제목 수준

Wagtail은 개발자가 리치 텍스트 기능이나 사용자 정의 StreamField 블록을 통해 특정 콘텐츠에 사용할 수 있는 제목 수준을 쉽게 제어할 수 있게 합니다. 두 경우 모두, 페이지의 문서 개요가 논리적이고 순차적일 가능성이 높도록 사용 가능한 제목 수준을 제한하는 데 시간을 투자하세요. 다음과 같은 제한 사항을 고려하세요:

  • 리치 텍스트에서 h1 을 허용하지 마세요. 페이지당 하나의 h1 태그만 있어야 하며, 일반적으로 페이지의 title 에 매핑됩니다.

  • 페이지 주요 콘텐츠의 제목 수준을 h2 로 제한하세요. 필요하다고 판단되는 경우에만 h3 을 추가하세요. 일반적으로 다른 수준은 피하세요.

  • 페이지의 특정 섹션에 표시되는 콘텐츠의 경우, 제목 수준을 섹션의 주요 제목 바로 아래 수준으로 제한하세요.

StreamField를 통해 제목을 관리하는 경우, 동일한 제한 사항을 적용하세요.

리치 텍스트의 굵게 및 기울임꼴 서식

기본적으로 Wagtail은 굵은 서식을 b 태그로, 기울임꼴을 i 로 저장합니다(#4665). 이러한 태그가 항상 올바른 의미를 갖지는 않지만(strongem 이 더 보편적임), 스크린 리더는 기본적으로 강조에 따라 콘텐츠를 다르게 발표하지 않기 때문에 스크린 리더 사용자에게 큰 영향은 없습니다.

이것이 걱정된다면, 리치 텍스트 형식 변환기를 사용하여 콘텐츠 저장 시 사용되는 태그를 변경할 수 있습니다. 미래에는 리치 텍스트 재작성 핸들러가 저장 형식을 변경하지 않고도 이를 지원할 것입니다(#4223).

TableBlock

스크린 리더는 행과 열 헤더를 사용하여 각 테이블 셀의 컨텍스트를 발표합니다. 편집자가 테이블에 적합한 행 헤더 및/또는 열 헤더를 설정하도록 권장하세요.

항상 캡션을 추가하여 스크린 리더 사용자가 사이트의 테이블을 탐색할 때 테이블 내용이 읽히기 전에 개요를 얻을 수 있도록 하세요.

템플릿의 접근성

사이트의 템플릿을 최대한 접근성 있게 만들기 위해 알아야 할 일반적인 함정은 다음과 같습니다.

템플릿의 대체 텍스트

위의 콘텐츠 모델링 섹션을 참조하세요. 또한, 이미지의 대체 텍스트를 사용자 정의하여 관련 필드로 설정하거나, 장식용 이미지의 경우 빈 문자열로 설정하거나, 대체 텍스트가 다른 콘텐츠의 반복이 될 이미지의 경우에도 설정해야 합니다. 이미지의 대체 텍스트가 이미지 모델에서 직접 오는 경우에도, 이미지가 사용되는 특정 컨텍스트에 대체 텍스트가 있어야 하는지 결정해야 합니다. 예를 들어, 대체 텍스트가 목록 항목의 제목을 반복하는 목록에서는 대체 텍스트를 피하세요.

빈 제목 태그

리치 텍스트와 사용자 정의 StreamField 블록 모두에서, 편집자가 제목 블록을 만들지만 내용을 추가하지 않는 것은 쉽습니다. 내장 접근성 검사기는 빈 제목을 강조 표시하여 편집자가 찾아 수정할 수 있게 합니다. 더 엄격한 시행이 필요한 경우:

  • 해당 필드에 유효성 검사 규칙을 추가하여 빈 제목이 있는 페이지를 저장할 수 없도록 합니다. 예를 들어, 기본적으로 필수인 StreamField CharBlock 을 사용하는 방법이 있습니다.

  • 리치 텍스트 필드에도 유사한 유효성 검사 규칙을 추가하는 것을 고려하세요.

또는 CSS로 빈 제목 블록을 숨길 수 있습니다:

h1:empty,
h2:empty,
h3:empty,
h4:empty,
h5:empty,
h6:empty {
    display: none;
}

양식

양식 빌더는 Django의 양식 API를 사용합니다. 템플릿의 양식과 관련된 고려사항은 다음과 같습니다:

  • as_table, as_ul, as_p 와 같은 렌더링 헬퍼 사용을 피하세요. 이는 스크린 리더 사용자가 양식을 탐색하기 어렵게 만들거나 HTML 유효성 검사 문제를 일으킬 수 있습니다(Django 티켓 #32339 참조).

  • 필수 필드와 선택적 필드를 시각적으로 구분해야 합니다.

  • 관련 필드를 fieldset 으로 그룹화하고 적절한 legend 를 사용하는 데 시간을 투자하세요. 특히 라디오 버튼과 체크박스의 경우 그렇습니다(Django 티켓 #32338 참조).

  • 관련이 있다면 적절한 autocompleteautocapitalize 속성을 사용하세요.

  • 날짜 및 날짜시간 필드의 경우, 예상 형식이나 예제 값을 표시해야 합니다(Django 티켓 #32340 참조). 또는 input type=”date”를 사용하세요.

  • 숫자 필드의 경우, input type="number" 가 정말로 적절한지, 아니면 inputmode와 같은 더 나은 대안이 있는지 고려하세요.

보조 기술로 양식 구현을 테스트하고, 추가 정보를 위해 접근성 있는 양식 개발에 관한 공식 W3C 지침을 검토하세요.

접근성 있는 콘텐츠 작성

접근성 있는 콘텐츠를 만드는 데 도움이 되는 여러 내장 도구와 추가 리소스를 사용할 수 있습니다.

내장 접근성 검사기

Wagtail에는 사용자 바와 미리보기를 지원하는 편집 뷰에 내장된 접근성 검사기가 포함되어 있습니다. 이 검사기는 작성자가 모범 사례와 WCAG와 같은 접근성 표준을 따르는 더 접근성 있는 웹사이트를 만드는 데 도움이 됩니다.

이 검사기는 Axe 테스트 엔진을 기반으로 하며 로드된 페이지에서 오류를 스캔합니다.

기본적으로 검사기는 작성된 콘텐츠에서 일반적인 접근성 문제를 찾기 위해 다음 규칙을 포함합니다:

  • button-name: <button> 요소에는 항상 텍스트 레이블이 있어야 합니다.

  • empty-heading: 이 규칙은 텍스트 내용이 없는 제목을 확인합니다. 빈 제목은 스크린 리더 사용자에게 혼란을 주므로 피해야 합니다.

  • empty-table-header: 테이블 헤더 텍스트는 비어 있지 않아야 합니다.

  • frame-title: <iframe> 요소에는 항상 텍스트 레이블이 있어야 합니다.

  • heading-order: 이 규칙은 잘못된 제목 순서를 확인합니다. 제목은 주요 제목(h1)으로 시작하여 하위 제목(h2, h3 등)이 이어지는 논리적이고 일관된 방식으로 정렬되어야 합니다.

  • input-button-name: <input> 버튼 요소에는 항상 텍스트 레이블이 있어야 합니다.

  • link-name: <a> 링크 요소에는 항상 텍스트 레이블이 있어야 합니다.

  • p-as-heading: 이 규칙은 제목으로 스타일링된 단락을 확인합니다. 단락은 콘텐츠를 탐색하기 위해 제목에 의존하는 사용자에게 도움이 되지 않으므로 제목으로 스타일링되어서는 안 됩니다.

  • alt-text-quality: 사용자 정의 규칙은 이미지 대체 텍스트에 파일 확장자 및 밑줄과 같은 안티 패턴이 포함되지 않도록 합니다.

검사기 실행 방법(예: 테스트할 규칙)을 사용자 정의하려면 AccessibilityItem 의 사용자 정의 하위 클래스를 정의하고 속성을 원하는 대로 재정의할 수 있습니다. 그런 다음 construct_wagtail_userbar 후크를 통해 기본 AccessibilityItem 인스턴스를 사용자 정의 클래스의 인스턴스로 교체합니다.

예를 들어, Axe의 p-as-heading 규칙은 글꼴 무게, 크기 및 기울임꼴의 조합을 평가하여 단락이 시각적으로 제목 역할을 하는지 결정합니다. 제목 스타일에 따라 Axe가 짧고 굵은 단락을 잠재적 제목으로 플래그하기 위해 글꼴 무게만 사용하도록 할 수 있습니다.

from wagtail.admin.userbar import AccessibilityItem


class CustomAccessibilityItem(AccessibilityItem):
    def get_axe_custom_checks(self, request):
        checks = super().get_axe_custom_checks(request)
        # 주변과 비교하여 글꼴 무게만을 기준으로 제목과 유사한 단락에 플래그를 지정합니다.
        checks.append(
            {
                "id": "p-as-heading",
                "options": {
                    "margins": [
                        { "weight": 150 },
                    ],
                    "passLength": 1,
                    "failLength": 0.5
                },
            },
        )
        return checks


@hooks.register('construct_wagtail_userbar')
def replace_userbar_accessibility_item(request, items, page):
    items[:] = [CustomAccessibilityItem() if isinstance(item, AccessibilityItem) else item for item in items]

프로덕션에서 실행하는 검사는 콘텐츠 편집자가 직접 수정할 수 있는 문제로 제한해야 합니다. 그들이 통제할 수 없는 것에 대한 경고는 모든 경고를 무시하도록 가르칠 뿐입니다. 그러나 개발 환경에서 추가 검사를 실행하는 것이 유용할 수 있습니다.

from wagtail.admin.userbar import AccessibilityItem


class CustomAccessibilityItem(AccessibilityItem):
    # 개발 환경에서 이러한 태그가 있는 모든 Axe 규칙 실행
    axe_rules_in_dev = [
        "wcag2a",
        "wcag2aa",
        "wcag2aaa",
        "wcag21a",
        "wcag21aa",
        "wcag22aa",
        "best-practice",
    ]
    # color-contrast-enhanced 규칙 제외
    axe_rules = {
        "color-contrast-enhanced": {"enabled": False},
    }

    def get_axe_run_only(self, request):
        if env.bool('DEBUG', default=False):
            return self.axe_rules_in_dev
        else:
            # 프로덕션에서는 작성된 콘텐츠에 대해서만 Wagtail의 기본 접근성 규칙 실행
            return self.axe_run_only


@hooks.register('construct_wagtail_userbar')
def replace_userbar_accessibility_item(request, items, page):
    items[:] = [CustomAccessibilityItem() if isinstance(item, AccessibilityItem) else item for item in items]

AccessibilityItem 참조

다음은 AccessibilityItem 클래스에 대한 참조 문서입니다:

class wagtail.admin.userbar.AccessibilityItem(in_editor=False)

A userbar item that runs the accessibility checker.

axe_include = ['body']

A list of CSS selector(s) to test specific parts of the page. For more details, see Axe documentation.

axe_exclude = []

A list of CSS selector(s) to exclude specific parts of the page from testing. For more details, see Axe documentation.

axe_run_only

A list of axe-core tags or a list of axe-core rule IDs (not a mix of both). Setting this to a falsy value (e.g. None) will omit the runOnly option and make Axe run with all non-experimental rules enabled.

axe_rules = {}

A dictionary that maps axe-core rule IDs to a dictionary of rule options, commonly in the format of {"enabled": True/False}. This can be used in conjunction with axe_run_only to enable or disable specific rules. For more details, see Axe documentation.

axe_custom_rules

A list to add custom Axe rules or override their properties, alongside with axe_custom_checks. Includes Wagtail’s custom rules. For more details, see Axe documentation.

axe_custom_checks

A list to add custom Axe checks or override their properties. Should be used in conjunction with axe_custom_rules. For more details, see Axe documentation.

axe_messages

A dictionary that maps axe-core rule IDs to custom translatable strings to use as the error messages. If an enabled rule does not exist in this dictionary, Axe’s error message for the rule will be used as fallback.

위의 속성은 요청별 사용자 정의를 허용하기 위해 다음 메서드를 통해 재정의할 수도 있습니다. 이러한 메서드를 재정의할 때는 위 클래스 속성의 변경 가능성에 주의하세요. 예상치 못한 동작을 방지하려면 메서드에서 직접 속성을 수정하는 대신 항상 새 객체를 반환해야 합니다.

get_axe_include(request)
get_axe_exclude(request)
get_axe_run_only(request)
get_axe_rules(request)
get_axe_custom_rules(request)
get_axe_custom_checks(request)
get_axe_messages(request)

더 고급 사용자 정의를 위해 다음 메서드도 재정의할 수 있습니다:

get_axe_context(request)

Returns the context object to be passed as the context parameter for axe.run.

get_axe_options(request)

Returns the options object to be passed as the options parameter for axe.run.

get_axe_spec(request)

Returns spec for Axe, including custom rules and custom checks

wagtail-accessibility

wagtail-accessibility는 Wagtail 미리보기에 tota11y를 추가하는 서드파티 패키지입니다. 이를 통해 작성자가 페이지의 제목 개요나 링크 텍스트를 검증하는 등 기본적인 접근성 검사를 쉽게 실행할 수 있습니다.

help_text 및 HelpPanel

가끔 Wagtail을 사용하는 사용자는 사이트의 콘텐츠 가이드라인이나 웹 작성의 모범 사례를 알지 못할 수 있습니다. 필드의 help_textHelpPanel 을 사용하세요(패널 유형 참조).

가독성

가독성은 접근성의 기본입니다. 텍스트 콘텐츠를 개선하는 방법 중 하나는 읽기 수준/읽기 연령에 대한 명확한 목표를 가지는 것입니다. 이는 wagtail-readinglevel을 사용하여 리치 텍스트 필드에 표시되는 점수로 평가할 수 있습니다.

prefers-reduced-motion

전정기관 장애가 있는 사용자와 같은 일부 사용자는 사이트의 더 정적인 버전을 선호할 수 있습니다. CSS에서 prefers-reduced-motion 미디어 쿼리를 사용하여 이 선호도를 존중할 수 있습니다.

@media (prefers-reduced-motion) {
    /* 사용자의 기기 설정이 모션 감소로 설정된 경우 적용할 스타일 */
    /* 예를 들어, 애니메이션 비활성화 */
    * {
        animation: none !important;
        transition: none !important;
    }
}

prefers-reduced-motion 은 운영 체제나 브라우저에서 이 설정을 활성화한 사용자에게만 적용됩니다. 이 기능은 Chrome, Safari 및 Firefox에서 지원됩니다. 모션 감소에 대한 자세한 정보는 MDN 웹 문서를 참조하세요.

접근성 리소스

우리는 Wagtail 웹사이트에 특화된 고려사항에 중점을 두지만, 접근성에 대해 더 많은 내용이 있습니다. 다음은 개발자뿐만 아니라 디자이너와 작성자에게도 유용한 가치 있는 리소스입니다: