← 모두의 툴

이모지 하나가 글자수 2~11개로 세지는 이유 — SNS 글자수 제한의 함정

가이드 · 2026.08.20 최종 확인

화면에는 이모지 하나(😀)가 딱 한 글자로 보이는데, 글자수를 세는 프로그램에 넣으면 갑자기 2글자로 잡히는 경험을 해본 적이 있을 겁니다. 가족 이모지(👨‍👩‍👧‍👦)처럼 여러 이모지가 겹쳐 보이는 경우는 더 심해서, 프로그램에 따라 최대 11글자까지도 잡힙니다. 이건 버그가 아니라 유니코드가 문자를 저장하는 방식과 "글자수를 어떤 기준으로 셀 것이냐"의 차이에서 나오는 현상입니다. 이모지 카운터의 실제 코드를 근거로 세 가지 서로 다른 "글자수" 개념을 정리하고, 트위터/X·인스타그램 같은 SNS 글자수 제한과 어떻게 연결되는지 설명합니다.

1. 이모지는 왜 UTF-16에서 두 조각으로 쪼개지는가

유니코드는 전 세계 문자에 고유 번호(코드포인트)를 부여합니다. 대부분의 이모지는 U+1F600(😀) 같은 코드포인트를 갖는데, 이 값은 16비트로 표현할 수 있는 범위(0~FFFF)를 넘어서는 "확장 영역"에 있습니다. JavaScript 문자열은 내부적으로 UTF-16 인코딩을 쓰기 때문에, 16비트를 넘는 문자는 서로게이트 쌍(surrogate pair)이라는 방식으로 2개의 16비트 코드유닛에 나눠 담습니다. 그 결과 JavaScript의 string.length 속성(코드유닛 개수를 세는 방식)으로 이모지 하나를 재면 1이 아니라 2가 나옵니다. 사람 눈에는 한 글자, 컴퓨터 내부적으로는 두 조각인 셈입니다.

2. ZWJ: 이모지 여러 개를 하나로 붙이는 보이지 않는 접착제

가족·직업·커플 이모지처럼 여러 사람이 함께 나오는 이모지는 실제로 존재하는 단일 문자가 아닙니다. 👨‍👩‍👧‍👦는 "남자 어른" + ZWJ(Zero-Width Joiner, U+200D, 폭이 0인 결합 문자) + "여자 어른" + ZWJ + "여자아이" + ZWJ + "남자아이", 이렇게 4개의 독립된 이모지가 눈에 보이지 않는 접착제 3개로 이어진 하나의 시퀀스입니다. 폰트와 브라우저가 이 시퀀스를 인식하면 화면에는 합쳐진 하나의 그림으로 렌더링하지만, 문자열 데이터 안에는 여전히 7개의 코드포인트(이모지 4개+ZWJ 3개)가 그대로 들어 있습니다. 지원하지 않는 오래된 환경에서 이 이모지가 4명이 나란히 붙어 보이는 것도 이 때문입니다.

3. 모두의 툴 이모지 카운터는 실제로 무엇을 세는가

이모지 카운터의 소스 코드를 보면, 이모지 개수(총 이모지·종류)는 Intl.Segmenter라는 브라우저 내장 API로 텍스트를 "그래핌 클러스터(grapheme cluster, 사람이 인지하는 하나의 글자 단위)" 단위로 쪼갠 뒤, 이모지 속성을 가진 클러스터만 걸러서 셉니다. 이 방식은 서로게이트 쌍이나 ZWJ 시퀀스를 모두 하나의 단위로 정확히 묶어주기 때문에, 가족 이모지도 "1개"로 정확히 집계됩니다. 반면 화면 하단의 "전체 문자" 수치는 [...text].length(스프레드 연산자로 문자열을 코드포인트 단위로 펼친 배열의 길이)를 사용합니다. 이는 코드유닛 기준인 string.length와도 다른, 세 번째 기준입니다.

4. 코드포인트·코드유닛·그래핌 — 같은 이모지, 다른 숫자 셋

가족 이모지 👨‍👩‍👧‍👦 하나를 놓고 세 가지 방식으로 세면 결과가 모두 다릅니다.

측정 방식사용하는 기준👨‍👩‍👧‍👦의 값
그래핌 클러스터(Intl.Segmenter)사람이 인지하는 글자 단위 — 이모지 카운터의 "총 이모지" 집계 방식1
코드포인트([...str].length)유니코드 문자 번호 개수 — 이모지 카운터의 "전체 문자" 집계 방식7 (이모지 4 + ZWJ 3)
UTF-16 코드유닛(str.length)JavaScript 순수 .length 기준 — 대부분의 SNS 글자수 카운터 뼈대11 (서로게이트 쌍 4×2 + ZWJ 3×1)
기본 이모지 😀 하나는 그래핌 1, 코드포인트 1, 코드유닛(.length) 2입니다. 제목의 "2~11개"는 이 두 극단 — 서로게이트 쌍만 있는 기본 이모지(2)와, ZWJ로 여러 개가 결합된 복합 이모지(11 이상)의 범위입니다.

5. Twitter/X·Instagram 글자수 제한과의 실전 연결

SNS 플랫폼의 글자수 제한은 대부분 순수 .length(코드유닛)와 비슷한 방식이거나 그와 유사한 가중치 규칙을 적용합니다. 즉 화면에는 이모지 하나로 보여도 실제로는 2글자 이상을 소모하며, ZWJ로 결합된 복합 이모지는 훨씬 더 많은 글자수를 잡아먹습니다. 짧은 문구에 이모지를 여러 개, 특히 가족·커플·직업 계열의 결합 이모지를 자주 쓰면 눈에 보이는 글자 수보다 훨씬 빨리 글자수 제한에 도달할 수 있습니다. 캡션이나 트윗을 작성하기 전에 실제로 몇 글자로 잡히는지 이모지 카운터글자수 세기로 미리 확인하는 것이 안전합니다.

6. 이모지를 코드 단위까지 뜯어보고 싶다면

특정 이모지가 정확히 몇 개의 코드포인트로 구성되어 있는지, ZWJ가 몇 번 들어갔는지 문자 단위로 직접 확인하고 싶다면 유니코드 인스펙터를 사용하세요. 반대로 이모지를 텍스트에서 모두 제거하고 순수 글자수만 세고 싶다면 이모지 제거기로 먼저 걸러낸 뒤 글자수를 재는 것이 정확합니다.

자주 묻는 질문

Q. 왜 기본 이모지도 1글자가 아니라 2글자로 세지나요?

이모지의 유니코드 코드포인트가 16비트로 표현 가능한 범위를 넘기 때문입니다. JavaScript 문자열은 UTF-16을 쓰므로 이런 문자를 서로게이트 쌍이라는 2개의 코드유닛으로 나눠 저장하고, .length는 이 코드유닛 개수를 셉니다.

Q. 이모지 카운터의 "전체 문자" 수치와 실제 SNS 글자수 제한이 다르게 나오는 이유는?

이모지 카운터의 "전체 문자"는 코드포인트 기준([...text].length)으로 집계되는 반면, 대부분의 SNS 글자수 제한은 UTF-16 코드유닛(.length)에 가까운 방식을 씁니다. 기본 이모지는 코드포인트 1개가 코드유닛 2개로 늘어나므로, SNS 쪽 글자수가 더 크게 나올 수 있습니다.

Q. 피부색이 적용된 이모지(👋🏽)도 여러 글자로 세지나요?

네. 피부색 변형은 기본 이모지 뒤에 별도의 수정자(modifier) 코드포인트가 붙는 방식이라, 코드포인트·코드유닛 기준으로는 기본 이모지보다 글자수가 더 늘어납니다. 다만 그래핌 클러스터 기준(사람이 보는 단위)으로는 여전히 1개로 인식됩니다.

Q. ZWJ로 결합된 이모지는 항상 모든 기기에서 하나로 보이나요?

아닙니다. 폰트와 운영체제가 해당 ZWJ 시퀀스를 지원하지 않으면, 결합되지 않은 개별 이모지들이 나란히 표시될 수 있습니다. 데이터 상으로는 항상 여러 코드포인트가 이어진 시퀀스이며, 렌더링만 환경에 따라 달라집니다.