컴포넌트/시멘틱태그

Aside (어사이드)

VanillaFront 2026. 9. 16. 18:12

Va.Aside — HTML <aside> 시맨틱 컨테이너

HTML5의 <aside> 태그를 감싸는 시맨틱 컨테이너. 주 콘텐츠와 관련은 있지만 부수적인 콘텐츠를 나타냅니다. 사이드바·관련 링크·광고·인용문 같은 UI에 어울려요.

  • 클래스: Va.Aside  va_component.js:21421
  • short name: aside
  • 상속: Va.Semantic (Main·Article·Section과 같은 부모)
  • DOM 태그: <aside>
  • isContainer: true
  • 베이스 CSS: va-aside

1. 기본 사용

{
    tagName: 'aside',
    layout: 'ds-flex fd-column gap-s',
    style: { width: '300px', padding: '20px' },
    tags: [
        { tagName: 'h3', innerHTML: '관련 글' },
        { tagName: 'ul', tags: [/* 링크들 */] }
    ]
}
  • HTML <aside> 태그로 렌더링
  • 스크린리더가 "보조 콘텐츠"로 인식
  • 대개 좌측/우측 사이드바 자리에 배치

2. <aside> HTML 표준의 의미

HTML5 표준상 <aside>는 "주 콘텐츠와 관련은 있지만 없어도 문서가 성립하는 부수적 콘텐츠". 판단 기준:

  • 없어져도 주요 콘텐츠 이해에 지장이 없나? — 있으면 aside
  • 관련 링크·용어 설명·광고·인용문인가? — aside
  • 사이드바·서브 메뉴인가? — aside

예시:

  • 블로그 글 옆 관련 글 목록
  • 기사 안 인용문 박스
  • 페이지 우측 광고 영역
  • 문서 좌측 목차 (navigation은 nav가 더 맞을 수도)

3. Semantic 계열에서의 위치

컴포넌트시맨틱 의미

Va.Main 페이지 주요 콘텐츠
Va.Article 독립 배포 가능 콘텐츠
Va.Section 주제별 문서 섹션
Va.Aside 부수적 콘텐츠
Va.Nav 네비게이션
Va.Header / Va.Footer 헤더/푸터

4. 주요 속성

Semantic 상속만. 자체 추가 없음:

속성설명

innerHTML HTML 콘텐츠 (_sanitize 적용)
text 순수 텍스트
layout Flex/Grid 레이아웃
style / mobileStyle 스타일
class / addClass CSS 클래스
mediaQuery 반응형

5. 이벤트 (Semantic 상속)

이벤트시그니처발생 시점

click (component, element, evt) 클릭
contextmenu (component, element, evt) 우클릭 (기본 컨텍스트 메뉴 자동 차단)
focus / blur (component, element, evt) 포커스 진입/이탈

6. 메서드

Semantic 상속. setText, setInnerHTML 등 표준.


7. 내부 구조

<aside elname="element" class="va-aside [layout classes]" tag-name="aside">
  <!-- 자식 컴포넌트들 -->
</aside>

매우 단순. HTML <aside> 태그 + va-aside 클래스.


8. 언제 쓰나

Va.Aside가 맞을 때

  • 사이드바 (좌측·우측 부가 메뉴)
  • 관련 글·추천 콘텐츠 목록
  • 인용문·주석 박스
  • 위젯·광고 영역
  • 용어 설명 박스
  • 주 콘텐츠 옆의 부수 정보

다른 걸 쓸 때

  • 네비게이션이 주된 역할 → Va.Nav
  • 페이지 주요 콘텐츠 → Va.Main
  • 독립 콘텐츠 → Va.Article
  • 주제별 섹션 → Va.Section
  • 단순 컨테이너 → Va.Div

⚠️ <nav>와 혼동 주의 — 사이드바가 네비게이션이 주된 역할이면 <nav>가 더 정확. 관련 링크가 부수적이면 <aside> 안에 <nav>를 중첩하기도.


9. 흔한 조합 예시

// 좌측 사이드바 + 메인 콘텐츠
{
    tagName: 'div',
    layout: 'ds-flex fd-row',
    tags: [
        {
            tagName: 'aside',
            style: { width: '250px', padding: '20px', background: '#f5f5f5' },
            tags: [
                { tagName: 'h3', innerHTML: '카테고리' },
                { tagName: 'ul', tags: [/* 카테고리 링크들 */] }
            ]
        },
        {
            tagName: 'main',
            style: { flex: 1, padding: '20px' },
            tags: [/* 주요 콘텐츠 */]
        }
    ]
}

// 블로그 글 + 우측 관련 글
{
    tagName: 'main',
    layout: 'ds-flex fd-row gap-l',
    tags: [
        {
            tagName: 'article',
            style: { flex: 1 },
            tags: [
                { tagName: 'h1', innerHTML: '기사 제목' },
                { tagName: 'p',  innerHTML: '본문...' }
            ]
        },
        {
            tagName: 'aside',
            style: { width: '300px' },
            tags: [
                { tagName: 'h3', innerHTML: '관련 글' },
                { tagName: 'ul', tags: [/* 관련 글 링크 */] }
            ]
        }
    ]
}

// 인용문 박스 (본문 안 aside)
{
    tagName: 'article',
    tags: [
        { tagName: 'p', innerHTML: '본문 1' },
        {
            tagName: 'aside',
            style: {
                background: '#eef',
                padding: '16px',
                borderLeft: '4px solid #66f',
                margin: '20px 0'
            },
            tags: [
                { tagName: 'p', innerHTML: '💡 참고: 이 개념은...' }
            ]
        },
        { tagName: 'p', innerHTML: '본문 2' }
    ]
}

// 광고·위젯 영역
{
    tagName: 'aside',
    style: { padding: '20px', border: '1px solid gray' },
    tags: [
        { tagName: 'h4', innerHTML: '이벤트 안내' },
        { tagName: 'img', src: '/promo.jpg' },
        { tagName: 'button', text: '자세히 보기' }
    ]
}

// 모바일: 상단 사이드바
{
    tagName: 'aside',
    style: {
        display: 'none'
    },
    mediaQuery: {
        mobile: { display: 'block' }
    },
    tags: [/* 모바일 전용 알림 */]
}

10. 실전 예 — 블로그 상세 페이지

class BlogDetail extends Va.View {
    config() {
        return {
            tagName: 'div',
            layout: 'ds-flex fd-column',
            style: { minHeight: '100vh' },
            tags: [
                // 헤더
                {
                    tagName: 'header',
                    tags: [/* 로고, 네비 */]
                },

                // 주요 콘텐츠 영역
                {
                    tagName: 'main',
                    layout: 'ds-flex fd-row gap-l',
                    style: { flex: 1, padding: '20px', maxWidth: '1200px', margin: '0 auto' },
                    tags: [
                        // 본문 (독립 콘텐츠)
                        {
                            tagName: 'article',
                            style: { flex: 1 },
                            tags: [
                                { tagName: 'h1', innerHTML: '블로그 제목' },
                                { tagName: 'p',  innerHTML: '본문 내용...' }
                            ]
                        },

                        // 우측 사이드바 (부수 콘텐츠)
                        {
                            tagName: 'aside',
                            style: {
                                width: '300px',
                                display: 'flex',
                                flexDirection: 'column',
                                gap: '20px'
                            },
                            tags: [
                                // 작성자 정보
                                {
                                    tagName: 'section',
                                    style: { padding: '16px', border: '1px solid gray' },
                                    tags: [
                                        { tagName: 'h3', innerHTML: '작성자' },
                                        { tagName: 'p',  innerHTML: '홍길동' }
                                    ]
                                },
                                // 관련 글
                                {
                                    tagName: 'section',
                                    style: { padding: '16px', border: '1px solid gray' },
                                    tags: [
                                        { tagName: 'h3', innerHTML: '관련 글' },
                                        { tagName: 'ul', tags: [/* 관련 글 링크 */] }
                                    ]
                                },
                                // 광고
                                {
                                    tagName: 'section',
                                    style: { padding: '16px', background: '#f5f5f5' },
                                    tags: [
                                        { tagName: 'p', innerHTML: '광고 영역' }
                                    ]
                                }
                            ]
                        }
                    ]
                },

                // 푸터
                { tagName: 'footer', tags: [/* 저작권 등 */] }
            ]
        };
    }
}

시맨틱 계층:

  • <header> — 페이지 헤더 (랜드마크)
  • <main> — 주요 콘텐츠 영역 (랜드마크)
    • <article> — 블로그 글 본문 (독립 콘텐츠)
    • <aside> — 부수 콘텐츠 (랜드마크)
      • <section> × 3 — 부수 콘텐츠 안 각 그룹
  • <footer> — 페이지 푸터 (랜드마크)

스크린리더 사용자가 "메인 콘텐츠로 이동 / 부수 콘텐츠로 이동" 같은 랜드마크 네비게이션으로 빠르게 이동 가능.


11. 알아두면 좋을 주의사항

  1. "부수적"이 판단 기준 — 없어져도 주 콘텐츠 이해에 지장 없어야 aside 적절.
  2. <nav>와 혼동 주의 — 네비게이션이 주된 목적이면 <nav>가 더 정확.
  3. 한 페이지 여러 개 OK — 사이드바가 좌우 둘 다 있어도 각각 aside.
  4. 본문 안에도 사용 가능 — 인용문·주석 박스로.
  5. 자체 스타일 최소  va-aside 클래스만. width·position·padding 명시 필요.
  6. 모바일에서 어떻게 보일지 계획 — 좌측 사이드바를 모바일에선 어떻게 처리할지 (mediaQuery 활용).
  7. contextmenu 자동 preventDefault — 우클릭 시 브라우저 메뉴 차단.
  8. 접근성 랜드마크 — 스크린리더가 "complementary" 랜드마크로 인식.
  9. SEO 관점 — 크롤러가 주 콘텐츠와 부수 콘텐츠를 구분해 이해.
  10. VanillaFront 실무엔 자주 안 쓰임 — 업무 화면은 대개 page + panel. Aside는 콘텐츠 사이트에 어울림.

12. aside vs nav vs section vs div 선택

상황추천

부수 콘텐츠 (관련 글, 광고) aside
좌측/우측 사이드바 (네비 위주) nav (안에 aside 중첩도 가능)
본문 안 인용문 박스 aside
주제별 문서 섹션 section
네비게이션 링크 모음 nav
단순 컨테이너 (시맨틱 무관) div
위젯·광고 영역 aside

"주 콘텐츠와 관련은 있지만 없어도 되는 부수 콘텐츠면 aside".


참고