[CSS] 왜 <span>은 수직 중앙 정렬이 안 맞고, <img>는 맞을까?

2025. 9. 17. 11:09CSS

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

반응형

UI 작업하다 보면 이런 경험 있으실 거예요.
텍스트 옆에 작은 뱃지나 아이콘을 붙이고 싶은데, <span>으로 만들면 수직 중앙이 애매하게 어긋납니다.

<strong>타이틀 영역입니다 <span>뱃지</span></strong>
strong {
    display: inline-block;
    color: #131518;
    font-size: 16px;
    font-style: normal;
    font-weight: 700;
    line-height: 22px;
    word-break: keep-all;

    >span {
      margin-left: 5px;
      color: #99A1A8;
      font-size: 13px;
      font-style: italic;
      font-weight: 400;
      line-height: 16px;
    }
  }

랜더링된 화면


👆 이렇게 했는데도 <span>이 살짝 아래로 치우쳐 보이는 경우가 있죠.

그런데 신기하게도 같은 자리에 <img>를 넣으면 중앙 정렬이 딱 맞습니다.

<strong>타이틀 영역입니다 <img src="./images/badge.svg" alt="" /></strong>
img {
  width: 20px;
  height: 11px;
}

뱃지 이미지 처리

 

 

왜 이런 차이가 생길까요?

span과 img의 차이

span: 텍스트 계열 요소

  • <span>은 원래 텍스트를 감싸는 inline 요소입니다.
  • 브라우저는 이를 baseline(문자가 놓이는 기준선)을 기준으로 정렬하려고 해요.
  • 그래서 line-height를 줄여도 실제 박스가 고정되지 않고, 폰트 메트릭스(ascender, descender)에 따라 살짝 어긋나게 보입니다.

즉, line-height만으로는 완벽한 “아이콘 박스”를 만들 수 없어요.

img: 치환 요소 (Replaced Element)

  • <img>는 텍스트가 아니라 외부 리소스로 대체되는 치환 요소입니다.
  • 브라우저는 <img>를 하나의 고정 박스로 인식합니다. (width × height)
  • baseline 영향이 적기 때문에, vertical-align: middle이 적용되면 부모 라인박스 기준으로 정확히 중앙에 옵니다.

결국, 같은 inline 요소여도 성격이 달라서 정렬 결과가 다른 거죠.

span을 img처럼 쓰고 싶다면?

아이콘을 반드시 <span>으로 구현해야 할 때가 있습니다. 예를 들어, 접근성 텍스트 처리, 폰트 아이콘, CSS 배경 아이콘 등등

이때는 아래처럼 처리하면 됩니다.

 

strong > span {
  display: inline-block;   /* span을 박스처럼 */
  height: 11px;            /* 고정 높이 */
  vertical-align: middle;  /* 부모 기준 중앙 정렬 */
  line-height: normal;     /* baseline 영향 제거 */
}

line-height만 주면 안 될까?

많이 하는 실수가 line-height: 11px만 주는 겁니다.
이 경우 span은 여전히 텍스트 박스이기 때문에, 브라우저가 baseline을 기준으로 정렬해 버립니다.
그 결과 중앙이 미묘하게 어긋날 수 있어요.

👉 그래서 반드시 height와 line-height: normal을 함께 써주는 게 안전합니다.

 


오늘 포스트에서는 span과 img의 동작 차이를 비교하며, 실무에서 헷갈리기 쉬운 수직 중앙 정렬의 비밀을 짚어봤습니다.

 

 

 

[React] React 개발 속도를 높이는 나만의 VS Code 스니펫 설정

리액트 컴포넌트를 작성하다 보면 반복되는 코드가 참 많습니다. 특히 className 처리, 인라인 스타일 작성, SCSS 모듈과 함께 컴포넌트를 구성하는 기본 템플릿까지~ 매번 복붙 하거나 타이핑하기

dev-chim.tistory.com

 

 

[Javascript] 직관적이고 유연한 슬라이더! Slick 슬라이더를 통해 갤러리를 구현해보세요.

웹 사이트에서 이미지 갤러리나 캐러셀처럼 슬라이더가 필요하다면, Slick 플러그인으로 간단하게 구현할 수 있습니다.  slick - the last carousel you'll ever needslick is a responsive carousel jQuery plugin that sup

dev-chim.tistory.com

 

 

[Safari] 사파리 브라우저로 iPhone 웹 페이지 디버깅하는 방법 (feat. 웹 인스펙터)

사파리 브라우저로 iPhone 웹 디버깅하는 방법에 대해서 알아보겠습니다. 웹 페이지 디버깅웹 개발을 하다 보면 데스크탑 브라우저뿐만 아니라 실제 모바일 디바이스에서의 동작을 확인하고 디

dev-chim.tistory.com

 

 

[AI] 손필기는 이제 그만! 클로바 노트(CLOVA Note)의 음성 메모 혁신을 경험하세요!

클로바노트는 음성인식, 자연어 처리 등의 AI 기술을 활용한 회의록 관리 서비스입니다. 이 서비스는 긴 문장과 비정형화된 대화를 인식하는 데 특화된 음성인식 엔진을 사용하며 참석자의 목소

dev-chim.tistory.com

 

 

[Git] Git Stash : 변경사항을 임시로 저장하는 방법

보통 개발자들은 여러 작업을 동시에 진행하거나, 작업 중에 예기치 않은 변경이 필요할 때가 있습니다. 이런 상황에서는 현재 작업 중인 변경사항을 커밋(commit)하기 전에 보관할 필요가 있습니

dev-chim.tistory.com

 

반응형