Menu

CSS ::before와 ::after 가상 요소 사용법

::before와 ::after는 CSS만으로 요소의 첫 번째와 마지막 자식 자리에 생성된 콘텐츠를 넣어요. content 속성, 빈 content가 꼭 필요한 이유, 위치 지정, attr() 툴팁, 카운터, 동작하지 않는 곳을 알아봐요.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

::before와 ::after가 하는 일

::before는 요소의 첫 번째 자식으로, ::after는 마지막 자식으로 상자를 넣어요. 상자에 무엇이 들어갈지는 content 속성이 정해요. HTML에는 아무것도 추가되지 않아요. 브라우저가 CSS에서 만들어 내요.

HTML에는 9와 Tests pass만 있어요. 달러 기호, "/ month" 레이블, 체크 표시는 모두 CSS에서 나와요. 위 예제처럼 덮어쓰지 않으면 요소의 스타일(글꼴, 색)을 상속받아요.

문법

selector::before {
  content: "text";   /* required */
  /* any other styles */
}

selector::after {
  content: "";       /* empty string: a box with no text */
}
content 값결과
"text"문자열. 줄바꿈은 "\A"(white-space: pre와 함께), 유니코드 문자는 "\2192"(→)처럼 써요
""빈 상자, 도형과 장식용
attr(data-label)요소의 속성 값
counter(step)CSS 카운터의 값
open-quote / close-quote요소의 언어에 맞는 따옴표
none 또는 normal가상 요소 없음(normal이 기본값)

content는 필수예요. 없으면 다른 속성을 얼마나 주든 ::before와 ::after는 만들어지지 않아요.

content: ""로 장식 도형 만들기

content: ""를 주면 가상 요소는 크기와 색을 정할 수 있는 빈 상자가 돼요. 기본은 인라인이고, 인라인 상자는 width와 height를 무시하니 display: block, inline-block, position: absolute 중 하나를 주세요.

가상 요소 위치 지정하기

요소 위나 주변에 놓이는 장식이라면 가상 요소에 position: absolute를, 요소 자체에 position: relative를 줘서 오프셋이 요소를 기준으로 계산되게 하세요.

가상 클래스와 함께 쓸 때는 순서에 주의하세요. 상태가 먼저, 그다음 가상 요소예요. .link:hover::after이지 .link::after:hover가 아니에요.

attr()로 속성 읽기: 툴팁

attr()는 속성 값을 content로 가져와서, 규칙 하나로 요소마다 다른 텍스트를 보여 줄 수 있어요.

hover에서만 보이는 툴팁은 키보드와 터치 사용자에게 보이지 않아요. 중요한 내용이라면 텍스트를 페이지에 두거나, 요소에 tabindex="0"을 주고 :focus에서도 보여 주세요.

카운터로 번호 매기기

CSS 카운터와 ::before를 쓰면 숫자를 직접 적지 않고 번호를 매길 수 있어요.

단계를 추가하거나 지우면 번호가 알아서 바뀌어요.

::before와 ::after가 동작하지 않는 곳

가상 요소는 요소 안, 태그 사이에 들어가요. 그런 안쪽이 없는 요소는 가상 요소를 보여 줄 수 없어요.

  • <img>, <video>, <iframe> (대체 요소)
  • <input>, <select>, <textarea> (폼 컨트롤), 그리고 <br>

일부 브라우저는 체크박스나 깨진 이미지에 그려 주기도 하지만 일관되지 않아요. 대신 감싸는 요소에 가상 요소를 두세요. <span class="field"><input></span>으로 감싸고 .field::after를 꾸미면 돼요.

자주 하는 실수

  • content 없음. 아무것도 안 보이는 가장 흔한 이유예요. content: ""를 추가하세요.
  • 인라인 가상 요소에 크기 주기. display: block, inline-block, position: absolute를 지정하기 전에는 width와 height가 아무 효과도 없어요.
  • 상태와의 순서 오류. a:hover::after는 동작하고, a::after:hover는 동작하지 않아요.
  • 위치가 지정된 부모 없는 absolute. 그러면 가상 요소가 먼 조상을 기준으로 정렬돼요. 요소에 position: relative를 추가하세요.
  • 진짜 콘텐츠를 CSS에 넣기. content의 텍스트는 선택하거나 복사할 수 없어요. 정보는 HTML에 두세요.

자주 묻는 질문

CSS에서 ::before는 무엇을 하나요?

선택한 요소의 첫 번째 자식이 되는 가상 요소를 만들고, content 속성에 적은 내용으로 채워요. ::after는 마지막 자식으로 같은 일을 해요. 둘 다 HTML에는 없어서 아이콘, 레이블, 장식에 편리해요.

::before나 ::after가 보이지 않는 이유는 무엇인가요?

가장 흔한 이유는 content 속성이 빠진 거예요. 없으면 가상 요소가 만들어지지 않아요. 빈 장식 상자에는 content: ""를 쓰세요. 다른 원인으로는 너비와 높이를 준 인라인 가상 요소(display: block이나 inline-block을 주세요), 또는 <img>, <input>처럼 가상 요소를 담을 수 없는 요소가 있어요.

:before와 ::before는 무엇이 다른가요?

동작은 같아요. 콜론 두 개인 ::before는 가상 요소임을 표시하는 현재 문법이고, 콜론 하나인 :before는 CSS2의 옛 표기예요. 브라우저는 before, after, first-line, first-letter에 대해 여전히 받아 줘요.

img나 input에 ::before를 쓸 수 있나요?

안정적으로는 안 돼요. 가상 요소는 요소의 콘텐츠 안에 들어가는데, <img> 같은 대체 요소와 <input> 같은 폼 컨트롤에는 그럴 콘텐츠 상자가 없어요. 요소를 <span>이나 <div>로 감싸고 가상 요소를 감싼 요소에 두세요.

스크린 리더가 CSS ::before 콘텐츠를 읽나요?

대체로 읽어요. content의 텍스트는 보통 접근성 이름에 포함되지만, 선택하거나 복사할 수는 없어요. 진짜 정보는 HTML에 두고, 가상 요소는 장식과 작은 시각적 신호에 쓰세요.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기