개발&Development/웹

p안에 div를 넣으면

겐도 2008. 3. 10. 14:25
리퍼러 중에 이런 문제로 고심하는 분들을 위해 왜 p안에 div를 넣으면 안되는지를 간략히 살펴보자.

우선 W3의 HTML 4.01 스펙부터 보자. 9.3.1 Paragraphs : the p element를 보면 p 태그는 inline 요소만을 자식으로 가질 수 있다고 한다. div는 block 그룹에 속한다. 따라서 p안에 div를 쓰면 잘못된 것이다. 헌데 다들 잘 쓰고 있지 않은가? 심지어 텍스트큐브나 티스토리 에디터도 이런 식으로 html을 생성하기도 한다(정확히는 각 브라우저의 위지윅 에디팅 모듈의 버그라고 할 수 있지만). 많은 웹사이트 코더들이 이 부분을 묵과한다.

아래의 코드를 보자.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<style type="text/css">
    p { border:black thick solid; }
    div { border:red thin solid; }
</style>
</head>
<body>
<p>
    <div>
        테스트문장
    </div>
</p>
<p>
    정상적인 문단
</p>
</body>
</html>
"테스트문장"이 전형적으로 실수한 부분이고 아래는 정상적이다. p 영역이 정확히 어딘지 알기 위해 보더를 주었다.
사용자 삽입 이미지

IE 7 on Windows XP Korean


우선 IE7. p의 보더가 두번 보인다. 이는 사파리도 비슷하다.
사용자 삽입 이미지

Safari 3 on Mac OS X Leopard

단란이 정확히 "테스트문장"을 감싸지 못하고 있다.

파이어폭스는 약간 다르다.
사용자 삽입 이미지

FireFox 2 on Mac OS X Leopard

아래쪽이 없다. 이는 부정확한 태그에 대한 핸들링 차이이다. 브라우저 입장에서 표준 좀 어겼다고 해서 "이거 해석 못하겠임"이라고 할 수 없는거 아닌가.
사용자 삽입 이미지

배째라 브라우저라면?

그래서 대부분의 브라우저가 에러 핸들링을 하는데 이것이 브라우저마다 약간씩 다르다. 물론 표준 밖의 내용이라 개발자 마음대로(?) 처리할 수 있다. 새로운 브라우저가 나올때 마다 어떻게 처리될지는 아무도 모른다.

IE와 Safari의 경우 p안에서 div를 만나는 순간 </p> 태그를 빼먹었다고 판단한다. 단락이 끝난다. 그리고 div가 시작되며 다시 </p>를 만나는 순간 이번엔 시작 태그<p>가 없다고 판단 빈 단락을 만든다. "테스트문장" 아래의 줄이 생기는 이유이다. 허나 FF는 뒷부분의 </p>를 엄하게 들어온 것으로 보고 discard 한다.

IE, Safari는
<body>
<p></p>
<div>
    테스트문장
</div>
<p></p>
<p>
    정상적인 문단
</p>
</body>

Firefox는
<body>
<p></p>
<div>
    테스트문장
</div>
<!-- 무시 </p> -->
<p>
    정상적인 문단
</p>
</body>
이런식으로 변환된다고 보면 되겠다.

이런걸 보고 브라우저가 좋네 마네 이야기 해서는 안되는 것이다. 표준을 벗어났을 때의 이야기기 때문이다. 이런 문제들이 쌓이고 쌓이면 복잡한 페이지에선 브라우저별로 정확히 렌더링 결과를 같게 만드는 것이 어려워 진다. HTML 구조가 다른 셈인데 같은 CSS로 어떻게 처리하리오.

표준을 지키는 것은 매우 중요하다. 표준을 제대로 이해하지 못하고 사용하게 되면 저련 문제에 당하는 것이다. HTML로 밥먹고 살고 있다면 HTML 스펙은 한번쯤은 정독하자. CSS를 먼저 공부할 것이 아니라 HTML부터다.

덧. Safari의 핸들링이 확실치는 않습니다. 제가 잘못 분석한 것이라면 코멘트 주세요. FF와 IE는 DOM을 통해 확인하였습니다.