개발

#:~:text= 링크로 페이지 속 문장까지 이동·강조하기 — 한글은 조사까지 맞춰야 하고, 강조색은 ::target-text 로 바꾼다

  • 4th October 2026
  • 5 min read

긴 안내 페이지나 약관, 문서 링크를 보내면서 "세 번째 단락 중간쯤 보세요"라고 덧붙인 적이 있을 것이다. 받는 사람은 페이지를 열고 스크롤을 내리면서 그 문장을 찾아야 한다. 단락마다 id가 달려 있으면 #id로 보낼 수 있지만, 남이 만든 페이지에는 그런 게 없는 경우가 대부분이다.

주소 끝에 #:~:text=찾을말을 붙이면 이 문제가 풀린다. 브라우저가 페이지를 연 뒤 그 문장을 찾아 화면 가운데로 스크롤하고 강조 표시까지 해 준다. 페이지 쪽에서 준비할 것은 없다. 이 기능(텍스트 프래그먼트)은 2024년 10월 파이어폭스 131이 합류하면서 Baseline이 됐고, 강조색을 CSS로 바꾸는 ::target-text는 2024년 12월 사파리 18.2로 Baseline이 됐다.

다만 한글로 쓸 때 알아야 할 규칙이 하나 있다. 단어의 일부만 적으면 찾지 못한다. 이 글은 크롬에서 그 규칙과 문법을 하나씩 재 본 결과다.

지금 이 페이지에서 눌러 보기

아래 상자에 예시 문장 두 개가 있다. 그 아래 링크를 누르면 이 페이지 안에서 텍스트 프래그먼트로 이동한다.

반품 접수는 상품 수령일로부터 14일 안에 해야 합니다.

포장을 마친 상자는 택배사에 직접 맡기면 됩니다.

크롬에서 확인했다. 지원하지 않는 브라우저에서는 링크를 눌러도 페이지가 움직이지 않을 뿐 오류는 나지 않는다.

기본 문법

https://example.com/guide#:~:text=신청서는

# 뒤의 :~:가 "여기부터는 브라우저에게 주는 지시"라는 구분자다. 페이지의 스크립트는 이 부분을 보지 못한다. 실제로 이동한 뒤 location.hash를 읽으면 빈 문자열이 나왔다. 기존 해시 라우팅을 쓰는 페이지에 이 링크를 보내도 라우터가 엉뚱하게 반응하지 않는다는 뜻이다.

한글은 그대로 써도 되고 퍼센트 인코딩해도 된다. text=신청서는과 text=%EC%8B%A0%EC%B2%AD%EC%84%9C%EB%8A%94는 같은 결과였다. 메신저나 메일로 보낼 때는 링크가 중간에 끊기지 않도록 인코딩된 쪽이 안전하다.

한글은 어절 단위로 맞춰야 한다

테스트 페이지에 이런 문장을 넣고 하나씩 이동해 봤다.

환불은 결제일로부터 7일 이내에 신청할 수 있습니다. 신청서는 고객센터에서 받습니다.

text=결과
신청서는찾음
신청서못 찾음
신청못 찾음 (신청할, 신청서는 둘 다 있는데도)
결제일로부터찾음
결제일못 찾음
고객센터에서찾음
고객센터못 찾음
refund / refu찾음 / 못 찾음
REFUND찾음 (대소문자 무시)

명세는 찾은 범위의 앞뒤가 단어 경계여야 한다고 정해 두었다. 영어에서는 refu가 refund에 걸리지 않게 하려는 규칙이다. 그런데 크롬은 한국어의 단어 경계를 띄어쓰기로 잡는다. 조사가 붙은 어절 전체가 하나의 단어로 취급된다. 그래서 신청서는 신청서는 안에 분명히 들어 있는데도 찾지 못한다.

링크를 손으로 만들 때는 본문에 적힌 어절을 조사까지 그대로 복사하면 된다. 단어 하나보다 문장 일부를 통째로 적는 편이 더 확실하다.

#:~:text=신청서는%20고객센터에서%20받습니다

범위, 앞뒤 문맥, 여러 개

긴 단락 전체를 가리키고 싶을 때는 처음과 끝을 쉼표로 이어 범위로 적는다. 단락 경계를 넘어가도 된다.

#:~:text=환불은,무료입니다

같은 말이 페이지에 여러 번 나오면 첫 번째로 간다. 특정 위치를 고르려면 앞뒤 문맥을 붙인다. 앞 문맥은 앞말-,, 뒤 문맥은 ,-뒷말이다. 문맥 자체는 강조되지 않고 위치를 고르는 데만 쓰인다.

#:~:text=있습니다.-,신청서는          앞 문맥
#:~:text=신청서는,-고객센터에서      뒤 문맥

앞 문맥에는 마침표까지 넣어야 했다. 받습니다-,배송비는는 실패했고 받습니다.-,배송비는는 성공했다. 앞 문맥과 찾을 말 사이에는 공백만 올 수 있어서, 마침표가 끼어 있으면 맞지 않는다. 앞 문맥이 이전 단락의 끝에 있어도 상관없었다.

&text=로 여러 개를 한 번에 강조할 수 있다. 전부 강조되고, 스크롤은 주소에 먼저 적은 것으로 간다. 페이지에서 먼저 나오는 것이 아니다. 찾지 못한 것이 섞여 있으면 그것만 건너뛴다.

#:~:text=배송비는&text=환불은     배송비는 쪽으로 스크롤, 둘 다 강조

id 와 함께 쓰면 못 찾을 때 대비가 된다

페이지 문구가 바뀌면 텍스트 프래그먼트는 조용히 실패하고 페이지 맨 위가 열린다. 해당 위치에 id가 있다면 앞에 같이 적어 둘 수 있다.

#refund:~:text=신청서는

문장을 찾으면 그 문장으로 가고, 못 찾으면 #refund 요소로 간다. 두 경우 모두 location.hash는 #refund로 남고 :target도 그 요소에 걸렸다.

::target-text 로 강조색 바꾸기

크롬의 기본 강조색은 연보라(#E9D2FD)다. 사이트 색과 맞지 않으면 ::target-text로 바꾼다.

::target-text {
  background-color: #ffe066;
  color: #111;
}
기본색
신청서는 이라는 어절이 연보라색 배경으로 강조된 문장
::target-text { background-color: #ffe066 }
배송비는 이라는 어절이 노란색 배경으로 강조된 문장
크롬 154에서 #:~:text= 로 이동한 직후

쓸 수 있는 속성은 정해져 있다. ::selection과 같은 하이라이트 의사 요소라서, 명세는 레이아웃에 영향을 주지 않는 속성만 허용한다. color, background-color, text-decoration 계열, text-shadow, 그리고 SVG 텍스트용 fill-color·stroke-color·stroke-width다.

font-size: 40px, padding, font-weight: bold, 물결 밑줄, 그림자를 한꺼번에 넣어 봤다. 글자 크기·여백·굵기는 무시되고, 밑줄과 그림자만 적용됐다.

배송비는 어절에 노란 배경, 빨간 물결 밑줄, 분홍 그림자만 적용되고 글자 크기와 굵기는 그대로인 문장
font-size·padding·font-weight 는 무시, text-decoration·text-shadow 는 적용

색을 바꿀 때는 강조된 글자가 배경 위에서 읽혀야 한다. background-color만 바꾸면 글자색은 원래 색 그대로 남으므로, 어두운 강조색을 고르면 본문 글자가 묻힌다. KWCAG 2.2 5.4.3 텍스트 콘텐츠의 명도 대비의 4.5:1 기준을 강조 배경에도 똑같이 적용하고, color를 함께 지정해 두는 편이 안전하다.

범위를 좁히고 싶으면 앞에 선택자를 붙인다. 하이라이트 의사 요소는 문장을 담고 있는 요소를 기준으로 스타일을 받기 때문에, .article ::target-text라고 쓰면 본문 안에서만 노란색이 된다. 위 "눌러 보기" 상자의 두 번째 문장이 이 방식이다.

링크 만들기

직접 문법을 쓸 필요는 거의 없다. 크롬과 엣지는 문장을 드래그한 뒤 오른쪽 클릭 메뉴의 "하이라이트 링크 복사"로 이 주소를 만들어 준다. 앞뒤 문맥이 필요하면 알아서 붙여 준다. 직접 만들어야 할 때는 위 규칙대로, 조사까지 포함한 어절이나 문장 일부를 적는다.

정리

  • #:~:text=는 페이지 수정 없이 특정 문장으로 이동하고 강조하는 링크다. 2024년 10월부터 모든 주요 브라우저가 지원한다.
  • 단어 경계 규칙 때문에 한글은 조사까지 포함한 어절 전체를 적어야 한다. 신청서로는 신청서는을 찾지 못한다.
  • 시작,끝은 범위, 앞말-,와 ,-뒷말은 문맥이다. 앞 문맥에는 문장부호까지 넣는다. &text=를 여러 개 쓰면 주소에 먼저 적은 것으로 스크롤한다.
  • #id:~:text=로 적으면 문장을 못 찾았을 때 id로 이동한다.
  • ::target-text는 색·배경·밑줄·그림자만 바꿀 수 있다. 배경을 바꾸면 글자색도 같이 정한다.

함께 읽으면 좋은 글