Author Archives: elegantcoder

브라우저 자동완성 기능의 미래

Form element 에 autocomplete 기능이 소개된 것은 1999년 Internet Explorer 5이 최초였다. 이후 각 브라우저 별로 산발적으로 지원하던 자동완성 기능은 HTML5에 이르러 표준화 되었다.

HTML5 스펙은 2012년 12월 17일 버전으로 기준으로 함.

이전 스펙에서 autocomplete attriute 는 “on” 또는 “off” 값만 가질 수 있었으나 최근의 스펙에서는 on, off 외에 공백으로 분리된 토큰들을 가질 수 있다. 이에 따르면 attribute 이 on, off 가 아니라면 아래와 같은 순서로 동작한다.

  1. 첫 8글자가 “section-” 으로 시작하는 경우 필드가 이름을 가진 그룹에 속함을 나타낼 수 있다. (선택사항)

예를들어, 양식에 두개의 배송주소가 있을 때 아래처럼 마크업 할 수 있다.

<fieldset>
 <legend>Ship the blue gift to...</legend>
 <p> <label> Address:     <input name=ba autocomplete="section-blue shipping street-address"> </label>
 <p> <label> City:        <input name=bc autocomplete="section-blue shipping region"> </label>
 <p> <label> Postal Code: <input name=bp autocomplete="section-blue shipping postal-code"> </label>
</fieldset>
<fieldset>
 <legend>Ship the red gift to...</legend>
 <p> <label> Address:     <input name=ra autocomplete="section-red shipping street-address"> </label>
 <p> <label> City:        <input name=rc autocomplete="section-red shipping region"> </label>
 <p> <label> Postal Code: <input name=rp autocomplete="section-red shipping country"> </label>
</fieldset>
  1. 어떤 토큰은 둘 중 하나일 수 있다. (선택사항)

    • shipping 은 이 필드가 배송 주소 또는 연락처 정보의 일부임을 나타냄
    • billing 은 이 필드가 청구 주소 또는 연락처 정보의 일부임을 나타냄
  2. 다음 두 옵션 중 하나

    • 어떤 토큰이 아래 autofill field string 중 하나:
      • “name”
      • “honorific-prefix”
      • “given-name”
      • “additional-name”
      • “family-name”
      • “honorific-suffix”
      • “nickname”
      • “organization-title”
      • “organization”
      • “street-address”
      • “address-line1”
      • “address-line2”
      • “address-line3”
      • “locality”
      • “region”
      • “country”
      • “postal-code”
      • “cc-name”
      • “cc-given-name”
      • “cc-additional-name”
      • “cc-family-name”
      • “cc-number”
      • “cc-exp”
      • “cc-exp-month”
      • “cc-exp-year”
      • “cc-csc”
      • “language”
      • “bday”
      • “bday-day”
      • “bday-month”
      • “bday-year”
      • “sex”
      • “url”
      • “photo”
  • 아래 순서대로
    1. 어떤 토큰이 아래 값들 중 하나 (선택사항)
      • home, work, mobile, fax, pager
    2. 어떤 토큰이 아래 autofill field 스트링 중 하나
      • tel, tel-country-code, tel-national, tel-area-code, tel-local, tel-local-prefix, tel-local-suffix, tel-extension, email, impp

즉, 이 스펙에 따르면 아래와 같은 경우의 수가 존재한다.

<input name="country" autocomplete="on">
<input name="country" autocomplete="off">
<input name="country" autocomplete="country">
<input name="country" autocomplete="shipping country">
<input name="country" autocomplete="section-a shipping country">
<input name="billing_home_tel" autocomplete="section-a billing home tel">

이런 상세한 분류를 통해 브라우저가 앞으로 더 강력한 자동완성기능을 갖게 될 것이다.

예를 들어 명세서 청구주소는 집이지만, 배송은 회사에서 받게 되는 경우가 있을 수 있다. 이런 경우 billing 에 집 주소, 집 연락처가 저장될 것이고 shipping 에는 회사 연락처 등이 저장되는 형태로 세분화가 가능해질 것이다.

참고

평범한 인터렉션, 비범한 인터렉션

여러분은 지금 어떤 자세로 이 페이지를 보고 있나요? 혹시 턱을 괴고 마우스에 손을 올리고 있지는 않은가요?
웹서핑을 할 때 많은 시간을 마우스와 함께 합니다. 하지만 가끔 양 손 모두가 키보드 위에 올라오는 때가 있죠. 바로 양식(Form)을 입력할 때 입니다.

양식을 채워서 로그인을 합니다.
메일을 쓰는 것도 양식을 채우는 일 입니다.
글을 보고 코멘트를 달아주는 것도 양식을 채움으로써 가능합니다.

즉 양식은 웹을 보는데서 그치는 것이 아니라 더 적극적인 소통을 가능하게 하는 매우 중요한 도구 입니다.

Hours 인터랙션 시리즈의 첫 꼭지는 바로 이 양식에 대한 것입니다.

좋은 인터랙션을 가진 양식 = 적절한 힌트를 주는 양식

힌트가 없는 입력창 (휑~) 힌트가 없는 입력창 (휑~)

웹페이지에 위 그림처럼 입력창(Input Element) 만 놓여있다면 무슨 내용을 입력해야 할지 알 수 없을 겁니다. 따라서 입력창은 적절한 힌트를 제공해야 합니다.

웹에서 양식에 힌트를 제공하는 기본요소는 Label 과 Placeholder 가 있습니다.

Label과 Placeholder

문구용품 중에서 라벨이 있죠? Label 은 바로 그 라벨을 생각하시면 됩니다.
Placeholder 는 언어학적으로 “문장 속에 필요한 요소이기는 하나 그 자체의 뜻은 없는 것” 이란 뜻이 있습니다.

HTML 표준 명세에서는 이 둘을 각각 이렇게 정의합니다.
“label 요소는 사용자 인터페이스에서 캡션을 나타냅니다.”
“placeholder 속성은 짧은 힌트(한 단어나 짧은 구)를 나타냅니다.”
“placeholder 속성을 label 을 대체하기 위해 사용할수는 없습니다.”

정의가 한 번에 와닿지 않으신다면 아래 그림을 살펴보세요.

이 것은 아이폰의 메일 계정 설정화면입니다. 여기서 Name, Email 등 까만글씨로 표현된 것이 Label이고 [email protected] 같이 회색 글씨로 표현된 것을 Placeholder 라고 합니다.

Label 은 각 입력 항목의 이름을 나타내고 있고, Placeholder 에는 입력할 값의 예라던지 꼭 입력해야 함 등의 부가 정보를 나타내고 있습니다.
형식 면에서도 Label 은 일반 명사를 사용하고 있지만, Placeholder 는 비교적 자유롭게 적혀있습니다.

두 가지 정보를 함께 사용하면서 어떤 정보를 어떻게 입력해야 하는지, 꼭 입력해야 하는 정보는 무엇인지 한 눈에 알 수 있게 했습니다. UI/UX 에 강점이 있는 애플 답게 Label과 Placeholder 를 적절하게 사용하고 있군요.

커서가 위치해도 어떤 값을 입력해야 할지 알 수 있도록

Label 요소를 입력창 안쪽으로 밀어넣는 것이 최근의 경향입니다. 아래의 로그인창들을 보세요.

네이버 로그인 팝업 – OSX

iCloud 로그인 영역

두 사이트 모두 Label 요소를 입력창 안에 넣어서 공간을 절약하고 시각적으로도 좋은 디자인을 만들어냈습니다. 아이폰 메일화면의 Placeholder 와 비슷한 모양을 하고 있긴 하지만, 아이디나 비밀번호 같은 것은 Label 이라고 할 수 있습니다.

한가지 중요한 차이는 네이버는 커서가 위치하면 아이디라는 글자가 사라지는 것이고, iCloud는 Apple ID 이라는 글자가 옅게 표시되면서 남아 있는 것입니다.

사실, 네이버의 로그인 창에서 첫번째 입력은 아이디라는 것을 쉽게 추정할 수 있으니 전혀 문제 될 것이 없습니다. 하지만 입력해야할 내용이 사번이었다면 단번에 추정하는 것은 어렵지 않을까요? 그래서 이런 방식의 UI는 커서가 위치하더라도 (내용을 채우지 않았다면) Label을 계속해서 보여주는 것이 더 좋습니다.

내 텍스트 커서(Caret)는 어디있을까?

텍스트 커서는 얇고 긴 모양입니다. 그래서 눈에서 놓치면 다시 찾아내기가 쉽지 않습니다. 따라서 내 커서가 어디에 위치하고 있는지 명확하게 보여주는 것이 좋습니다.

네이버 로그인영역 – Windows XP, IE8

KBStar.com 로그인영역

이번에는 네이버와 국민은행 사이트입니다. 네이버는 커서가 위치한 입력창의 테두리를 녹색으로 만들어 커서의 위치를 보여줍니다. 반면 국민은행은 커서의 위치를 나타내는 곳을 따로 표시하고 있지 않습니다. 대부분의 평범한 사이트는 이런 형태로 서비스되고 있습니다. 로그인은 입력창이 두 세 개 정도이지만 회원가입과 같이 입력창이 많은 경우는 사용자가 길을 잃는 확률이 높아지므로 커서의 위치를 표시하는 것이 좋습니다.

평범과 비범의 차이는 바로 디테일

양식의 목적은 사용자가 제작자의 의도를 쉽게 파악해 적절한 정보를 입력하게 하는 것입니다. 이 목적을 잘 달성하려면 좋은 인터랙션이 필요합니다. 그런 의미에서 양식에서의 좋은 인터랙션은 세상에 없는 거창한 것이 아니라 사용자에게 주는 조그만 힌트로 충분합니다. 하지만 평범과 비범의 차이는 바로 그 한 치의 디테일에서 나오는 것이 아닐까요?

관련글

이 글은 KTH 디자인실에서 발행하는 Hours 에 실린 글입니다.

Safari 6 Web Inspector 로 iOS6 Safari 디버그하기

차기 아이폰 출시일이 9월 12일로 예상되고 있습니다. 아울러 iOS6도 출시될 텐데요.
Front-end 개발자로써 이번 업그레이드가 매우 반갑습니다. 기존의 Weinre와 같은 3rd party 프로젝트에 의존하지 않는, built-in 개발자 도구 연동기능이 추가되기 때문입니다. 이 기능은 OSX Safari6 와 iOS6 간의 연동으로 이루어 집니다.

대략 어떻게 사용가능한지 빠르게 정리하겠습니다. 환경은 OSX Mountain Lion(10.8.1), Safari 6(8536.25), iOS6 Developer Preview 3 입니다.

준비물

  • Mac OSX Lion, or Mountain Lion (Safari 6는 Windows 용이 출시되지 않았습니다.)
  • Safari 6
  • iOS6 Device
  • iPhone USB Sync Cable

디버그 방법

  • 아이폰 케이블을 맥컴퓨터에 꽂기
  • iOS Device 에서 설정 – Safari – 고급 – 웹 속성 활성화하기
    iOS Device 에서 설정 - Safari - 고급 - 웹 속성 활성화하기
  • iOS Device 의 Safari 를 켜고 디버그 할 페이지에 접속하기
    iOS Device 의 Safari 를 켜고 디버그 할 페이지에 접속하기
  • Safari 6 의 개발자 메뉴에서 자신의 iOS Device 이름과 디버그할 웹페이지 타이틀이 보이나 확인하기
    Safari 6 의 개발자 메뉴에서 자신의 iOS Device 이름과 디버그할 웹페이지 타이틀이 보이나 확인하기
  • 이제 Web Inspector 사용가능!
    OSX Web Inspector 화면
    iOS 디버그 페이지 화면

주의할 점은 iOS Device 화면에 Safari 가 올라와있어야 Safari 6 의 개발자 메뉴에서 디버그할 웹페이지를 고를 수 있습니다. 여러 페이지가 켜져 있는 경우에는 골라서 디버그 할 수 있으니 참고하세요.

이번 업데이트로 OSX-iOS에서는 Weinre 같은 네트워크를 통한 리모트 디버깅 환경을 사용하지 않아도 됩니다. 그리고 케이블로 연결해 디버그 하므로 성능면에서 월등합니다. 하지만 Windows 에서 지원하지 않는 점은 아쉬운 점으로 남겠네요.

Git pull 시에 Merge branch .. 메시지 나오지 않도록 하기

Git Pull 시에 머지 커밋하지 않기

$> git pull

을 실행하면 리모트의 내용과 내 작업내역을 머지하게 되는데 이 때 머지되었다는 커밋을 한번 더 수행해주어야 한다. 이 경우 Merge branch ‘local branch name’ of remote into ‘remote branch’ 와 같은 자동 생성 커밋 메시지가 올라온다.

머지 커밋이 불필요하다고 생각하는 경우라면

$> git pull --rebase

를 사용하면 머지 커밋이 필요없다.

Github Client 의 Sync 기능이 내부적으로 이와 같이 동작 중임. Github for Mac – help

커밋하지 않고 Git Pull 받아오기

SVN과 다르게 Git은 작업물이 완전히 커밋되어 있지 않으면 Pull 을 받아올 수 없다. 현재 작업상태를 유지하면서 Pull 을 받아오고 싶다면 stash를 사용한다. 아래 명령을 순서대로 적용하면 된다.

$> git stash
$> git pull --rebase
$> git stash pop

SSI를 이용한 HTML 산출물 모듈화

개요

SSI 는 Server Side Include 의 약자로, 웹서버에서 직접 제공하는 서버사이드 스크립트 언어 입니다.

PHP, ASP, JSP 등도 서버사이드 스크립트 언어의 범주에 들어가지만, SSI 는 대부분의 웹서버에서 직접 지원하고, 문법이 HTML 형식이라는 특징이 있습니다.

문법을 살펴보면,

<!--#include virtual="../quote.txt" -->

와 같이 HTML 의 주석 문법에 #을 붙인 형태로 지시자를 작성하고, attirubte 을 사용해 파라미터를 전달합니다.

일반적인 지시자들

일반적으로 많이 사용하는 지시자들 입니다.

#include
다른 파일을 이 파일 내부로 불러들이기
#exec
외부 명령 실행
#set
변수 선언
#echo
변수 프린트
#if, #else, #elif, #endif
조건문

특징

대부분의 웹서버에서 동일 문법으로 사용 가능

Apache, Nginx, Tomcat, Web sphere 등 다양한 웹 서버에서 동일한 문법으로 사용 가능합니다. 확인결과 Apache, Nginx, Tomcat 에서는 설치가 필요하지 않고, 설정만으로 곧바로 사용 가능합니다.

제한된 기능

SSI 는 간단한 스크립트를 작성하는데 최적화 된 언어입니다. 반복문이 없고, 모든 문법이 HTML 주석을 포함한 형태여서 코드가 길어집니다. 따라서 복잡한 작업에는 어울리지 않습니다.

활용방안

기능이 작고, 대부분의 웹서버와 호환된다는 면에서 HTML 산출물의 모듈별관리에 매우 적합합니다. 게다가 문법이 웹 퍼블리셔에게 친숙한 HTML 문법으로 작성하므로 러닝커브 면에서 꽤 괜찮은 선택입니다.

KTH FI팀에서는 현재 SSI를 활용해 HTML을 모듈별로 관리하고 있습니다.

HTML 의 모듈화는 서버사이드 언어의 지원을 받지 않으면 실현 불가능한 명제 입니다. 그래서 많은 퍼블리셔들이 반복되는 부분에 대해 아얘 모듈화하지 않거나, PHP 같은 언어의 지원을 받아 구현을 합니다.

아직 모듈화하고 있지 않다면 꼭 고려해보세요.

HTML 산출물을 작성할 때 Plain HTML 을 사용한다면 반복되는 코드는 모두 중복될 수 밖에 없습니다. 이 방법은 다른 파일에 의존성없이 완전한 결과물을 볼 수 있다는 장점이 있지만, 중복되는 부분에 변경이 발생하면 일괄 변경해야 하는 어려움이 있습니다.

모듈화된 HTML 을 사용하면

  • 변경이 간편해집니다.
  • 모듈을 퍼블리셔가 직접 지정하므로 개발자와의 커뮤니케이션 공수가 줄어듭니다.
  • 파일 내에서 공통 부분이 차지하는 코드의 양이 적어지므로 실제로 작업할 내용에 대해 집중도가 높아집니다.

만약 다른 방법으로 목적을 달성하고 있더라도 한번 고려해보세요.

사실 SSI는 이미 많이 알려진 방법이고, 굉장히 오래 전에 사용되었던 방법입니다. 하지만 시선을 HTML 산출물의 모듈관리로 돌려보면 이보다 좋은 솔루션을 찾기 어렵습니다.

  • 러닝커브가 크지 않습니다.
  • 대부분의 웹서버에서 동작합니다.
  • 웹서버에 언어모듈을 올리지 않아도 되므로 더 간단한 구조로 구현할 수 있습니다.
  • (물론 mod_includes 모듈이 로드되어야 하긴 하지만, 나도모르는 사이에 로드되어 있는 경우가 많고, 모듈 크기도 더 작습니다)

기능이 제한된다는 것은 일견 나쁠 수도 있지만 다시 생각해보면 장점으로 생각할 수도 있습니다. 단 몇가지를 위해 기능이 과도하게 많은 언어를 사용하는 것은 닭잡는데 소잡는 칼을 쓰는 것과 다르지 않기 때문입니다.

사용해보기

설정

설정은 아파치를 기준으로 합니다.

.htaccess 설정

# +Includes 를 넣었습니다. 이것은 httpd.conf 에서 <Directory> 설정을 상속받아 Includes를 추가해주어야 하므로
# Options Includes 가 아니라  Options +Includes 입니다.
# .htaccess 를 사용하려면 <Directory> 에서 AllowOverride All 로 설정하세요.
AddOutputFilter INCLUDES .html
Options +Includes

Include 사용해보기

설정이 끝나면 간단히 include 문을 테스트 해봅니다.

미리보기: http://code.elegantcoder.com/blog-examples/SSI/html5_boilerplate.html

본체- html5_boilerplate.html

  • include 문을 주의해서 봐주세요.

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <!--#include virtual="_header.html" -->
        <title>html5_boilerplate</title>
      </head>
    
      <body>
        <div>
          <header>
            <h1>html5_boilerplate</h1>
          </header>
          <nav>
            <p>
              <a href="/">Home</a>
            </p>
            <p>
              <a href="/contact">Contact</a>
            </p>
          </nav>
    
          <div>
    
          </div>
    
          <footer>
            <!--#include virtual="_footer.html" -->
          </footer>
        </div>
      </body>
    </html>
    

header – _header.html

     <meta charset="utf-8" />

    <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
    Remove this if you use the .htaccess -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />

    <meta name="description" content="" />
    <meta name="author" content="elco" />

    <meta name="viewport" content="width=device-width; initial-scale=1.0" />

    <!-- Replace favicon.ico & apple-touch-icon.png in the root of your domain and delete these references -->
    <link rel="shortcut icon" href="/favicon.ico" />
    <link rel="apple-touch-icon" href="/apple-touch-icon.png" />

footer – _footer.html

<p>
&copy; Copyright by elco
</p>

그 외의 활용 예

User-Agent Sniffing

모바일 웹에서 User Agent Sniffing 이 필요한 경우 JS를 사용하거나 다른 서버사이드 언어에 의존할 수 밖에 없는데, SSI 는 이런 간단한 작업에 적합합니다. Server 변수들은 바로 SSI 에서 사용가능하고, Apache 의 mod_rewrite 를 통하면 URL 에 따른 변수 지정도 가능합니다.

미리보기- http://code.elegantcoder.com/blog-examples/SSI/user-agent.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>User Agent Sniffing Example</title>
    </head>
    <body>
        <h1>User Agent Sniffing Example</h1>
        <div><span>User-agent String:</span><span><!--#echo var="HTTP_USER_AGENT" --></span></div>
        <!--#if expr="$HTTP_USER_AGENT = /Chrome/" -->
        <!--#set var="ua_result" value="Chrome" -->
        <!--#elif expr="$HTTP_USER_AGENT = /Safari/" -->
        <!--#set var="ua_result" value="Safari" -->
        <!--#elif expr="$HTTP_USER_AGENT = /Firefox/" -->
        <!--#set var="ua_result" value="Firefox" -->
        <!--#elif expr="$HTTP_USER_AGENT = /MSIE/" -->
        <!--#set var="ua_result" value="Internet Explorer" -->
        <!--#endif -->
        <div><span>so, u r using : </span><span><!--#echo var="ua_result" --></span></div>
    </body>
</html>

참고