아이콘 이미지 대신 문자 기호 쓰기 | 요청 수와 레이아웃 잡기

서브메뉴 앞에 작은 화살표 아이콘 이미지가 있었습니다. 용량은 1KB도 되지 않는 GIF 파일이었고, 화면에서도 아주 작은 장식 요소였습니다. 처음에는 굳이 손댈 필요가 없다고 생각했습니다.

그런데 접근성 정리를 하다가 이 이미지가 페이지마다 반복 출력되는 것을 봤습니다. 메뉴가 12개면 같은 아이콘 요청도 12번 가까이 등장했고, 이미지가 늦게 로드될 때 메뉴 줄이 미세하게 움직이는 것도 보였습니다.

이 글은 아이콘 이미지를 무조건 없애자는 글이 아닙니다. 오래된 사이트에 남아 있던 장식용 화살표 이미지를 문자 기호와 CSS로 바꾸면서, 요청 수와 레이아웃 안정성, 접근성에서 어떤 차이가 있었는지 정리한 글입니다.

장식용 화살표 이미지를 문자 기호와 CSS로 대체한 코드

서브메뉴 앞에 반복되던 작은 이미지

기존 코드는 이런 형태였습니다.

<img src="minihome_img/icon_arr03.gif" alt=""> 회사소개

하나만 보면 별것 아닙니다. 작은 GIF 파일이고, alt=""도 들어가 있어서 접근성상 큰 문제처럼 보이지 않았습니다.

하지만 실제 페이지에서는 이 코드가 여러 번 반복됐습니다.

<img src="minihome_img/icon_arr03.gif" alt=""> 회사소개
<img src="minihome_img/icon_arr03.gif" alt=""> 오시는길
<img src="minihome_img/icon_arr03.gif" alt=""> 연혁
<img src="minihome_img/icon_arr03.gif" alt=""> 자료실

이때 든 생각은 단순했습니다.

이게 꼭 이미지여야 하나?

정보를 전달하는 이미지가 아니라 메뉴 앞에 붙는 장식이라면, 이미지 파일을 불러올 이유가 크지 않았습니다.

문자 기호와 CSS로 대체

이미지 대신 문자 기호를 쓰고, CSS로 폭과 색상을 맞췄습니다.

<span class="submenu-mark" aria-hidden="true">└</span> 회사소개
.submenu-mark {
    display: inline-block;
    width: 12px;
    margin-right: 4px;
    color: #999;
    font-size: 12px;
    line-height: 1;
    text-align: center;
}

aria-hidden="true"를 넣은 이유는 이 기호가 장식이기 때문입니다. 스크린 리더가 메뉴를 읽을 때마다 “기호”나 “박스 드로잉” 같은 불필요한 말을 읽지 않게 하려는 목적입니다.

핵심은 width: 12px입니다. 문자 기호는 폰트에 따라 폭이 조금씩 달라질 수 있습니다. 메뉴 정렬이 흔들리지 않도록 고정 폭을 줬습니다.

요청 수가 줄어든 효과

이 작업으로 사라진 것은 이미지 용량보다 HTTP 요청이었습니다.

작은 GIF 파일 하나는 용량만 보면 별것 아닙니다. 하지만 브라우저가 파일을 가져올 때는 파일 본문만 오가는 것이 아닙니다.

  • 요청 헤더
  • 응답 헤더
  • 캐시 확인
  • 연결 처리
  • 이미지 디코딩
  • 렌더링 반영

작은 파일일수록 실제 파일 크기보다 요청 오버헤드가 더 크게 느껴질 수 있습니다.

물론 아이콘 하나를 바꿨다고 사이트 속도가 극적으로 빨라지지는 않습니다. 하지만 오래된 사이트에는 이런 장식 이미지가 여러 곳에 남아 있었습니다.

화살표 아이콘 → 문자 기호
구분선 이미지 → CSS border
동그라미 모서리 이미지 → border-radius
그라데이션 배경 → linear-gradient
버튼 배경 이미지 → CSS background

하나씩은 작아도 여러 개가 모이면 요청 수와 관리 포인트가 줄어듭니다.

레이아웃 이동이 줄어든 이유

더 크게 느낀 변화는 레이아웃 안정성이었습니다. 이미지에 width, height가 없으면 브라우저는 이미지가 로드되기 전까지 정확한 공간을 모를 수 있습니다.

<img src="/img/icon_arrow.gif" alt="">

이미지가 늦게 도착하면 처음에는 공간이 없다가, 로드되는 순간 주변 텍스트가 밀릴 수 있습니다. 메뉴가 여러 개라면 화면이 한 번 울컥하는 것처럼 보일 수 있습니다.

문자 기호는 외부 파일을 기다리지 않습니다. HTML과 CSS만 있으면 처음 렌더링부터 공간이 잡힙니다.

<span class="submenu-mark" aria-hidden="true">└</span>
.submenu-mark {
    display: inline-block;
    width: 12px;
}

고정 폭을 주면 메뉴 텍스트 시작 위치도 일정해집니다. 사용자가 메뉴를 누르려는 순간 아이콘 로드 때문에 줄이 밀리는 상황을 줄일 수 있었습니다.

이미지를 유지해야 하는 경우

모든 아이콘을 문자로 바꿀 수는 없습니다. 브랜드 아이콘이나 실제 의미가 있는 그림은 이미지로 두는 편이 맞습니다.

이미지를 유지해야 한다면 최소한 크기를 명시했습니다.

<img src="/img/icon_arrow.gif" alt="" width="12" height="12">

width와 height 속성이 있으면 브라우저가 이미지 로드 전에도 공간을 미리 확보할 수 있습니다. CSS로 크기를 조절하더라도 HTML 속성에 원본 비율을 알려두면 레이아웃 안정성에 도움이 됩니다.

의미 있는 이미지라면 빈 alt가 아니라 적절한 설명도 필요합니다.

<img src="/img/tetris-play-screen.jpg" alt="테트리스 게임 플레이 화면" width="640" height="360">

장식 이미지와 의미 있는 이미지를 구분하는 것이 먼저였습니다.

CSS로 바꿀 수 있었던 장식 요소

화살표 아이콘을 바꾸고 나니 다른 장식 이미지도 보였습니다. 오래된 사이트에는 CSS로 처리할 수 없던 시절의 흔적이 많이 남아 있었습니다.

기존 이미지대체 방법확인할 점
화살표 아이콘문자 기호 또는 CSSaria-hidden 처리
구분선 이미지border-top색상과 여백
둥근 모서리 이미지border-radius구형 브라우저 범위
그라데이션 배경linear-gradient명암 대비
반복 배경 패턴CSS 배경 또는 단색가독성

예를 들어 구분선 이미지는 이렇게 바꿀 수 있었습니다.

<!-- before -->
<img src="/img/line_dot.gif" alt="">

<!-- after -->
<hr class="section-line">
.section-line {
    border: 0;
    border-top: 1px dotted #ccc;
    margin: 12px 0;
}

이미지를 없애면 색상, 두께, 여백을 CSS에서 바로 조정할 수 있어 유지보수도 쉬워졌습니다.

문자 기호 선택 기준

문자 기호를 고를 때는 예쁜 것보다 안정적인 것을 우선했습니다.

비교적 안전한 기호는 이런 쪽이었습니다.

└
›
•
-

반대로 특수한 유니코드 기호나 이모지는 환경마다 다르게 보일 수 있습니다. 어떤 기기는 컬러 이모지로 보이고, 어떤 기기는 네모 박스로 깨질 수 있습니다.

장식 요소라면 화려한 기호보다 단순하고 널리 지원되는 문자를 쓰는 편이 안전했습니다.

문서 인코딩도 확인했습니다.

<meta charset="utf-8">

오래된 사이트가 EUC-KR이나 다른 인코딩을 쓰고 있다면 문자 기호가 깨질 수 있습니다. 기호를 넣은 뒤에는 모바일과 데스크톱에서 모두 표시를 확인했습니다.

접근성에서 확인한 부분

장식 이미지를 문자로 바꾸면 접근성 처리를 다시 확인해야 합니다. 이미지일 때는 alt=""로 건너뛰게 했지만, 문자 기호는 그대로 두면 읽힐 수 있습니다.

그래서 aria-hidden="true"를 붙였습니다.

<span class="submenu-mark" aria-hidden="true">└</span>

스크린 리더가 읽어야 하는 것은 기호가 아니라 메뉴명입니다.

회사소개
오시는길
연혁

만약 버튼이나 링크의 의미를 아이콘이 전달한다면 이야기가 달라집니다. 예를 들어 검색 버튼의 돋보기 아이콘은 장식이 아니라 기능을 나타낼 수 있습니다. 이때는 버튼에 이름을 줘야 합니다.

<button type="submit" aria-label="검색">
    <span aria-hidden="true">🔍</span>
</button>

장식은 숨기고, 기능은 이름을 주는 식으로 나눴습니다.

적용 후 확인한 항목

수정 후에는 화면만 보지 않고 네트워크와 레이아웃 흐름을 같이 확인했습니다.

curl -I https://example.com/img/icon_arrow.gif

이미지 요청이 더 이상 필요한지 확인했고, 개발자 도구 네트워크 탭에서도 해당 아이콘 요청이 사라졌는지 봤습니다.

브라우저에서는 아래 항목을 확인했습니다.

  • 메뉴 텍스트 시작 위치가 일정한지
  • 모바일에서 기호가 깨지지 않는지
  • 스크린 리더가 기호를 읽지 않는지
  • CSS 없이도 메뉴명이 보이는지
  • 고해상도 화면에서 흐릿하지 않은지
  • 색상 대비가 너무 낮지 않은지

이미지 하나를 없애는 작업이지만, 실제로는 렌더링과 접근성까지 같이 봐야 했습니다.

적용 후 달라진 점

작업 후에는 작은 변화들이 모였습니다.

  • 페이지당 장식 이미지 요청 감소
  • 메뉴 영역의 레이아웃 이동 감소
  • 아이콘 색상과 여백을 CSS로 관리 가능
  • 고해상도 화면에서 흐릿한 GIF 느낌 제거
  • 스크린 리더에서 불필요한 장식 읽힘 방지
  • 장식 이미지를 추가로 정리할 기준 확보

가장 큰 수확은 “작은 이미지는 그냥 둬도 된다”는 생각이 바뀐 것입니다. 용량은 작아도 요청과 레이아웃 안정성에 영향을 줄 수 있었습니다.

장식 이미지 대체 체크리스트

작은 아이콘도 렌더링 흐름의 일부

1KB도 안 되는 아이콘 이미지 하나를 줄이는 일은 용량만 보면 큰 의미가 없어 보입니다. 하지만 실제 페이지에서는 요청 하나, 이미지 디코딩 하나, 레이아웃 이동 가능성 하나가 같이 줄어듭니다.

제가 얻은 기준은 단순합니다. 정보를 전달하지 않는 장식 이미지라면 먼저 CSS나 문자로 바꿀 수 있는지 봅니다. 바꿀 수 없다면 최소한 width, height, 빈 alt를 제대로 넣습니다.

오래된 사이트에는 작은 장식 이미지가 많이 남아 있습니다. 하나씩 보면 사소하지만, 모아보면 요청 수와 유지보수 비용을 줄일 수 있습니다. 특히 메뉴처럼 반복 출력되는 요소라면 작은 아이콘 하나도 페이지 안정성에 영향을 줄 수 있었습니다.

댓글 남기기