블로그 내 검색

2012. 5. 22.

이미지 대치 기법

Image Replacement???

이미지 대치 기법이라고 합니다.
먼저 Text + CSS로 마크업한 뒤 그 내용을 그것을 표현하는 이미지로 가려 실제 일반적인 환경(대표적으로 PC 브라우저)의 유저들에게 Text + CSS의 조합 대신 이미지를 노출하는 기법입니다.

왜 이런 쓰잘데기 없어보이는(?) 일을 할까요.

CSS3의 등장

CSS3 에 되어서는 이제 기존의 플래시나 이미지에 의존하지 않고도 애니메이션이나 재미있는 로고등을 만들어낼 수 있게 되었습니다.

transition 이나 transform 등을 사용해서 여러 효과를 주기도 하고, 예전에는 이미지로 표현했던 border-radiusbox-shadow 등....이제는 CSS로 거의 모든 걸 할 수 있게 되었죠.

하지만 만능은 아니다

하지만 Text + CSS로 모든 걸 할 수 있는 것은 아닙니다. 그리고 해 낸다 하더라도, 복잡한 CSS의 코드에 코드 리딩이 어려워지는 결과를 낳기도 합니다.
(유지보수를 맡게 된 개발자의 한숨이 들릴지도 모르겠네요)

보통 CSS와 텍스트의 조합으로 표현하기 어려운 경우 기존에는 이미지로 디자인을 만들어 페이지에 img 태그나 css의 background 속성으로 표현하는게 일반적이었습니다.
보통 회사의 로고등에 그런 작업을 많이 쓰지요.

그러나 최근에는 이미지가 컨텐트의 내용을 직접적으로 표현하는 것은 비권장되며, 가능한 Text + CSS의 조합으로 컨텐트를 표현하는 것이 추천됩니다.

이유가 무엇일까요.

SEO 와 접근성

그 이유중 제일 큰 것은 SEO 때문입니다. 

SEO는 검색 엔진 최적화(Search Engine Optimized) 의 약자입니다. 일반적인 브라우저에서 사람의 눈으로 보는 HTML문서와는 별개로 검색 엔진이 페이지를 읽었을 때 효율적으로 검색 엔진에게 정보를 전달할 수 있도록 최적화 마크업을 하는 것을 말합니다.

검색 엔진에게 최적화된 문서는

알맞은 태그를 써서
문자열 형식으로
깨진 링크가 없이 전부 도메인의 페이지가 연결

된 페이지를 말합니다.
Semantic Markup 의 방향과 같다고 볼 수 있죠. 둘이 합쳐지면 SEO++ 가 된다 더군요.

또한 사용자가 HTML을 보는 방식은 PC 브라우저뿐이 아닙니다.

맹인을 위한 스크린 리더, 제한적인 모바일 환경의 브라우저...드물지만 텍스트 브라우저 등, 하나의 HTML에 접근하는 방법은 여러개일 수 있습니다.
이럴 경우 이미지로 표현된 컨텐트는 아무래도 접근성이 떨어지며 해석도 힘듭니다.
alt 속성에도 한계가 있습니다.

방법

서론이 길었네요. 다시 본론으로 돌아오죠.
위에 설명한 SEO와 접근성을 높이기 위해 이미지 대치 기법을 사용합니다.

기본 방식은
  • 텍스트 + CSS로 마크업
  • 텍스트를 안보이게 조작
  • 이미지 CSS 속성 등으로 대신 표시
입니다.

코드를 예로 들어보죠

요새 제가 관심있어하는 RequireJS 에 대한 포스팅을 쓴다고 가정합니다

<h1>RequireJS 짱좋네</h1>
<p>어저고저쩌고.....더이상의 자세한 설명은 생략한다.</p>

이렇게 마크업할 경우 일단은 SEO와 접근성에서 합격점을 받을 수 있습니다. 그러나 문서의 제목을 좀더 돋보이고 화려한 효과를 줘서 강조하고 싶습니다. 

SEO와 접근성을 해치지 않으면서 스타일을 적용하여 이미지 대치 기법을 적용해야 하는 상황이 된거죠.

예전에는 원래 표현할 내용을 span 태그 등으로 감싼 뒤 display를 hidden 등으로 감추거나(파너 이미지 대치 기법), h1안의 텍스트를 text-indent 등의 속성으로 글자를 안보이게 한 뒤에 이미지를 h1의 background 속성으로 지정하는 방법(파크 방법)을 많이 썼습니다. 

그러나 이 방법들에는 치명적인 문제가 있는데 첫번째 방법의 경우, 일반적인 스크린 리더등에서는 display: none 등의 비가시성 요소를 해석하지 않아서 문제가 되며, 두번째 방법의 경우에는 브라우저가 CSS를 사용하지만 이미지를 해석할 수 없을 경우 아무것도 볼 수 없습니다.

위 두 방법보다 그나마 제일 안정적이고 어떤 환경에서도 잘 해석되는 방법으로 알려진 방법을 하나 소개합니다. (길더/레빈 방법)

<h1>
    <span></span>RequireJS 짱좋네
</h1>
<p>어저고저쩌고.....더이상의 자세한 설명은 생략한다.</p>

마크업을 위와 같이 의미없는 span 태그를 문자열 앞에 삽입합니다.
(이 부분이 이 방법의 최대 단점입니다. 의미없는 마크업이 추가되어야 합니다.)

이제 스타일을 줍니다. h1을 위치지정으로 바꿉니다

h1 {
    position: relative;
    width: 860px;
    height: 40px;
}

그 다음 span을 절대영역으로 지정하고 크기를 100%로 주고 컨텐트 이미지를 배경으로 지정합니다.

h1 span {
    background: url(requirejs) no-repeat;
    position: absolute;
    width: 100%;
    height: 100%;
}

이렇게 하면 CSS를 꺼도, 이미지를 꺼도 어디서든 텍스트나 이미지 둘중 하나는 볼 수 있습니다.

덧붙여...

사실 위와 같은 방법에 더해, 추가적인 정보를 다른 특이한 브라우저나 리더, 검색엔진에 주고 싶다면 img의 alt 속성을 활용할 수 있습니다.

실제 W3C 사이트의 로고는

<h1 class="logo">
    <a tabindex="2" accesskey="1" href="/">
        <img src="/2008/site/images/logo-w3c-mobile-lg" 
                 width="90" height="53" alt="W3C">
    </a>
    <span class="alt-logo">W3C</span>
</h1>

과 같이 마크업되어 있습니다.
W3C 로고를 텍스트로 코딩해두고, 그 위를 로고 이미지로 덮은 뒤에 그 이미지에도 alt 속성으로 W3C임을 나타내고 있죠.

사람에게 잘보이는 것 외에도 기계에게까지 잘 보여야 하다니...
웹 접근성과 SEO...참 어려운 것 같네요.

2012. 5. 17.

크롬 개발자 도구로 클로저 차근차근 써보기


크롬 개발자 도구와 클로저

전에 포스팅한 자바스크립트 클로저의 글이 좀 부족한 것 같아 이번에는 새로운 접근으로 한번 풀어보려고 합니다.

그리고 이것에 더해서 크롬 개발자 도구의 유용함과 대화형으로 자바스크립트 디버깅을 하는 방법도 같이 알아보죠.
차근차근 글을 따라 타이핑 하면서 하시면 더욱 좋을 것 같습니다(?)

!! 주의 !!
완전 초보분만을 대상으로 한 포스팅입니다.
초보가 아닌 분이 본 뒤 시간낭비가 되도 책임지지 않습니다

준비

일단 크롬 브라우저가 필요합니다.

크롬을 기동하고 새로운 빈 탭을 만듭니다.
크롬의 주소창에 chrome://newtab 을 입력하면 새로운 빈 탭이 열립니다.

그 다음 F12을 눌러 개발자 도구를 엽니다.
개발자 도구가 열리면 상단의 아이콘 중 Console을 클릭합니다.

저기 있네요

이 콘솔에서는 자바스크립트를 대화형 모드로 코딩해볼 수 있습니다. 프로그래머가 코드를 입력하고 Enter를 치면 바로바로 해석해서 결과를 알려주지요.

개발자 도구 콘솔에 코딩하기

이제 준비가 다 됐습니다.
테스트로 아래와 같은 코드를 타이핑합니다.
var hello = "world";
엔터를 누르면 크롬의 자바스크립트 엔진은 위 문장을 바로 해석하여 결과를 돌려줄 겁니다.
위 문자열은 자바스크립트 문장(statement)로서 반환값이 없습니다.
그래서 undefined 가 찍힐 겁니다.

hello 변수에 값이 잘 할당되어 있는지 볼까요?
hello를 타이핑해 봅시다.
hello는 표현식(expression)으로 부르는데 계산되어 값을 표현할 수 있는 단위입니다.

결과는 예상대로...
이제 본격적으로 시작해 봅시다.
다음과 같은 코드를 타이핑해 봅니다. 여러 줄을 걸쳐 입력할 경우 시프트와 엔터를 동시에 누르면 바로 엔진에게 보내지 않고 줄바꿈이 가능합니다.
var createSeq = function() {
    var i = 0;
    return function() {
        return ++i;
    }
};

제대로 입력했다면 undefined 가 출력됩니다. 이것도 물론 문장(statement) 이기에 아무런 값을 반환하지 않죠.
제대로 입력되어 있는지 확인해보기 위해 createSeq 를 입력합니다. 방금 입력한 함수의 내용이 그대로 출력된다면 제대로 입력한 겁니다.
(함수를 실행하지 않고 바로 값을 보려고 할 경우, toSource 라는 함수의 메서드가 자동으로 호출되어 함수의 표현식을 문자열 형식으로 출력하게 됩니다.)

함수 소스를 볼 수 있군요 

이제 저 함수를 실행합니다. 반환값이 있으니 변수 a 에 담아봅시다.
var a = sreateSeq();
아 실수...제가 오타를 쳤군요...

오타;


저렇게 존재하지 않는 함수나 잘못된 문법을 입력할 경우 오류를 출력해 줍니다. 클릭해보면 오류 객체의 내용도 볼 수 있습니다.
다시 제대로 쳐봅시다.
var a = createSeq();

변수 a에는 뭐가 있을지 한번 찍어볼까요.
콘솔에 표시된 반환된 함수의 내용
function () {
    return ++i;
}
입니다.
반환된 함수 내용

그렇다면...a의 실행 결과는 어떨까요...?
일반적으로 생각하면 현재 변수 i가 없으므로 정의되지 않은 변수 오류를 내야 정상일 것 같습니다.
정말 그럴지 한번 실행해 봅시다.
i 는 정의되지 않은 변수일텐데...

어째선지 1이 찍힙니다. 변수 i 를 어디서 참조한 걸까요.
여기가 중요합니다.
전에 분명 createSeq 를 실행하여 함수를 반환받았습니다. 그 createSeq 안에는 변수 i가 선언되어 있지요.
var createSeq = function() {
    var i = 0; // 여기 선언되어 있네요!
    return function() {
        return ++i;
    }
};

우리가 createSeq를 실행해서 얻은 함수 a 는 변수를 찾을 때 자신이 선언된 곳의 변수를 참조하여 찾은 i에 ++ 연산을 수행하여 결과를 1로 반환한 것이죠.

이렇게 하면 어떨까요.
변수 i를 새로 선언합니다. 값을 99 로 줍시다.
var i =99;
전역에 i 를 선언합니다.

a를 실행하면 어떻게 될까요. a의 소스 내용을 다시 보면
function () {
    return ++i;
}

입니다.
그렇다면 결과는 99에 1을 더해 100이 될까요?

음...

결과는 2가 나옵니다.

a가 실행될 때 전역에 선언된 i를 사용하지 않고, 자신이 선언된 createSeq의 변수를 사용했기 때문입니다.

자바스크립트는 코드를 실행할 때 그 코드에 설정된 유효범위를 뒤지는데, 유효범위에도 순서가 있습니다. a의 경우 createSeq의 유효범위가 전역보다 앞에 있다고 보면 정확합니다.

뭔가 신기하다면 a 함수와 같은 기능을 하는 함수를 전역에 선언해보고 실행해 봅시다
var b = function () {
    return ++i;
}
b();

100 이 나오는군요.

변수 i를 전역에 선언했지만 a의 결과는 2

전역의 i에 ++를 수행하여 반환한 겁니다.
b는 createSeq 의 변수에 접근할 수 없는게 확실하죠. (당연한가요...)

“a는 createSeq의 유효범위의 변수를 사용할 수 있다.”

a를 보통 클로저라고 부릅니다. 여기서 좀더 생각해보면 변수 i는 a만 접근할 수 있도록 포장(encapsulation)되어 있다고도 할 수 있습니다. 다른 곳에서는 아무리 해도 a가 접근할 수 있는 i 변수를 읽을수도, 값을 변경할수도 없습니다.

자바스크립트에서는 이러한 클로저의 특성을 사용해서 private, public 등의 개념을 구현하여 각종 패턴에 사용합니다.

백견이 불여일타

크롬 개발자 도구를 사용해서 자바스크립트 코드를 타이핑해보면서 이런저런 시도를 해본다면 좀 더 자바스크립트에 대해 이해가 쉬울거라고 생각합니다.

크롬 개발자 도구 콘솔 창에서는 자동 완성은 물론 배시 쉘등에서 지원하는 방향키로 커맨드 히스토리를 볼러올 수도 있고 어시스트되는 내용으로 객체의 내용도 미리 알 수 있기에 참 유용합니다.

크롬의 DOM API에서는 get으로 시작하는 메서드들이 이런게 있군요

크롬 개발자 도구와 함께 즐거운 웹 코딩 되시길 바랍니다~

2012. 5. 14.

DevFextX Korea 2012 후기

지난 토요일, DevFextX Korea 2012 에 참여하고 왔습니다.
아래는 직접 찍은 사진들.
대형 플래카드가 보이네요

음료수는 무한대로 마실 수 있었습니다.

세션 중간중간에 있던 쉬는시간.

크게 Web, Android, Emerging 3개의 세션으로 나뉘어 진행됐는데요.
전 주로 Web 분야를 들었습니다.

특히 크롬 웹 확장 개발이 제일 인상 깊었네요
바로 크롬 웹 어플리케이션 개발에 뛰어들고 싶을 정도로...

그리고 세션 후 다트언어에 관심있는 사람들끼리 모여서 프론트엔드 기술에 대해 짧게 이야기를 나눴습니다.

NHN에서 진도 프레임워크를 개발하시고 계신 개발자분에게 제가 좀 과감한 발언을 했는데, 그것에 대해 설명을 듣던 도중 시간이 다 되어 이야기는 추후 하기로 해서 조금 아쉬웠습니다.
다트 한국 그룹에 오시는 분이셨으니 앞으로 기회가 많을거라고 생각하며 행사 종료후 집에 돌아왔습니다.

넋두리 몇마디...
전 사실 이런 모임에 나갈 때마다 새로운 지식을 배우기도 하지만 오히려 여기 모이는 개발자와 나와 차이를 비교하며 살짝 좌절도 합니다. 하지만, 뭔가 넘을수 없는 차이를 가진 개발자를 직접 만나서 나 자신도 그것에 조금이나마 따라가고 싶다는 느낌이 계속 개발자 관련 모임에 나가게 되는 거 같네요.

뱁새도 열심히 노력하면 언젠간 황새 풍월정돈 읊을 수 있지 않을까요 ㅎㅎ

다음 모임도 반드시 참여하고 싶을 정도로 유익한 모임이었습니다.



아래는 세션 발표 자료 모음 링크입니다.
https://docs.google.com/folder/d/0B0ucmHKqyC8_WjlzUDFlUVBwZ2M/edit?pli=1

2012. 5. 1.

자바카페 세미나 발표자료

발표 자료 공유합니다.

이런 발표는 처음이라 참 어색하고 긴장됐는데 끝나고 나니 아쉬움 밖에 안남네요.




다음에 다른 기회가 있었으면 좋겠네요.