반응형

2025년 웹접근성 주요 변경 사항 개요

2025년 1월부터 웹 콘텐츠 접근성 인증 기준이 기존 22개 항목에서 33개 항목으로 크게 확대되다. 이는 약 8년 만의 대폭 개정으로, 시대 변화와 기술 발전을 반영하여 강화된 규정들이다. 특히 음성 인식 지원, 터치 제스처 대체 수단 제공, 드래그 앤 드롭 대체 방식 등이 새롭게 의무화되었다.


1. 버튼 크기 및 인터랙션 변화

과거 웹접근성 지침에서 버튼의 최소 크기는 주로 44×44픽셀 정도였으나, 2025년 지침에서는 모바일 및 터치 환경에 맞춰 최소 48×48픽셀로 확대 권고되고 있다. 사용자가 손가락으로 정확히 누를 수 있도록 더 큰 크기가 요구되며, 버튼과 인터랙션 요소 사이에 충분한 여백도 강조된다. 

또한 스와이프, 핀치 줌 등 터치 제스처 중심인 모바일 환경에서 제스처 대체 수단도 반드시 제공해야 하며, 손목이나 손가락 움직임이 불편한 사용자를 위한 다양한 조작 방법이 포함되어야 합니다.

2. 음성 인식 및 대체 수단 강화

2024년 이전 지침에서는 음성 인식 기능 지원이 명시적 의무사항은 아니었으나, 2025년부터는 웹사이트 내 음성 명령 지원이 필수적으로 권고된다. ‘헤이 구글’, ‘시리야’와 같은 음성 명령이 웹 인터페이스와 자연스럽게 연동되어야 하며, 보조기기 사용자가 음성으로 웹 콘텐츠와 상호작용할 수 있도록 해야 한다. 

이와 함께 끌어다 놓기(드래그 앤 드롭) 기능은 대체 수단, 즉 클릭 등의 방법으로도 동일한 작업이 가능해야 하며, 단일 상호작용에만 의존하면 안 된다. ​

3. 명도 대비 및 텍스트 크기

기존에는 명도 대비 비율이 4.5:1 이상으로 권고되었으나, 2025년 업데이트에서는 중요 콘텐츠에 대해 7:1 이상의 높은 명도 대비 유지가 권장되어 시각장애 사용자의 가독성을 높여야 한다. 텍스트 크기 역시 반응형 환경 최적화를 위해 최소 16px에서 스케일 조정이 필수가 되었고, 모바일에서는 12~14px로 유동적으로 변경하는 것을 인정하지만 가독성 손실이 없도록 해야 한다. ​

4. KWCAG 2.2 및 한국형 웹 콘텐츠 접근성 지침

2025년부터는 국제 WCAG 2.2를 기반으로 한 한국형 웹 콘텐츠 접근성 지침(KWCAG 2.2)이 공식 적용된다. 이 지침은 한국어 환경에 맞춘 맞춤형 규정들로, 맞춤법, 발음, 조사 등 언어 특성을 고려한 접근성 요소가 포함되어 있으며, 공공기관과 민간기업 모두 필수 준수 대상이다.


정리:  과거와 현재 비교

항목2024년 이전 기준2025년 변경 기준
심사 항목 수 22개 33개로 확대
버튼 최소 크기 44×44 픽셀 48×48 픽셀 이상 권고
터치 제스처 대체 수단 권고 수준 필수 제공
음성 인식 지원 권고 수준 필수 연동 권장
드래그 앤 드롭 단일 방식 지원 가능 대체 수단 반드시 제공
명도 대비 비율 4.5:1 이상 권고 중요한 콘텐츠 7:1 이상 권장
텍스트 크기 고정 크기 또는 제한적 반응형 지원 최소 16px 이상, 모바일 유동적 조정 허용
 
 

웹 표준과 웹접근성은 단순 기술 기준이 아닌 모두에게 공평한 정보 접근권 보장을 위한 필수 요소이다. 2025년 변경 사항을 반영해 더욱 다양하고 편리한 사용자 경험을 설계, 개발해보자! ​

  1. https://www.witheni.com/kor/index.php?pCode=MN0000003&pg=4&mode=view&idx=6256
  2. https://pure-f.tistory.com/62
  3. http://kwacc.or.kr/Board/Notice/5082/Detail?page=1
  4. https://blog.naver.com/oncodenews/223919190305?fromRss=true&trackingCode=rss
  5. https://moo-you.tistory.com/1204
  6. https://jinbytes.com/entry/KWCAG-2025-%EC%9B%B9-%EC%A0%91%EA%B7%BC%EC%84%B1-%EC%B5%9C%EC%8B%A0-%EA%B8%B0%EC%A4%80-%EC%A0%95%EB%A6%AC
  7. https://www.wa.or.kr/board/view.asp?BoardID=0001&sn=32749
  8. https://comblindness.tistory.com/entry/%E2%9C%A8-2025%EB%85%84-%EC%B5%9C%EC%8B%A0-%EA%B5%AD%EB%82%B4%EC%99%B8-%EC%A0%91%EA%B7%BC%EC%84%B1-%EB%B2%95%EA%B7%9C-%EB%B0%8F-%EC%A0%95%EC%B1%85-%EB%B3%80%ED%99%94-%ED%95%B5%EC%8B%AC%EB%A7%8C-%EC%8F%99%EC%8F%99-feat-%EC%A0%9C%EB%AF%B8%EB%82%98%EC%9D%B4-%F0%9F%A4%96
  9. https://www.wa.or.kr/board/view.asp?sn=32036&page=1&search=&SearchString=&BoardID=0001&cate=
  10. https://blog.naver.com/agapeuni/223852360075?fromRss=true&trackingCode=rss
  11. https://uiweb.tistory.com/230
  12. https://www.w3.org/WAI/standards-guidelines/ko
  13. https://www.kioskui.or.kr/index.do?menu_id=00001200
  14. https://hcdl.mohw.go.kr/notice/detail/567/1
  15. https://m.nuli.navercorp.com/community/article/1133264
  16. https://time.ly/ko/blog/%EC%A0%91%EA%B7%BC%EC%84%B1-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EA%B0%80%EC%9D%B4%EB%93%9C-%ED%8F%AC%EC%9A%A9%EC%A0%81%EC%9D%B8-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EA%B8%B0%ED%9A%8D/
  17. http://www.webwatch.or.kr/WA/010301.html?MenuCD=130
  18. https://developer.chrome.com/blog/new-in-web-ui-io-2025-recap?hl=ko
  19. https://itpe.jackerlab.com/entry/%EC%9B%B9-%EC%A0%91%EA%B7%BC%EC%84%B1-%EA%B0%80%EC%9D%B4%EB%93%9C%EB%9D%BC%EC%9D%B8Web-Accessibility-Guideline
  20. https://www.seo.incheon.kr/open_content/main/guidance/webpolicy.jsp

 

반응형
반응형

childNodes vs children의 핵심 차이

기본 개념

// HTML 구조 예시
const div = document.createElement('div');
div.innerHTML = `
    첫 번째 텍스트
    <p>단락 1</p>
    <!-- 주석입니다 -->
    <span>스팬 요소</span>
    마지막 텍스트
`;

// childNodes: 모든 종류의 자식 노드 (NodeList)
console.log(div.childNodes);
// NodeList(9) [
//   text (줄바꿈과 공백),
//   text ("첫 번째 텍스트"),
//   text (줄바꿈과 공백),
//   p,
//   text (줄바꿈과 공백),
//   comment ("주석입니다"),
//   text (줄바꿈과 공백),
//   span,
//   text ("마지막 텍스트")
// ]

// children: HTML 요소만 (HTMLCollection)
console.log(div.children);
// HTMLCollection(2) [p, span]

핵심 정리:

  • childNodes: 모든 것 (텍스트, 주석, 요소) → 정밀한 DOM 조작
  • children: HTML 요소만 → 일반적인 웹 개발
  • 대부분의 경우 children이 더 편리하고 직관적
  • DOM의 정확한 구조가 중요할 때만 childNodes 사용
반응형

'JS_개념' 카테고리의 다른 글

childNodes vs children  (0) 2025.09.19
2-1-5. Node와 Element의 차이에 대해 설명해주세요  (0) 2025.09.19
textContent  (0) 2025.09.19

반응형

textContent의 근본 개념

textContent노드와 그 자손들의 텍스트 콘텐츠를 순수 텍스트로 표현한 것입니다. HTML 태그는 모두 제거하고 오직 텍스트만 추출하거나 설정하는 속성입니다.

const div = document.createElement('div');
div.innerHTML = '<p>Hello <strong>World</strong>!</p>';

// textContent는 모든 텍스트만 추출
console.log(div.textContent);  // "Hello World!"

// innerHTML은 HTML 구조 포함
console.log(div.innerHTML);  // "<p>Hello <strong>World</strong>!</p>"

주요 사용 케이스

1. 안전한 텍스트 삽입 (XSS 방지)

사용자 입력을 받을 때 가장 중요한 용도입니다:

// ❌ 위험: 사용자가 스크립트를 삽입할 수 있음
userComment.innerHTML = userInput;  // "<script>alert('해킹!')</script>" 실행됨

// ✅ 안전: HTML로 해석되지 않고 순수 텍스트로 표시
userComment.textContent = userInput;  // 스크립트가 문자 그대로 표시됨

2. 텍스트만 추출하기

HTML 구조에서 순수 텍스트만 필요할 때:

// 복잡한 HTML 구조에서 텍스트만 추출
const article = document.querySelector('article');
const plainText = article.textContent;  // 모든 태그 제거, 텍스트만

// 예: 글자 수 세기
const charCount = article.textContent.length;

// 예: 검색 기능
if (article.textContent.includes('JavaScript')) {
    // 해당 article에 'JavaScript' 단어가 포함됨
}

3. 간단한 텍스트 업데이트

HTML 구조가 필요 없이 텍스트만 변경할 때:

// 버튼 텍스트 변경
button.textContent = '로딩중...';

// 에러 메시지 표시
errorDiv.textContent = '입력값이 올바르지 않습니다.';

// 카운터 업데이트
counterSpan.textContent = count.toString();

4. 텍스트 노드 직접 조작

// 텍스트 노드의 내용 변경
const textNode = element.firstChild;  // 첫 번째 텍스트 노드
if (textNode.nodeType === Node.TEXT_NODE) {
    textNode.textContent = '새로운 텍스트';
}

textContent vs innerHTML vs innerText

const div = document.createElement('div');
div.innerHTML = `
    <p>보이는 텍스트</p>
    <p style="display:none">숨겨진 텍스트</p>
`;

// innerHTML: HTML 태그 포함
console.log(div.innerHTML);  // 전체 HTML 구조

// textContent: 모든 텍스트 (숨겨진 것 포함)
console.log(div.textContent);  // "보이는 텍스트숨겨진 텍스트"

// innerText: 실제로 보이는 텍스트만
console.log(div.innerText);  // "보이는 텍스트"

실전 예시: 댓글 시스템

function addComment(userInput) {
    const comment = document.createElement('div');

    // 사용자 입력을 위한 별도 요소 생성
    const textContainer = document.createElement('p');
    textContainer.textContent = userInput;  // XSS 방지

    // 시간 정보 요소 생성
    const time = document.createElement('span');
    time.className = 'comment-time';

    // small 요소도 DOM으로 생성 (더 안전)
    const small = document.createElement('small');
    small.textContent = new Date().toLocaleString();
    time.appendChild(small);

    // 조립
    comment.appendChild(textContainer);
    comment.appendChild(time);
    commentList.appendChild(comment);
}

// 결과 HTML:
// <div>
//     <p>사용자의 댓글 내용</p>
//     <span class="comment-time">
//         <small>2024. 12. 27. 오후 3:30:00</small>
//     </span>
// </div>

핵심은 "HTML 태그 해석이 필요한가?"입니다:

  • 필요 없음 → textContent (더 안전하고 빠름)
  • 필요함 → innerHTML (XSS 위험 주의)

코드 상세 해석

실무에서 자주 쓰는 패턴

function addComment(userInput) {
    const comment = document.createElement('div');
    comment.className = 'comment-item';

    // HTML 템플릿 사용 (신뢰할 수 있는 데이터만)
    comment.innerHTML = `
        <div class="comment-content"></div>
        <span class="comment-meta">
            <small class="comment-time">${new Date().toLocaleString()}</small>
        </span>
    `;

    // 사용자 입력은 textContent로 안전하게 삽입
    comment.querySelector('.comment-content').textContent = userInput;

    commentList.appendChild(comment);
}

XSS 공격 시뮬레이션

// 악의적인 사용자 입력 예시
const maliciousInput = '<img src=x onerror="alert(\'해킹!\')">'; 

// ❌ innerHTML 사용 시 (위험!)
comment.innerHTML = maliciousInput;  
// 결과: 스크립트가 실행되어 alert 창이 뜸!

// ✅ textContent 사용 시 (안전!)
comment.textContent = maliciousInput;  
// 결과: "<img src=x onerror="alert('해킹!')">" 텍스트가 그대로 표시됨

완전한 실전 예시

class CommentSystem {
    constructor(container) {
        this.container = container;
    }

    addComment(userInput, userId) {
        // 입력값 검증
        if (!userInput.trim()) {
            alert('댓글을 입력해주세요');
            return;
        }

        // 댓글 요소 생성
        const comment = document.createElement('article');
        comment.className = 'comment';
        comment.dataset.timestamp = Date.now();

        // 안전한 템플릿 구조
        comment.innerHTML = `
            <div class="comment-header">
                <span class="comment-author"></span>
                <time class="comment-time">${this.formatTime(new Date())}</time>
            </div>
            <div class="comment-body"></div>
            <div class="comment-actions">
                <button class="btn-like">좋아요</button>
                <button class="btn-reply">답글</button>
            </div>
        `;

        // 사용자 입력은 textContent로 안전하게
        comment.querySelector('.comment-author').textContent = userId;
        comment.querySelector('.comment-body').textContent = userInput;

        // 이벤트 리스너 추가
        comment.querySelector('.btn-like').addEventListener('click', () => {
            this.likeComment(comment);
        });

        this.container.appendChild(comment);
    }

    formatTime(date) {
        const now = new Date();
        const diff = now - date;

        if (diff < 60000) return '방금 전';
        if (diff < 3600000) return `${Math.floor(diff/60000)}분 전`;
        if (diff < 86400000) return `${Math.floor(diff/3600000)}시간 전`;
        return date.toLocaleDateString();
    }

    likeComment(comment) {
        comment.classList.toggle('liked');
    }
}

// 사용
const commentSystem = new CommentSystem(document.getElementById('comments'));
commentSystem.addComment('좋은 글 감사합니다!', 'user123');

핵심 원칙:

  • 사용자 입력 → textContent (항상!)
  • 신뢰할 수 있는 구조 → innerHTML (조심스럽게)
  • 두 가지를 섞을 때는 구조를 먼저 만들고, 사용자 데이터를 나중에 삽입
반응형

'JS_개념' 카테고리의 다른 글

childNodes vs children  (0) 2025.10.14
childNodes vs children  (0) 2025.09.19
2-1-5. Node와 Element의 차이에 대해 설명해주세요  (0) 2025.09.19
반응형

1. JavaScript 기초


1-1. 데이터 타입 & 변수


1-1-1. undefined와 null의 차이점에 대해서 설명해주세요

1-1-2. JavaScript의 데이터 타입에는 어떤 것들이 있나요?

1-1-3. let, const, var의 차이점을 설명해주세요

1-1-4. 호이스팅(Hoisting)이란 무엇인가요?

1-1-5. 스코프(Scope)에 대해 설명해주세요

1-1-6. 클로저(Closure)란 무엇인가요?

1-2. 함수

1-2-1. 화살표 함수와 일반 함수의 차이점은 무엇인가요?

1-2-2. call, apply, bind 메서드의 차이점을 설명해주세요

1-2-3. 콜백 함수란 무엇인가요?

1-2-4. 고차 함수(Higher-Order Function)에 대해 설명해주세요

1-3. 객체 & 배열

1-3-1. 객체를 복사하는 방법들을 설명해주세요 (얕은 복사 vs 깊은 복사)

1-3-2. 배열의 주요 메서드들(map, filter, reduce 등)에 대해 설명해주세요

1-3-3. 구조 분해 할당(Destructuring)에 대해 설명해주세요

1-4. 비동기 처리

1-4-1. 동기와 비동기의 차이점을 설명해주세요

1-4-2. Promise란 무엇이고, 어떻게 사용하나요?

1-4-3. async/await에 대해 설명해주세요

1-4-4. 콜백 지옥(Callback Hell)과 해결 방법을 설명해주세요

2. HTML/CSS

2-1. HTML

2-1-1. 시맨틱 HTML이란 무엇인가요?

2-1-2. DOCTYPE의 역할은 무엇인가요?

2-1-3. meta 태그의 용도를 설명해주세요

2-1-4. 웹 접근성(Web Accessibility)에 대해 설명해주세요

2-1-5. Node와 Element의 차이에 대해 설명해주세요

자세히 보기

2-2. CSS

2-2-1. CSS Box Model에 대해 설명해주세요

2-2-2. Flexbox와 Grid의 차이점을 설명해주세요

2-2-3. CSS 선택자 우선순위에 대해 설명해주세요

2-2-4. position 속성의 값들(static, relative, absolute, fixed)에 대해 설명해주세요

2-2-5. CSS-in-JS의 장단점을 설명해주세요

3. React

3-1. 기본 개념

3-1-1. React가 무엇이고, 왜 사용하나요?

3-1-2. Virtual DOM이 무엇이고, 어떤 장점이 있나요?

3-1-3. JSX란 무엇인가요?

3-1-4. 컴포넌트의 생명주기에 대해 설명해주세요

3-2. Hooks

3-2-1. useState와 useEffect에 대해 설명해주세요

3-2-2. useCallback과 useMemo의 차이점을 설명해주세요

3-2-3. useRef는 언제 사용하나요?

3-2-4. 커스텀 Hook을 만드는 이유는 무엇인가요?

3-3. 상태 관리

3-3-1. props와 state의 차이점을 설명해주세요

3-3-2. Context API에 대해 설명해주세요

3-3-3. Redux의 동작 원리를 설명해주세요

3-3-4. 전역 상태 관리가 필요한 이유는 무엇인가요?

4. 웹 개발 일반

4-1. 성능 최적화

4-1-1. 웹 성능을 최적화하는 방법들을 설명해주세요

4-1-2. 번들 사이즈를 줄이는 방법들을 설명해주세요

4-1-3. 이미지 최적화 방법들을 설명해주세요

4-1-4. 메모이제이션(Memoization)이란 무엇인가요?

4-2. 브라우저 & 네트워크

4-2-1. 브라우저 렌더링 과정을 설명해주세요

4-2-2. HTTP와 HTTPS의 차이점을 설명해주세요

4-2-3. CORS란 무엇이고, 어떻게 해결하나요?

4-2-4. 웹 스토리지(localStorage, sessionStorage)에 대해 설명해주세요

4-3. 보안

4-3-1. XSS와 CSRF 공격에 대해 설명해주세요

4-3-2. 보안 헤더들(CSP, HSTS 등)에 대해 설명해주세요

5. 협업 & 도구

5-1. 버전 관리

5-1-1. Git의 기본 개념과 주요 명령어들을 설명해주세요

5-1-2. Git Flow 전략에 대해 설명해주세요

5-1-3. 브랜치 전략에 대해 설명해주세요

5-2. 테스팅

5-2-1. 단위 테스트, 통합 테스트, E2E 테스트의 차이점을 설명해주세요

5-2-2. Jest와 같은 테스팅 라이브러리 사용 경험이 있나요?

5-3. 빌드 도구

5-3-1. Webpack의 역할과 주요 개념들을 설명해주세요

5-3-2. Babel이란 무엇인가요?

5-3-3. 모듈 번들러가 필요한 이유는 무엇인가요?

6. 프로젝트 & 경험

6-1. 실무 경험

6-1-1. 가장 기억에 남는 프로젝트와 그 이유를 설명해주세요

6-1-2. 프로젝트에서 겪었던 기술적 어려움과 해결 과정을 설명해주세요

6-1-3. 코드 리뷰에서 중요하게 생각하는 점들은 무엇인가요?

6-1-4. 새로운 기술을 학습할 때 어떤 방식으로 접근하나요?

6-2. 문제 해결

6-2-1. 디버깅할 때 주로 사용하는 방법들을 설명해주세요

6-2-2. 성능 문제를 발견하고 해결한 경험이 있나요?

6-2-3. 브라우저 호환성 문제를 어떻게 해결하나요?

7. 최신 트렌드

7-1. 개발 트렌드

7-1-1. SSR과 CSR의 차이점을 설명해주세요

7-1-2. JAMstack에 대해 알고 있나요?

7-1-3. 마이크로 프론트엔드에 대해 설명해주세요

7-1-4. PWA(Progressive Web App)란 무엇인가요?

7-2. TypeScript

7-2-1. TypeScript를 사용하는 이유는 무엇인가요?

7-2-2. any와 unknown의 차이점을 설명해주세요

7-2-3. 제네릭(Generics)에 대해 설명해주세요


반응형

+ Recent posts