CSS핵(hack)
정리 그리고 주요버그 |
크로스브라우징을 하기위해 작업을 하다보면 브라우저의 디폴트값이 각기 틀리고 각각의 버그가
있기에
어려움이 많습니다.
하지만 어떤 환경에서도 페이지가 동일하게 보여야 하기에 hack으로 해결하는 부분들이
많습니다.
가급적 hack 사용을 자제하고 css작성을 할때 브라우저의 특성을 고려해서 작성하는게
좋습니다.
hack은 완전한 해결책이 될 수 없으며 페이지에 다른 영향을 끼칠 가능성이 있습니다.
일단 알려진 핵들을 정리하겠습니다. 어떤한 문제가 발생시 많은 테스트가 필요합니다.
알려진 핵을 사용하여도 틀린 결과물도 종종 발생합니다.
|
|
star
hack |
셀렉트 앞에 *html를
붙이면, Win IE 4~6, Mac IE 4~5 등에는 스타일이 적용되고, 그 외의
브라우저에서는
적용되지 않는다.
*html p { color:white; } |
|
|
underscore
hack |
프로퍼티의 가장
앞부분에 언더스코어(_)를 붙이면, Win IE 4~6에서 스타일이 적용되고, 다른
브라우저에서는
적용되지 않는다.
p { _color:white; } |
|
|
hash
hack |
프로퍼티의 앞에
샾(#)을 붙이면, Win IE 4~6, Mac IE 5, Opera 7,
Mozilla, Firefox에서는
스타일이 적용되고, 다른 브라우저에는 적용되지 않는다.
p { #color:white; } |
|
|
star
7 hack |
셀렉트의 앞에 html*을
붙이면, Win IE 5.5~6, Mac IE 5, Safari 등에서 스타일이
적용되고, 다른
브라우저에서는 적용되지 않는다. html*과 셀렉터사이에 스페이스를 넣지 않는다.
html*p { color:white; } |
|
|
!important
hack |
스타핵은 IE6을
구분하기 위하여 2가지의 선언을 해야한다.
그러나 한 규칙선언안에서 IE6 이하버전을 위한 선언과 다른 브라우저를 위한 선언을
하고 싶다면
!important 핵을 사용하면된다.
#top {
position:fixed !important;
position:static;
}
IE6 버전에서는 한 규칙안에 여러개의 속성을 사용할 수 없으므로,
첫번째 선언을
무시하고 두번째 선언을 적용한다.
나머지 브라우져에서는 important 키워드가 쓰여진 속성의 우선순위를 높게
인식하기때문에 첫번째
선언을 적용한다. |
|
|
주요
브라우저 호환성 확보를 위한 실전 비 표준 가이드 ‘CSS Hack’ |
Target
Browser |
CSS Hack |
Comment |
IE 5 ~ IE 7 |
#selector { *property:value
} |
DTD와 무관하게 작용 |
IE 5 ~ IE 6 |
#selector { _property:value
} |
DTD가 Quirks Mode인 경우
IE 7에도 작용함 |
IE 5 |
#selector { _property
/**/:value } |
DTD가 표준모드인 경우 작용 |
Firefox 2 |
#selector { property:default-value;
}
#selector, x:-moz-any-link {
property:firefox-value;
}
#selector, x:-moz-any-link, x:default {
property:default-value;
} |
첫 번째 라인은 희망하는 값
두 번째 라인은 FF 2 디버깅 값
세 번째 라인은 다시 희망하는 값
DTD가 표준모드인 경우 작용 |
Opera 9 |
html:first-child #selector
{ property:value; } |
Opera 9.5 부터 작용하지 않음
DTD와 무관하게 작용 |
|
|
|
Netscape
4 제외시키기 |
Netscape
4은 media속성값에 “screen”이외의 값이 올 경우 읽어 들이지 못하는 것을
이용한 방법이다.
<link
rel="stylesheet"
type="text/css" href="/css/style.css"
media="all" />이나
<link
rel="stylesheet"
type="text/css" href="/css/style.css"
media="screen, tv" />
라고 지정할 경우 Netscape 4은 읽어 들이지 못한다.
부분적으로 읽어들이지 못하게 하는 경우에는 Caio’s hack인 /*/*/를
이용한다.
보통 코멘트는 */으로 닫지만 /*/으로 닫게 되면 Netscape 4에서는 인식되지
않는다.
그 뒤에 평상시의 코멘트 /* */를 적어두면 그 뒤의 스타일은 Netscape
4에서도 문제없이
적용된다.
p {
/*/*/ color:white; /* */
} |
|
|
Mac
IE 4.5, Netscape 4 제외시키기 |
@import룰로
url()함수를 이용하여 외부 스타일시트를 이중인용부호로 지정한다.
Mac IE 4.5는 @import에 url()함수를 이용하는 경우, 단일 인용부호와
인용부호가
없는 것이 아니면 읽어 들이지 못한다. Netscape 4은 @import를 지원하지
않는다.
@import
url("/css/style.css") |
|
|
Mac
IE 5 제외시키기 |
CSS소스 안의
코멘트 서식을 /* \*/ 이라는 방식으로 기술한다. holly hack이라고 하며 그
뒤에 평상시의
코멘트 /* */를 적어두면 그 뒤의 스타일은 Mac IE 5에서도 문제없이 적용된다.
p {
/* \\*/ color:white; /* */
} |
|
|
Win
IE 4~5 제외시키기 |
셀렉터 바로 뒤에
/**/라고 적는다.
p/**/ { color:white;} |
|
|
Win
IE 4~5, Mac IE 4.5~5 제외시키기 |
프로퍼티와 값을
구분하는 콜론(;) 앞에 코멘트에 스페이스를 포함하여 /* */라고 적는다.
p { color/* */:white;} |
|
|
Win
IE 4~6, Mac IE 4, Netscape 4 제외시키기 |
셀렉터 앞에 html>body를
붙인다.
html>body p {
color:white;} |
|
|
Win
IE 6 제외시키기 |
프로퍼티와 값을
구분하는 콜론(;)의 앞에, 스페이스와 코멘트를 /**/라고 적는다.
p { color /**/:white;} |
|
|
xmlns
hack |
속성셀렉터를 이용하여,
html요소에 붙이는 xmlns속성을 스타일적용을 위하여 사용하는 방법.
Mozilla, Fire-fox, Opera 7/8, Safari, IE 7 등
속성셀렉터를 서포트하는
브라우저에서는 스타일이 적용되고, 다른 브라우저에서는 적용되지 않는다.
html[xmlns] h1 {
color:red; } |
|
|
:root
hack |
셀렉터의 앞에 :root를
붙이면, Mozilla, Firefox, Mac IE 5, Safari 등
:root유사클래스를
지원하는 브라우저에만 스타일이 적용되고, 다른 브라우저에서는 적용되지 않는다.
:root h1 { color:red; } |
|
|
Tantek
box model hack |
voice-family프로퍼티를
이용한 가장 유명한 박스모델핵.
div#content {
width:500px;
voice-family: "\"}\"";
voice-family:inherit;
width:400px;
} |
|
|
Win
IE 5용 패스필터 |
@media
tty {
i{content:"\";/*" "*/}}; @import
'/css/style.css';
{;}/*";}
}/* */ |
|
|
Win
IE 5-5.5용 패스필터 |
@media
tty {
i{content:"\";/*" "*/}}@m; @import
'/css/style.css';/*";}
}/* */ |
|
|
모던브라우저용
패스필터 |
@import
"null?\"\{";
@import "/css/style.css";
@import "null?\"\}"; |
|
|
|
IE
7 and below (IE7이하) |
*:first-child+html,
* html |
|
|
|
IE
7 and modern browsers only (IE7과 모던브라우저) |
|
|
Modern
browsers only (not IE 7) (IE7이외의 모던 브라우저) |
|
|
|
Opera
9와 Safari 동시적용 |
/*
safari only \\*/
html:\\66irst-child div.globalContainer{
margin: 0 0 0 18px;
}
/* end */ |
|
|
IE를
위한 조건부 주석 사용하기 |
마이크로소프트사는
다른 버전의 IE을 목표로 조건부 주석을 포함시켰다.
마크업, 자바스크립트, 자바스크립트 파일들, CSS, 외부 스타일시트를 포함하여 조건부
주석 안에
그 어떤 것도 삽입 할 수 있다.
조건부 주석을 사용하면 당신은 구체적인 버전의 IE를 집어내거나, 특정 버전 전,후의
어떤 버전이라도
집어낼 수 있다.
문법은 다음과 같다:
<!--[if lte IE 6]>
<p>This message will only appear in
versions of
Internet Explorer less than or equal to version
6.</p>
<![endif]-->
<!--[if gte IE 6]>
<p>This message will only appear in
versions of
Internet Explorer greater than or equal to
version 6.</p>
<![endif]-->
<!--[if gt IE 6]>
<p>This message will only appear in
versions of
Internet Explorer greater than version
6.</p>
<![endif]-->
<!--[if IE 5.5]>
<p>This message will only appear in
Internet Explorer
5.5.</p>
<![endif]-->
<!--Sample Conditional Stylesheet, IE6 and
below-->
<!--[if lte IE 6]>
<link type="text/css" rel="stylesheet"
href="css/ie6.css" />
<![endif]-->
조건부 스타일시트를 사용하면 다른 방법에 비해서 몇 가지 장점이 있다.
스타일시트는 다른 스타일시트와 구분되고, 다른 브라우저에 영향을 주는 등의 혼란이
없다.
IE6가 현저하게 시장점유율이 낮아진다면, 그 스타일시트를 제거하기만 하면 된다.
조건부 파일을 사용하는 유일한 단점은 그것들이 추가적인 HTTP 요청을 브라우저를
위해서 페이지에
추가한다는 것이다.
이것이 스타일시트를 사용하는 것과 비교하면 수용 가능한 거래(trade-off)이긴
하지만,
조건주 외부 자바스크립트 파일을 사용하는데는 반대한다.
왜냐하면 자바스크립트 파일은 마치 블록커(Blocker)처럼 행동하고,
그들이 완전하게 로드되기전에는 다른 파일들이 로드 되는 것을 막을 것이기 때문이다.
만약 당신이 외부 파일에 조건부 자바스크립트를 필요로 한다면, 그 브라우저를 목표로
하는 자바스크립트만을
사용하라. |
|
|
Selector
Hacks |
/* IE6 and
below */
* html #uno { color:
red }
/* IE7 */
*:first-child+html #dos
{ color:
red }
/* IE7, FF, Saf, Opera */
html>body #tres {
color: red
}
/* IE8, FF, Saf, Opera (Everything but IE 6,7)
*/
html>/**/body
#cuatro { color:
red }
/* Opera 9.27 and below, safari 2 */
html:first-child #cinco
{ color:
red }
/* Safari 2-3 */
html[xmlns*=""]
body:last-child
#seis { color: red }
/* safari 3+, chrome 1+, opera9+, ff 3.5+ */
body:nth-of-type(1)
#siete {
color: red }
/* safari 3+, chrome 1+, opera9+, ff 3.5+ */
body:first-of-type
#ocho { color:
red }
/* saf3+, chrome1+ */
@media screen and
(-webkit-min-device-pixel-ratio:0)
{
#diez { color: red }
}
/* Safari 2 - 3.1 */
html[xmlns*=""]:root
#trece { color: red }
/* Safari 2 - 3.1, Opera 9.25 */
*|html[xmlns*=""]
#catorce
{ color: red }
/* Everything but IE6-8 */
:root *> #quince {
color:
red }
/* IE7 */
*+html #dieciocho {
color: red
}
/* Firefox only. 1+ */
#veinticuatro,
x:-moz-any-link
{ color: red }
/* Firefox 3.0+ */
#veinticinco,
x:-moz-any-link,
x:default { color: red }
/***** Attribute Hacks ******/
/* IE6 */
#once { _color: blue }
/* IE6, IE7 */
#doce { *color: blue }
/* Everything but IE6 */
#diecisiete { color
/**/: blue
}
/* IE6, IE7, IE8 */
#diecinueve { color:
blue\9;
}
/* IE7, IE8 */
#veinte { color/*\**/:
blue\9;
}
IE5 ~ IE7 대응‘*’Hack
#selector
{ property:value; *property:value; }/*
문서의 DTD와 무관하게 작용함 */
IE5 ~ IE6 대응‘_’Hack
#selector
{ property:value; _property:value; }
/* DTD가 없는 문서는 IE7에도
작용함 */
IE5 대응‘_ & /**/
’Hack
#selector {
property:value;
_property /**/:value; } /* DTD가
표준모드인 경우에만 작용함 */
- IE5 대응 Hack의 경우 /**/
주석 앞에 한
칸의 공백이 있음에 유의한다.
- '_'를 사용하여
IE5~IE6에
대응하게 한 다음, IE6만을 제외하는 ' /**/'를 적용함으로서 IE6을 제외한
IE5만 대응하게
하는 응용편 핵이다. |
|
|
더블마진
플로트(float) 버그 |
#box{
float:left;
margin-left:20px;
display: inline;/*IE6더블마진 해결*/
} |
|
|
텍스트
주변 3픽셀 공간 버그 |
플로트 지정한 엘리먼트
주변에 텍스트가 있을때 엘리먼트와 접촉부분에 3px의 공간이 생긴다.
해결방법으로는 텍스트에 height:1%;를 주는것이다.
#box{
float:left;
margin:0;}
p{
height:1%;
margin-left:0; |
|
|
문자중복
버그 |
가끔 문자가 중복되어
박스를 넘어설때가 있다.
원인은 주석때문인데 처음두개까지는 이상없다가 이후 주석을 사용하면 중복되어표시된다.
갸령 텍스트가 this is web site 라고 한다면 주석을 3번주면 te처럼
2개의 문자가
중복되고
4개사용하면 4개중복되고 5개 주석사용하면 6개문자가 중복된다.
이건 연속해서 주석을 남발했을때 일어나는데 가급적 주석 사용을 줄이자 |
|
|
피커부(peek-a-boo)
버그 |
플로트가 지정된엘리먼트
플로트가 지정되지않은 엘리먼트 플로트를 해제하는 엘리먼트가 있을때
플롯이 지정되지않은 엘리먼트가 처음에 보이지않는다.
이경우는 엘리먼트에 크기를 지정하거나, line-height,
position:relative 를
지정하면 해결된다. |
|
|
<button>
마크업
|
IE6/7 에서만
버튼에 무의미한 패딩이 들어갈 경우, overflow:visible; 로 속성을
주세요.
그러면 여백이 깔끔하게 사라집니다. |
|
|
Hooly
Hack |
*
html {height 1px;}
기본적으로 Layout을 갖는다고 알려진 요소
<html>, <body>
<table>, <tr>, <th>,
<td>
<img>
<hr>
<input>, <button>, <select>,
<textarea>,
<fieldset>, <legend>
<iframe>, <embed>, <object>,
<applet>
<marquee>
Layout을 갖게 만드는
CSS 속성
position: absolute
float: left|right
display: inline-block
width: ‘auto’ 외의 모든 값
height: ‘auto’ 외의 모든 값
zoom: ‘normal’ 외의 모든 값 (IE 전용)
writing-mode: tb-rl (IE 전용)
overflow: hidden|scroll|auto (IE7만 적용됨)
overflow-x|-y: hidden|scroll|auto (IE7만 적용됨)
|
|
|
브라우져별
상이한 width계산 오류 |
#content
{ width: 200px; padding-left: 10px; }
//이렇게 주게되면, IE 계열에선 총 width 를 200을 유지합니다.
//하지만 다른 브라우져에서는 width 가 padding 까지 포함하여 210 을
유지합니다.
//아래처럼 핵으로 IE에선 210 을 유지하도록 추가합니다.
#content { width:
200px; padding-left:
10px; }
* html #content { width: 210px; }
//padding 은 상위속성을 따라가고, content 의 width 는 변경합니다. |
|
|
IE6
> Transitional > Tabel 스크롤바 영역 초과 오류 |
IE6 DIV 하위
테이블에 layout fixed 가 적용된 경우, 스크롤바는 div width 를
초과하여 생성되어,
div 가 밀립니다.
이경우, table 의 width 가 100% 이기 때문에 그런데, IE6 만
width:100%
속성을 적용하지 않으면 해결됩니다. |
|
|
IE6
> Transitional > Tabel TD nowrap 속성 안먹힘 |
IE6 에서 table
td 의 nowrap 속성이 doctype 을 Transitional 로 선언할 경우,
적용이 되지
않습니다.
완전하게 해결한 것은 아니지만, TD 내부 태그를
<pre></pre> 로
감싸주면, wrap 이 적용됩니다. |
|
|
이미지
아래의 여백 조정 (vertical-align) |
이미지를 td 안에
꽉차게 넣을때 img element 뒤에 줄바꿈이 있으면 cellpadding 을
0으로 해도 이미지들이
정확히 붙지 않는다.
이는 줄바꿈이 IE 에서는 한칸의
공백으로 인식이
되고 이 공백과 img element 의 하단 경계가 맞지 않아서 이다.
하단 경계가 공백이 더 낮아서
전체적으로 inline
block 의 height 가 높아지는 것이다.
이는 CSS 의
vertical-align 속성으로
해결 할 수 있다.
공백이 생기지 않게 하기 위해서 td
와 img
사이의 공백을 없애야만 했다.
<table
cellpadding="0"
cellspacing="0">
<tr>
<td><img src="image.gif"
alt=""></td>
</tr>
<tr>
<td><img src="image.gif"
alt=""></td>
</tr>
</table>
이것을 이렇게 vertical-align
속성을 이용해서 해결 할 수 있다.
<table
cellpadding="0"
cellspacing="0">
<tr>
<td>
<img src="image.gif" alt="" style="vertical-align:
top;">
</td>
</tr>
<tr>
<td>
<img src="image.gif" alt="">
</td>
</tr>
</table>
display: block;도 같은
효과를 보여준다.
|
|
|