월별 글 목록: 2014년 7월월

조건부 주석 Conditional Comment 를 이용한 IE 버전별 지원의 문제 & Javascript를 통한 해결책

IE에서 하위 버전 지원을 위해서 조건부 주석 Conditional Comment 이라는 것을 지원하고 있습니다.
예를 들어, 다음과 같습니다.


이 문구는 모든 브라우저에서 나타납니다.

HTML 주석문 사이에 [if lt IE 7] 같은 조건을 명시하면 타 브라우저는 해당 부분 전체를 주석문으로 인식하지만 조건에 해당하는 IE 버전에서는 조건부 주석 내부의 코드를 인식합니다.

HTML5 Boilerplate에서는 조건부 주석을 다음과 같이 활용하고 있습니다.





 <html class="no-js"> 

브라우저의 버전에 따라 html에 태그에 각기 다른 클래스를 할당해주는 방식입니다. 이런 식으로 html에 클래스가 할당되면

.box {
    background: rgba( 0, 0, 0, 0.7 );
}
.lt-ie9 .box {
    background: url( "blank70.png" );
}

위와 같은 스타일 시트 구성이 가능합니다.
rgba 같은 표현식을 정확히 표현하지 못하는 IE8 이하의 버전에서는 png를 통해서 반투명 배경 처리를 한다든가 하는 처리가 가능해지죠.

유용하게 사용되는 방법이지만 두 가지 문제점이 있습니다.

첫째로, IE11에서 더 이상 조건부 주석을 지원하지 않는다는 겁니다. 게다가 개발자 모드에서 하위 버전 에뮬레이션을 돌릴 때에도 조건부 주석은 동작하지 않습니다. 조건부 주석을 이용해서 jQuery 1.x와 2.x를 동시에 사용하는 방법등을 테스트할 때 아주 곤란한 문제가 발생합니다.
둘째로, 오늘 이 포스팅의 핵심인데… 호환성 보기에 대한 X-UA-Compatible 메타태그에 오동작을 유발한다는 점입니다.

아직 정확히 왜 그런 문제가 발생하는지는 알 수가 없습니다. MSDN에도 해당 내용이 나온 페이지는 아직 찾질 못했고요, 스택오버플로의 답변 중 ‘조건부 주석은 head 태그 이후에만 사용하는 것이 좋다’는 내용이 유일합니다.
테스트를 해보니, html 여는 태그에 조건부 주석을 사용할 경우 <meta http-equiv=”X-UA-Compatible” content=”IE=edge”> 태그 자체가 동작하지 않는 문제가 있었습니다.

현재로선 html 여는 태그에 클래스를 추가하는 부분은 Modernizr 같은 라이브러리와 같이 자바스크립트상에서 동적으로 해결하는 방법이 가장 나은 대안이 될 것 같습니다.

// UserAgent를 이용해서 IE인지를 체크합니다.
var ua = navigator.userAgent.toLowerCase();
// IE7엔 브라우저 엔진명인 Trident가 없고 IE11엔 MSIE란 문자열이 없으므로 두 가지 경우를 다 체크합니다.
if( ua.indexOf( 'msie' ) != -1 || ua.indexOf( 'trident' ) != -1 ) {
	var version = 11;
	ua = /msie ([0-9]{1,}[\.0-9]{0,})/.exec( ua );
	if( ua )
	{
		version = parseInt( ua[ 1 ] );
	}
	var classNames = '';
	// 기존의 방식에 is-ie 라는 클래스도 추가해봅니다.
	classNames += ' is-ie';
	// 마찬가지로 기존의 방식에 현재 버전 표시를 추가해봅니다.
	classNames += ' ie' + version;
	for( var i = version + 1; i <= 11; i++ ) {
		classNames +=  ' lt-ie' + i;
	}
	// html 태그에 클래스를 추가합니다.
	document.getElementsByTagName( 'html' )[ 0 ].className += classNames;
}

크게 문제 없이 동작하고 Modernizr 같은 라이브러리와 딱히 충돌하지도 않네요. 일단 IE Checker라는 이름으로 깃허브에도 소스 공개 해두었습니다. https://github.com/Unk/IE-Checker 워낙에 코드가 짧은데 굳이 별도의 파일이 필요하냐 하시는 분들은 minify 된 코드를 복사해서 다른데에 붙여넣고 사용하세요.