column을 이용한 vGrid따라하기

요즘 유행하는 레이아웃 중 vGrid(이름이 맞는지 몰라서, jQuery플러그인 이름을 따랐습니다.)라는 레이아웃이 있습니다. jQuery플러그인으로 나온 뒤 많은 사이트에서 사용되고있는 멋진 레이아웃 방법이라고 생각합니다.

이 레이아웃 방식은 박스별로 float을해서 코딩을 하면 position으로 바꿔서 알맞는 위치에 담아주는게 핵심이라고 생각합니다. 문제는 유동적인 박스때문에 javascript를 이용하지 않으면 방법이 없었지만, css3의 속성 중 column을 이용하면 비슷하게나마 구현이 가능한듯합니다.

익스에서는 column을 지원하지 않기 때문에 작동하지 않습니다.

Demo

height: 70px
height: 50px
height: 40px
height: 60px
height: 90px
height: 100px

column에 대해선 다른곳에서도 많이 다뤘기때문에 설명 드리지 않겠습니다.

문제는 div의 높이가 정의 되있지만, column을 세개로 정확하게 나눠버린다는것 입니다.
div박스가 있다면 중간에 짤라서 다음 column에 이어서 보여주게 되는거죠 파이어폭스4 기준으로 붉은색 부분과 파란색 부분이 다음 칸으로 짤려서 올라간 걸 보실수 있습니다.

해결방법

파이어폭스, 오페라의 경우 divdisplay속성을 바꿔주시면 해결이됩니다. 여러 속성르 테스트해보진 않았고. inline-block, table두가지 속성을 이용해서 테스트 해본결과 문제 없이 돌아갔습니다.
webkit엔진을 사용하는 브라우저(사파리, 크롬)의 경우에는 더 확실한 방법을 제시해놨습니다. -webkit-column-break-before, -webkit-column-break-after, -webkit-column-break-inside를 이용해 문제를 해결 할수 있더군요.

완성된 Demo

height: 70px
height: 50px
height: 40px
height: 60px
height: 90px
height: 100px

완선된 Code

[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” xml:lang=”ko” lang=”ko”>
<head>
<meta http-equiv=”content-type” content=”text/html; charset=utf-8″ />
<title> new document </title>
<style media=”screen, print” type=”text/css”>
.vGrid { -moz-column-count:3; -webkit-column-count:3; column-count:3; -moz-column-gap:10px; -webkit-column-gap:10px; column-gap:10px; }
.vGrid div { -webkit-column-break-before:always; display:inline-block; width:100%; margin-bottom:10px; background-color:#dadad9; }
.vGrid .item1 { height:70px; }
.vGrid .item2 { height:50px; }
.vGrid .item3 { height:40px; background-color:red; }
.vGrid .item4 { height:60px; }
.vGrid .item5 { height:90px; background-color:blue; }
.vGrid .item6 { height:100px; }
</style>
</head>
<body>
<div class=”vGrid”>
<div class=”item1″>height: 70px</div>
<div class=”item2″>height: 50px</div>
<div class=”item3″>height: 40px</div>
<div class=”item4″>height: 60px</div>
<div class=”item5″>height: 90px</div>
<div class=”item6″>height: 100px</div>
</div>
</body>
</html>
[/html]

webkit의 버그?

하위 divopacity값을 줄 경우 -webkit-column-break-before등이 동작하지 못하는 문제가 있습니다.
다른 해결 방법이 있을지 모르겠지만..
몇달간 찾아본 결과 opacity값을 빼는 방법 외에는 다른 방법을 아직 찾지 못했습니다.

더 좋은 방법을 아신다면 피드백 부탁드립니다.ㅋ

mouseenter, mouseleave event

mouseover, mouseout event는 마우스가 객체 위에 놓여졌을 때, 영역을 벗어낫을때 발생하는 event입니다.
허나 이 event들은 객체에서 자식요소로 마우스를 이동해도 event가 발생하는 문제가 있습니다.
아래의 예제처럼요.

event :

이런 문제를 회피하기 위해서 IE에서는 mouseenter, mouseleave 두 event가 존재합니다만, IE에서 밖에 실행이 되질 않아서 스크립트를 작성하는데 문제가 많더군요.
jQuery.js, prototype.js같은 JavaScript Framework을 쓰면 좋겠지만 제 특성상 Framework을 못쓰는 경우가 많아서 ppk(책)에 있는 내용을 참조해서 만들어봤습니다.

event :

Code

[js]
function addEvent(element, type, callback) {
var eventListener = function(element, event) {
element.addEventListener(event, function(e) {
var obj = e.relatedTarget;
while (obj != element) {
if (!obj) return callback.apply(this);
obj = obj.parentNode;
}
return false;
}, false);
};

if (element.addEventListener) {
switch(type) {
case ‘mouseleave’: eventListener(element, ‘mouseout’);
break;
case ‘mouseenter’: eventListener(element, ‘mouseover’);
break;
default : element.addEventListener(type, callback, false);
break;
}
} else if (element.attachEvent) {
element.attachEvent(‘on’ + type, function() {
callback.apply(element);
});
}
}
[/js]

사용 방법

mouseenter

[js]
//일반적인 사용법
object.onmouseenter = function() {
alert(‘mouseenter’);
};
//addEvent를 이용한 방법
addEvent(object, ‘mouseenter’, function() {
alert(‘mouseenter’);
});
[/js]

mouseleave

[js]
//일반적인 사용법
object.onmouseleave = function() {
alert(‘mouseleave’);
};
//addEvent를 이용한 방법
addEvent(object, ‘mouseleave’, function() {
alert(‘mouseleave’);
});
[/js]

실력이 많이 부족하다 보니 좋은방법인지까지는 모르겠습니다.
더 좋은 방법을 아시거나 버그를 발견하신분은 꼭 알려주세요~

IE8 Hack

[css]
/* IE6, IE7, IE8 */
selector { color: blue\9; }

/* IE7, IE8 */
selector { color/*\**/: blue\9; }
[/css]

구글검색을 하다보면 IE8 STANDARDS MODE ONLY로 되어있지만…
막상 IE Tester로 테스트 해보면 IE7에서도 동작 하더군요..-_-
IE Tester가 문제인지 올라온 글들이 문제인지는 확인해 보지 못했지만 IE Tester로 테스트하고 안된다고 하는 사람도 있기에…-_-;
IE7, IE8 두개 다 된다고 생각하는게 좋을듯합니다.

inline-block속성 이용하기

요즘 제가 float속성 대신 많이 사용하고있는 방법은 inline-block입니다.
이미지 겔러리 같은 디자인을 코딩시 float의 단점은 높이가 다를 경우 다음줄의 정렬이 뒤틀어지는 문제가 생기기 때문에 높이를 정해주거나 사이에 clear를 해야 하는 문제가 있었죠..
(저같은 경우는 말이죠.. 좋은 방법을 알고계시다면 알려주세요.)

그래서 사용하는 방법이 inline-block입니다.
inline-block로 정렬시 높이가 일정하지 않아도 정렬이 뒤틀림 없이 나오게 할수가 있습니다.
거기다 세로 정렬까지 되는 아주 멋진 속성인듯 싶습니다.

단점

구버전 브라우저의 빈약한 지원

파이어폭스 2.0 이하의 브라우저에서는 이 속성을 지원하지 않기 때문에 -moz-inline-box속성을 써야만 합니다.
하지만 이것 역시 완벽한 방법은 아닌듯합니다.
[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" xml:lang="ko" lang="ko">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title> Code Example </title>
<style type="text/css">
li {
display:-moz-inline-box; /* 구 버전의 Moz */
display:inline-block; /* Op, Saf, Moz3.0이상, IE8등 */
}
</style>
</head>

<body>
<ul>
<li>
<span>test</span>
<span>test</span>
</li>
</ul>
</body>
</html>
[/html]
위와 같은 코드가 있을시 li의 자식요소인 span까지 -moz-inline-box속성을 먹어서 줄바꿈되는 문제가 있습니다.
CSS tests and experiments를 운영하는 Bruno Fassino님은 li의 자식요소를 한번 더 감싸는 방법으로 회피하고 있더군요.

익스플로러의 경우 inline요소(span, strong..등)에서는 문제가 없지만 block요소(div, li, p…등)에서는 문제가 생깁니다.
이 방법을 회피 하기 위해서는 익스플로러에서는 inline속성으로 만들어주면 됩니다.
[css]
li {
display:-moz-inline-box; /* 구 버전의 Moz */
display:inline-block; /* Op, Saf, Moz3.0이상, IE8등 */
}
/* IE7 */
*+ html li {
display:inline;
}
/* IE6 */
* html li {
display:inline;
}
[/css]

공백문자

inline-block의 경우 inline속성과 같이 줄바꿈없이 내용을 보여주게 되지만 코드의 가독성을 위해서 사용된 줄바꿈, 들여쓰기를 하나의 공백문자로 인식하게 되어서 &nbsp; 한개 만큼의 공백이 생기게 됩니다.

제가 아는 해결방법은 두가지가 있습니다.

첫번째로는 아래와 같이 부모 요소에 font-size, line-height를 0으로 설정하고 inline-block을 준 요소에 font-size와 line-height를 다시 설정해주는 방법이죠.
[css]
ul {
font-size:0;
line-height:0;
}
ul li {
font-size:12px;
line-height:1.2;
display:-moz-inline-box; /* 구 버전의 Moz */
display:inline-block; /* Op, Saf, Moz3.0이상, IE8등 */
}
[/css]

두번째 방법은 html코드의 “>”부분을 줄바꿈해 버리거나 한줄로 붙여 쓰는 방법이죠.
(위에서도 언급했던 Bruno Fassino님의 경우에도 아래와 같은 방법으로 공백문자가 생기는 방법을 회피 했더군요.)
[html]
<ul
><li>content</li
><li>content</li
><li>content</li
></ul>
[/html]
두번째 방법의 경우 개발자와의 대화가 필요합니다.
html를 잘 모르는 개발자일 경우 이런 상황을 인식하지 못하고 할줄로 붙여서 쓴 방법을 무시해 버릴수도 있기 때문이죠.

덧.
위의 글은 접근성에 대한 부분은 무시하고 작성되었습니다.
접근성에 문제가 있다고 딴지를 거신다면 할말이 없습니다.:(

IE를 위한 css모음

IE6 png filter

IE6에서 알파값이 들어간 png를 처리하지 못하기 때문에 filter를 사용해야 합니다.

[css]
/*scale*/
selector {
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’pngImage.png’, sizingMethod=’scale’);
}
/*crop*/
selector {
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’pngImage.png’, sizingMethod=’crop’);
}
/*image*/
selector {
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’pngImage.png’, sizingMethod=’image’);
}
[/css]

scale, crop, image 속성을 지원합니다.

  • scale 상위의 객체에 꽉 체워 줍니다. 만일 이미지를 싸고 있는 레이어가 있다면 그 레이어에 크기에 맞게 그림이 늘어납니다.
  • crop 이미지의 크기 비율에 맞게 디스플레이 합니다.
  • image 기본 설정값으로 본래의 이미지 크기로 보여줍니다.

Opacity

opacity의 경우 브라우마다 지원하는 방법이 다릅니다.

[css]
/*표준브라우저*/
selector {
opacity:.5;
}
/*IE 5~7*/
selector {
filter:alpha(opacity=50);
}
/*IE 8*/
selector {
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
}
[/css]

expression

IE6에서 max-width같은 지원하지 않는 스타일을 써야할때 많이 사용합니다.

[css]
selector {
max-width:320px;

}
* html selector {
width:expression(this.width > 320 ? "320px" : this.width);
}
[/css]
안에 사용되는 스크립트의 경우 코딩 상황에 따라 달라질수도 있습니다.

child selector

expression을 child selector이용한 사용하기
[css]
.selector { color:blue; }
.selector > .selector { color:red; }
* html .selector .selector { color:expression(/selector/.test(this.parentNode.className) ? ‘red’ : ‘blue’); }
[/css]
class가 아니여도 스크립트만 잘 조합해서 쓰시면 됩니다.

first-child selector

IE6은 :first-child, :last-child 둘 다 지원하지 않고, IE7은 :last-child를 지원하지 않습니다.
(왠만하면 한번만 쓰는게 좋기 때문에 :first-child로 통일하는게 좋을듯합니다.)
[css]
selector { color:blue; }
selector:first-child { color:red; }
* html selector { color:expression((this.previousSibling == null) ? ‘red’ : ‘blue’); }
[/css]
class는 지원하지 않습니다.
태그(li, div…등)에서만 사용 가능합니다.
:last-childthis.previousSiblingthis.nextSibling로 바꾸시면 됩니다.

이중 class

IE6에서 .class.class2같은 이중클래스를 사용할수있게 해줍니다.
[css]
.selector { color:red; }
.selector.selector2 { color:blue; }
.selector2 { color:green; }
* html .selector { color:expression((function(that) { if(/[selector]\s*[selector2]/.test(that.className) === true) return ‘blue’; })(this)); }
[/css]
부모의 클래스를 찾고 싶을때는 that.classNamethat.parentNode.className로 바꿔서 사용 하시면 됩니다.

:before, :after

IE에서 :before, :after를 사용할수 있게 해주는 속성입니다.
[css]
.selector:before {
content:’앞의 내용 추가’;
background-color:blue;
}
.selector:after {
content:’뒤의 내용 추가’;
background-color:red;
}
.selector {
* zoom:expression(
this.runtimeStyle[‘zoom’] = ‘1’,
this.innerHTML = ‘<span style="background-color:blue;">앞의 내용 추가</span> ‘ + this.innerHTML + ‘ <span style="background-color:red;">뒤의 내용 추가</span>’
);
}
[/css]
내용 설명은 생략합니다만, this.runtimeStyle['zoom'] = '1',를 뺀뒤 테스트 해보시는것도 또 하나의 재미라고 생각됩니다.

아래와 같이 selecter tag가 before, after에 사용될 태그와 같을 경우 에러가 납니다.
[css]
span {
* zoom:expression(
this.runtimeStyle[‘zoom’] = ‘1’,
this.innerHTML = ‘<span style="background-color:blue;">앞의 내용 추가</span> ‘ + this.innerHTML + ‘ <span style="background-color:red;">뒤의 내용 추가</span>’
);
}
[/css]
em같은 태그로 회피해서 사용.

소스를 사용함에 있어

몇몇 소스의 경우 인터넷에 돌아다니는 내용이고, 대부분 많이 사용 되는 소스기때문에 문제가 없지만, 몇몇 소스는 제가 만든소스입니다. 저도 실무에서 잘 안쓰는 소스이고, 검증되지 않았습니다.
그런고로 책임은 지지 않습니다.