웹을 떠받치는 기술은 모두 비슷한 사정이지만, 특히나 CSS 작성 결과물은 개개인의 코딩 습관과 숙련도 그리고 유동적인 브라우저 지원 상황에다 반갑지 않은 버그 등 여러 외적 요인이 모여서 큰 변수로 작용하기 마련이다. 표면적으론 단순해 보이지만, 자유의지에 맡겨진 properties 지정 작업은 픽셀 하나하나 차곡차곡 쌓아 올린 작용과 반작용의 만남이다. 이것은 잔잔한 브라우저 창에 파도의 물결을 일으키는 상상력의 실현이 될 수도, 혹은 의도치 않은 부작용 때문에 엉키고 뒤틀려버린 혼란의 골칫거리가 되버릴 수도 있다. 그래서 항상 집중과 주의가 요구되는 고난의도 작업.

이런 복잡 미묘한 상황에 조금이라도 외적 잡음을 줄이고 동시에 CSS 작성의 효율을 높이고자 OOCSS, SMACSS, BEM과 같은 여러 구조적 방법론들이 계속 등장하고 있으며, 또한 공동 작업의 편의를 위한 CSS 코딩 스타일 통합을 목적으로 properties 지정 순서에서부터 공백의 개수, 따옴표 스타일 등 아주 세세하고 민감한 부분까지 일관되게 정리해주는 CSS 빗질 도구까지 마련되어 있다.

여기서 한발 더 나아가 SASS, Less와 같은 일명 Pre-Processor의 힘을 빌려 CSS 작성 효율을 구조적으로 좀 더 끌어올리려는 노력도 활발한데, 최근엔 한술 더 떠서 CSS 후처리 과정까지 더해준 Post-Processor들도 덩달아 비 온 뒤 잡풀처럼 여기저기 생겨나고 있어서 이들의 태생 목적과 사용법을 소개하고자 한다.

CSS Pre-Processors vs. Post-Processors

CSS Pre-Processor는 기존 CSS 문법의 확장 성격으로 자기만의 syntax로 작성하고 parse/compile 과정을 거쳐 일반 CSS로 되돌려준다. 이에 반해 Post-Processor는 그냥 맨살의 CSS 문법으로 작성된 것을 해석/처리해서 다시 일반 CSS를 돌려주는 차이가 있다.

정의만 살펴보면, Post-Processor를 써서 얻을 수 있는 장점을 이해하기 힘든데, Post-Processor가 제공하고 있는 기능 중 가장 많이 애용되는 Autoprefixer의 사용 예를 보면 Post-Processor만의 장점이 뚜렷해진다.

CSS3 규칙 중 브라우저 지원 때문에 prefix를 일일이 붙여줘야 하는 상황이라면, Sass(SCSS)의 경우 mixin 기능으로 다음과 같이 적용해 줄 수 있다.

@mixin flexbox() {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
}
 
.box {
  @include flexbox();
}

하지만 Autoprefixer의 힘을 빌리면 CSS 작성은 아주 단순해진다.

.box { display: flex; }

원래의 CSS 문법을 그대로 작성하면, 후처리 과정을 거쳐 골치 아픈 vender prefix를 더해 다음과 같이 돌려준다.

.box {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
}

특정 CSS property의 브라우저 지원 상황을 일일이 확인해 가면서 mixin을 써야 할지 말아야 할지 고민할 필요가 없는 것이다.
Post-Processor(PostCSS) 소개 슬라이드: PostCSS: the Future after Sass and Less

Post-Processor를 이용한 깔끔하고 미래 지향적인 CSS 작성(이)란 제목의 글 마저 읽기 →

CSS3에서 새로 소개된 rem(root em) unit은 em unit과 마찬가지로 상대성을 띤 Relative length units 중 하나지만, 기존 부모 요소를 기준으로 한 em unit과 달리 root element, 그러니까 html element를 기준으로 그 크기 값이 정해지면서 부모 요소의 중첩으로 생기는 뻥튀기의 부작용을 걱정할 필요가 없다는 것이 장점이다.

그래서, 어느 하나의 요소를 기준으로 또 다른 요소의 상대적 크기를 정해주고 싶을 때 많이 사용되는데, 문젠 언제나 그렇듯 IE < 9을 포함해서 아직 만족스럽지 못한 rem unit의 브라우저 지원 상황을 고려해서, 미지원 브라우저에서도 인식되도록 적절한 대응 값을 함께 정의해 줘야 하는 성가심이 있다.

이런 상황에서 SaasLESS 혹은 Stylus와 같은 CSS pre-processor의 힘을 빌린다면 효율적인 CSS 작성에 큰 도움이 된다는 것은 이미 잘 알려져 있다. 하나의 좋은 본보기로, CSS pre-processor를 써서 rem unit의 fallback을 구현한 예.

한편 아래는 실험 삼아 지금 한창 논의되고 있는 CSS VariablesCalc() function만을 써서 rem unit의 fallback을 구현해 보았는데, 여기에 꼭 안성맞춤으로 CSS polyfill임을 자처하면서 지금 한창 개발중인 또 하나의 CSS preprocessor인 Myth의 힘을 빌려서 바로 적용해 보았다.

:root {
  var-base-font-size: 10;
  var-body-font-size: 14;
  var-heading1-font-size: 18;
}
 
html {
  font-size: calc(var(base-font-size) / 16 * 100%);
}
 
body {
  font-size: calc(0px + var(body-font-size));
  font-size: calc(0rem + var(body-font-size) / var(base-font-size));
}
 
h1 {
  font-size: calc(0px + var(heading1-font-size));
  font-size: calc(0rem + var(heading1-font-size) / var(base-font-size));
}

이렇게 작성된 CSS는 Myth를 통해 다음과 같이 변환된다.
CSS Variables와 Calc() function을 써서 rem unit의 fallback 구현하기(이)란 제목의 글 마저 읽기 →

가령, CSS3 애니메이션 효과를 적용할 때 미지원 브라우저한테는 대신에 JavaScript를 써서 애니메이션 효과를 대체하려고 할 때 유용한 gist로 jQuery plugin 형태로 다음과 같은 것이 있다.

$.support.cssProperty = (function() {
  function cssProperty(prp) {
    var b = document.body || document.documentElement,
    s = b.style;
 
    // No css support detected 
    if(typeof s == 'undefined') { return false; }
 
    // Tests for standard prop 
    if(typeof s[p] == 'string') { return rp ? p : true; }
 
    // Tests for vendor specific prop 
    v = ['Moz', 'Webkit', 'Khtml', 'O', 'ms', 'Icab'],
    p = p.charAt(0).toUpperCase() + p.substr(1);
    for(var i=0; i<v.length; i++) {
      if(typeof s[v[i] + p] == 'string') { return rp ? (v[i] + p) : true; }
    }
  }
 
  return cssProperty;
})();

출처 – Extends the jQuery.support object to CSS Properties

처음부터 무조건 JavaScript를 써서 애니메이션 효과를 주지 않는 이유는, 당연 CSS3 애니메이션 효과를 지원하는 브라우저에선 더 매끄러울 테니까 그렇다.
사용 예: CSS3 Dropdown Menu – CodePen

과거 Ajax를 필두로 웹 기술이 진화하면서 많은 웹 애플리케이션이 개발돼서 공개되고 있는데, 이런 곳엔 소위 ‘Loading spinner (Activity indicator)’를 쓸 일도 많아졌다. 이는 요청한 작업이 정상적으로 처리 중임을 알려주는 것으로 사용자 경험 측면에서 아주 중요한 요소 중의 하나이다.

이런 효과를 나타내려고 과거엔 animated gif 이미지를 주로 썼지만, 브라우저의 CSS3 Animation과 Transforms 지원 상황이 호전되면서 지금은 더 효과적인 대체수단으로서 선택적으로 CSS가 사용되고 있다. 이런 추세에 맞춰 CSS spinners를 만들어주는 도구도 생겨났는데 대표적으로 CSS load.net이 있다.

CSS에서 제공하고 있는 다양한 효과와 함께 개발자의 상상력만 더하면 아주 멋진 효과를 구현할 수가 있는데, 아래는 CSS3 Animation, Transforms와 함께 중첩된 text-shadow 효과를 써서 구현해 본 예 (animated GIF 이미지).
CSS3 loading spinner
현재 최신 버전의 Firefox, Chrome 그리고 Safari만이 CSS3 Animation과 Transforms 모두를 지원하기 때문에, 그 외 브라우저에선 아직 대체 이미지의 사용이 불가피하다. (차기 버전인 IE 10과 Opera 12에선 모두 지원 예정.)

CSS3 Loading Spinner 데모 페이지

이미 널리 쓰이고 있는 CSS3 Gradients의 용법이 이번에 또 바뀌었는데, 관련 CSS Image Values and Replaced Content Module Level 3가 지난 1월 12일에 “Last Call” draft 상태로 진입한 것을 보면 어떤 커다란 용법의 변경은 더는 없으리라 예상(기대)된다.

우선 Linear Gradient 용법의 달라진 점.

Linear Gradient의 가장 단순한 사용 예로 다름과 같은 것이 있다. (vendor prefix는 생략함)

div { background: linear-gradient(whiteblack); }

적용하면 위에서 아래 방향으로 흰색을 시작으로 점점 짙어지면서 마지막은 검은색으로 표시된다.

linear gradient function의 첫 번째 argument는 gradient의 시작점과 끝점을 잇는 기준 축인 gradient-line을 지정하게 되는데, 위의 예에서처럼 생략되면 위에서 아래방향을 가리킨다. 그리고 gradient-linedeg 단위를 써서 각도를 지정해 주거나, 혹은 몇몇 정의된 keywords를 쓸 수도 있다. 거의 막바지에 바뀐 CSS3 Gradients 용법(이)란 제목의 글 마저 읽기 →