구닥다리 공룡을 위한 오늘날의 CSS

in #css6 years ago

이 post는 아래 article을 번역한 것입니다.

Modern CSS Explained For Dinosaurs

  • 영문 고유명사는 가능한 영문 그대로 썼습니다.
  • 비표준어를 다소 사용했습니다.
  • 저는 전문 번역가가 아닙니다. 오역이 있을 수 있으니 의심 스러운 부분은 원문을 참고하세요!
  • 원문에 있는 링크가 빠졌다거나 오탈자가 있으면 제보 부탁드립니다. 정말 감사하겠습니다.

c01.png
Images from Dinosaur Comics by Ryan North

이상하게도 CSS는 웹 개발자에게 있어 가장 쉽고도 가장 어려운 언어로 여겨집니다. 분명 아주 쉽게 시작할수 있습니다-특정 엘리먼트에 적용할 스타일 프로퍼티와 값을 적용하고, 그리고… 뭐 이정도면 필요한건 전부 다 한 거죠. 그러나 더 커다란 프로젝트에 의미있는 방법으로 CSS를 구성할라치면 갈수록 엉키고 꼬이기 시작합니다. 한 페이지의 엘리먼트에 스타일을 주기 위해 CSS 한줄을 바꿔 놓으면 의도치 않게 다른 페이지의 엘리먼트들이 바뀌어 버리곤 합니다.

CSS의 상속 복잡성을 다루기 위해서 온갖 종류의 ‘최고의 방법’들이 수립되었습니다. 문제는 어떤 최고가 진짜 최고인지 확실한 의견 일치를 보지 못했다는 겁니다. 그래서 이들 중 많은 수가 서로에게 모순적으로 보입니다. 만약 여러분이 생애 최초로 CSS를 학습하고자 한다면 이 말이 혼란스러울 겁니다.

이 글의 목표는 CSS의 접근 방식과 도구화(tooling)가 2018년 오늘날 까지 어떻게 발전했는지에 대한 역사적 맥락을 짚어 보는 겁니다. 이 역사를 이해함으로써 접근법과 CSS를 유용하게 사용할 방법을 더 쉽게 받아 들일 수 있을 겁니다. 자 그럼 시작해 보죠!

CSS로 기초 스타일링 하기

단순한 웹사이트 부터 시작해 봅시다. 여기 별도의 index.css 파일을 연결한 index.html 파일이 있습니다:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Modern CSS</title>
  <link rel="stylesheet" href="index.css">
</head>
<body>
  <header>This is the header.</header>
  <main>
    <h1>This is the main content.</h1>
    <p>...</p>
  </main>
  <nav>
    <h4>This is the navigation section.</h4>
    <p>...</p>
  </nav>
  <aside>
    <h4>This is an aside section.</h4>
    <p>...</p>
  </aside>
  <footer>This is the footer.</footer>
</body>
</html>

지금은 HTML에 클래스나 아이디없이 그저 시맨틱 태그만 있습니다. 아무런 CSS도 없기 때문에 아래와 같이 보일겁니다 (플래이스홀더 텍스트 사용):

ss01.png

여길 누르면 라이브 예시를 볼 수 있습니다.

기능적이지만 예쁘진 않죠. index.css에 CSS를 더하면 기본 타이포그래피를 발전시킬 수 있습니다.

/* BASIC TYPOGRAPHY                       */
/* from https://github.com/oxalorg/sakura */
html {
  font-size: 62.5%;
  font-family: serif;
}
body {
  font-size: 1.8rem;
  line-height: 1.618;
  max-width: 38em;
  margin: auto;
  color: #4a4a4a;
  background-color: #f9f9f9;
  padding: 13px;
}
@media (max-width: 684px) {
  body {
    font-size: 1.53rem;
  }
}
@media (max-width: 382px) {
  body {
    font-size: 1.35rem;
  }
}
h1, h2, h3, h4, h5, h6 {
  line-height: 1.1;
  font-family: Verdana, Geneva, sans-serif;
  font-weight: 700;
  overflow-wrap: break-word;
  word-wrap: break-word;
  -ms-word-break: break-all;
  word-break: break-word;
  -ms-hyphens: auto;
  -moz-hyphens: auto;
  -webkit-hyphens: auto;
  hyphens: auto;
}
h1 {
  font-size: 2.35em;
}
h2 {
  font-size: 2em;
}
h3 {
  font-size: 1.75em;
}
h4 {
  font-size: 1.5em;
}
h5 {
  font-size: 1.25em;
}
h6 {
  font-size: 1em;
}

여기 대부분의 CSS가 타이포그래피(폰트 사이즈, 라인 높이, 기타 등등)를 스타일링하며, 몇몇은 색깔과 가운데 정렬 레이아웃을 스타일링 합니다. 각각의 프로퍼티에 좋은 값을 선택할 수 있으려면 디자인을 공부해야 합니다(이 예제의 스타일은 sakura.css에서 가져왔습니다). 그러나 여기에 적용된 CSS 자체는 읽기에 그리 어렵지 않습니다. 결과는 아래와 같습니다:

ss02.png

여길 누르면 라이브 예시를 볼 수 있습니다.

완전 딴판이네요! 이것이 CSS의 약속입니다-단순한 방법으로 문서에 스타일을 입히는 것, 복잡한 로직이나 프로그래밍을 요구하지 않는 것. 그러나 불행히도 CSS를 통해 파이포그래피와 색깔 이상의 (다음 장에서 다룰)무언가를 시도하면 상황은 엉킨 털 투성이처럼 됩니다.

CSS로 레이아웃 잡기

1990년대, CSS가 대대적으로 적용되기 이전에는 페이지 콘텐트를 레이아웃 하기 위한 옵션이 그리 많지 않았습니다. HTML은 기본적으로 사이드바나 칼럼 등이 없는 정적인 웹사이트, 단순한 문서를 만들기 위해 설계된 언어였죠. 그런 초기에는 레이아웃을 위해 주로 HTML 테이블이 사용되었습니다-전체 웹 사이트가 컨테트를 행과 열에 담을 수 있는 하나의 테이블로 구성 됐었죠. 이 방식은 꽤 효과적이었지만, 기저에서 내용(content)과 표현(presentation)이 빡빡하게 엮였습니다-이는 사이트의 레이아웃을 바꾸고자 한다면 상당한 양의 HTML을 새로 작성해야만 함을 뜻합니다.

CSS가 등장하자 내용(HTML로 작성)과 표현(CSS로 작성)을 구별하라는 강한 압박이 있었습니다. 그래서 사람들은 모든 레이아웃 코드를 (더 이상 테이블을 쓰지 않도록)HTML에서 CSS로 옮기는 방법을 찾았었죠. HTML처럼 CSS도 페이지 콘텐트를 레이아웃하기위해 설계된 녀석이 아님을 알아 두세요. 그래서 내용과 표현을 근사하게 구별하고자 했던 초기의 시도들은 굉장히 까다로웠습니다.

이게 어떻게 돌아가는건지 위 예제에다 연습해 보도록 하죠. CSS 레이아웃을 설정하기 전에, 먼저 마진이나 패딩(레이아웃 계산에 영향을 미치는 것들)을 리셋시킬겁니다. 또 각 섹션을 구별하기 위해 색을 넣을 겁니다(예쁘게 만들지 않을 거예요. 다만 레이아웃을 시험 할 때 시각적으로 서로 구분되도록 할겁니다).

/* RESET LAYOUT AND ADD COLORS */
body {
  margin: 0;
  padding: 0;
  max-width: inherit;
  background: #fff;
  color: #4a4a4a;
}
header, footer {
  font-size: large;
  text-align: center;
  padding: 0.3em 0;
  background-color: #4a4a4a;
  color: #f9f9f9;
}
nav {
  background: #eee;
}
main {
  background: #f9f9f9;
}
aside {
  background: #eee;
}

이제 웹사이트는 잠시 이렇게 보일겁니다:

ss03.png

여길 누르면 라이브 예시를 볼 수 있습니다.

이제 CSS 레이아웃을 페이지 콘텐트에 사용할 준비가 됐습니다. 연대기적 순서에 따라 서로 다른 세 가지 접근법을 살펴볼 것이며, 그 시작으로 전통적인 float 기반 레이아웃을 보기로 합시다.

float 기반 레이아웃

CSS float는 텍스트 칼럼 내의 이미지를 왼쪽 또는 오른쪽으로 띄우기 위한 프로퍼티로 소개되었습니다(신문에서 흔히 볼 수 있는 그거요). 2000년대 초 웹 개발자들은 이미지 뿐만 아니라 어떤 엘레먼트든지 띄울(float) 수 있다는 사실을 잘 활용했습니다. 이는 전체 콘텐트의 div를 띄움으로써 행과 열의 환영을 만들수 있음을 의미합니다. 그러나 다시 말하지만, float는 레이아웃을 목적으로 만들어진 것이 아니기 때문에 환영을 만들어내는 일을 일관된 방식으로 시작하기가 어려웠습니다.

2006년, A List Apart는 인기있는 아티클 In Search of the Holy Grail을 발표했습니다. 이 아티클은 -하나의 헤더, 세개의 칼럼, 하나의 풋터로 구성되는-Holy Grail 레이아웃을 만들기 위한 상세하고도 철저한 접근법의 개요를 담고 있었습니다. 상당히 단순한 이 레이아웃을 Holy Grail(성배) 라고 부르는게 꽤 웃기게 들릴 수도 있지만, 그 시절의 순수한 CSS를 사용하여 일관된 레이아웃을 만드는 일은 정말로 엄청나게 어려운 일이었습니다.

아래는 위 아티클에 기술된 테크닉을 기반으로 한 float 레이아웃 예제입니다:

/* FLOAT-BASED LAYOUT */
body {
  padding-left: 200px;
  padding-right: 190px;
  min-width: 240px;
}
header, footer {
  margin-left: -200px;
  margin-right: -190px;   
}
main, nav, aside {
  position: relative;
  float: left;
}
main {
  padding: 0 20px;
  width: 100%;
}
nav {
  width: 180px;
  padding: 0 10px;
  right: 240px;
  margin-left: -100%;
}
aside {
  width: 130px;
  padding: 0 10px;
  margin-right: -100%;
}
footer {
  clear: both;
}
* html nav {
  left: 150px;
}

CSS를 봅시다. 목표한 레이아웃을 얻기 위해 필요한 몇몇 핵(음수 마진, clear: both 프로퍼티, 하드코딩한 너비 계산 등등)들을 볼 수 있습니다. 이 아티클은 각각을 추론하는 자세하고 좋은 설명을 해주고 있습니다. 아래 그 결과물을 볼 수 있습니다:

ss04.png

여길 누르면 라이브 예시를 볼 수 있습니다.

꽤 나이스 합니다. 그러나 세 칼럼의 높이가 다르고 스크린 높이만큼을 페이지가 꽉 채워주질 못하고 있습니다. 이런 이슈들이 float 레이아웃에 상속되고 있습니다. 모든 float은 콘텐트를 섹션의 왼쪽 또는 오른쪽으로 위치 시킬 수 있습니다. 그러나 CSS에는 다른 섹션의 콘텐츠 높이를 알아낼 수 있는 방법이 없습니다. 이 문제점은 수년 후 flex 기반 레이아웃의 등장 전까지 곧바로 해결 할 수 없었습니다.

역자의 discussion

이 부분은 원 아티클에서 번역된 내용이 아닙니다. 다만 문맥상 중요하다고 여겨져 첨부합니다.

음수 마진은 핵이 아닙니다. The Definitive Guide to Using Negative Margin에 아래와 같은 구문이 있습니다.

Negative margins are not a hack. This is especially true. It’s because of not understanding negative margins properly that it got its hackish image. It only becomes a hack if you use it to fix an error you made elsewhere.

음수 마진은 핵이 아닙니다. 이는 분명한 사실입니다. 음수 마진이 갖고 있는 핵 스러운 이미지는 음수 마진에 대한 잘 못 된 이해가 불러온 것입니다. 핵이란 것은 다른 곳에서 만들어지는 오류를 수정하는데 사용되는 것을 말합니다.

실제로 W3C 공식 문서에서도 다음과 같은 구문을 찾아 볼 수 있습니다.

Negative values for margin properties are allowed, but there may be implementation-specific limits.

마진에 대한 음수 값은 허용되어 있습니다. 단지 구현 스펙상의 제한이 있을 수 있습니다.

이에 대해서 원 작성자인 Peter Jang에게 문의한 결과 다음과 같은 대댓글을 받았습니다.

You’re definitely right about negative margins not being a hack in the sense that they’re supported by CSS. I’m referring to negative margins being a hack in the sense that you shouldn’t need to use negative margins to define a layout. They’re a hack that enables floats to create the illusion of columns, which is cool but was something it was never designed to do, and they’re fragile for layout (changing the width of a column also requires changing the negative margins).

네 말이 맞아. 음수 마진은 핵이 아니야. CSS가 정식으로 지원 한다는 점에서는 그렇지. 내가 음수 마진을 핵이라고 한 건 음수 마진이 레이아웃에 쓰려고 만들어진게 아니라는 맥락 위에서야. float으로 가짜 열을 만들기 위해 사용되는 핵은 유용하긴 하지만 절대 그렇게 쓰라고 설계 된 것들이 아니지. 그리고 레이아웃을 깨트리기 쉬워(열의 너비를 바꾸려면 음수 마진도 바꿔줘야 한다는 걸 생각 해 봐).

결론을 내리자면, CSS 마진은 스펙상으론 핵이 아니지만 레이아웃을 위해 사용된다는 상황에선 핵으로써 쓰이고 있는 겁니다. 레이아웃을 만들기 위해 존재하는 스펙이 아니기 때문이죠.

자 그럼 다시 원글의 번역으로 돌아가도록 하겠습니다.

Flexbox 기반 레이아웃

flexbox 프로퍼티는 2009년 제안되었지만 2015년 전까지 그리 널리 퍼지지는 못했습니다. Flexbox는 공간이 하나의 열 또는 행을 가로질러 어떻게 배분될 것인지를 정의하기 위해 설계되었습니다. 레이아웃을 잡는데 float을 쓰는 것 보단 나은 대안으로요. float 기반의 레이아웃을 사용한지 10여년만에 웹 개발자들은 비로소 핵을 써야하는 float을 써야할 필요 없어진 것입니다. (역주: 국내는 구버전 Internet Explorer의 점유율이 비교적 높기 때문에 브라우저 호환을 지원해야 한다면 여전히 float 기반의 레이아웃을 사용해야 합니다.)

아래는 다양한 flexbox 예시가 있는 인기 사이트, Solved by Flexbox에 기술된 테크닉을 우리의 예제에 적용시켜 본 것입니다. flexbox를 구현하기 위해서 3개의 div 래퍼가 HTML상에 추가 된 것을 주의 하세요:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Modern CSS</title>
  <link rel="stylesheet" href="index.css">
</head>
<body>
  <header>This is the header.</header>
  <div class="container">
    <main>
      <h1>This is the main content.</h1>
      <p>...</p>
    </main>
    <nav>
      <h4>This is the navigation section.</h4>
      <p>...</p>
    </nav>
    <aside>
      <h4>This is an aside section.</h4>
      <p>...</p>
    </aside>
  </div>
  <footer>This is the footer.</footer>
</body>
</html>

flexbox CSS 코드입니다:

/* FLEXBOX-BASED LAYOUT */
body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.container {
  display: flex;
  flex: 1;
}
main {
  flex: 1;
  padding: 0 20px;
}
nav {
  flex: 0 0 180px;
  padding: 0 10px;
  order: -1;
}
aside {
  flex: 0 0 130px;
  padding: 0 10px;
}

이 방식이 float 기반의 레이아웃 방식보다 훨씬 컴팩트 하네요! flexbox 프로퍼티와 값은 언뜻 보기엔 무척 혼란스럽습니다. 그러나 float 기반 레이아웃을 사용할 때 필요한 무수한 핵을 제거 할 수 있게 됩니다. 더 큰 승리죠. 여기 결과 화면이 어떤지 봅시다:

ss05.png

훨씬 낫네요! 모든 열들이 동일한 높이를 갖고 페이지는 최대 높이를 얻었습니다. 어떻게 보면 완벽합니다. 하지만 조금 불안한 구석이 있습니다. 먼저 브라우저 호환성을 들 수 있겠습니다. 현재 대부분의 모던 브라우저는 flexbox를 지원합니다. 그러나 몇몇 옛날 부라우저는 영원히 그럴일이 없을 겁니다. 다행스럽게도 브라우저 제작사들은 이들 구식 브라우저에 대한 지원을 중단하기위해 많은 노력을 기울이고 있습니다. 이는 웹 디자이너에게 보다 일관된 개발 경험을 제공할겁니다. 또 다른 불안한 점은 마크업에 <div class="container">을 추가해야 한다는 것입니다. 이건 안 할 수 있다면 하지 않는 편이 좋습니다. CSS 때문에 HTML 마크업을 변경하는 일은 이상적이지 못합니다.

가장 불안한 점은 무엇보다도 CSS 코드 자체에 있습니다-flexbox는 모든 float 핵을 없애주지만 레이아웃을 정의하는 것 처럼 표현이 풍부하지 않습니다. flexbox CSS는 읽기 어렵고 모든 요소들이 페이지 위에 어떻게 놓여 있는지 시각적으로 이해해야만 합니다. 무척 많은 추측과 검증이 필요하게 되죠.

flexbox는 페이지 전체를 레이아웃 하기 위해 만들어진 것이 아닙니다. 단일 열 또는 행의 요소를 배치하기 위해 만들어졌습니다. flexbox로 (float 기반 레이아웃보다 훨씬 효율적인)서비스 가능한 작업을 할 수 있지만, 여러 행과 열이 있는 레이아웃을 처리하기 위해 다른 사양이 특별히 개발되어 있습니다. 이것이 바로 CSS Grid입니다.

Grid 기반 레이아웃

CSS grid는 2011년 첫 선을 보였습니다(flexbox가 소개된지 그리 오래지 않았던 때였죠). 그러나 많은 브라우저에 적용되기까지는 꽤 긴 시간이 필요했습니다. 2018년 초입인 현재, CSS grid는 대부분의 모던 브라우저에서 지원하고 있습니다(일 이년 사이에 많은 개선이 있었어요).

아래 우리의 grid 기반 레이아웃 예제가 있습니다. CSS tricks article의 첫번째 방식을 따랐습니다. flexbox 기반 레이아웃에선 추가할 수 밖에 없었던 <div class="container">을 이 예제에서는 없앨 수 있단 것에 주목해 주세요-별도의 수정없이 원본 HTML만 사용할 수 있습니다. CSS는 이렇게 생겼어요:

/* GRID-BASED LAYOUT */
body {
  display: grid;
  min-height: 100vh;
  grid-template-columns: 200px 1fr 150px;
  grid-template-rows: min-content 1fr min-content;
}
header {
  grid-row: 1;
  grid-column: 1 / 4;
}
nav {
  grid-row: 2;
  grid-column: 1 / 2;
  padding: 0 10px;
}
main {
  grid-row: 2;
  grid-column: 2 / 3;
  padding: 0 20px;
}
aside {
  grid-row: 2;
  grid-column: 3 / 4;
  padding: 0 10px;
}
footer {
  grid-row: 3;
  grid-column: 1 / 4;
}

결과물이 시각적으로 flexbox 기반 레이아웃과 동일합니다. 그러나 CSS 코드상으로 목표 레이아웃이 깔끔하게 표현된다는 점에서 훨씬 발전된 모습입니다. 열과 행의 크기와 모양이 바디 선택자안에 정의되어 있고, 그리드 내 각각의 아이템들이 각각의 위치에 직접 정의되고 있습니다.

한 가지 혼란스러운 점은 grid-column프로퍼티 입니다. 열의 시작점과 종료점을 정의하는 프로퍼티예요. 이 예제에는 세 개의 열이 있지만 그 수의 범위는 1부터 4까지이기 때문에 혼란스러울 수 있습니다. (그러나) 아래의 그림을 보면 훨씬 쉽게 이해 될 겁니다.

ss06.png

여길 누르면 라이브 예시를 볼 수 있습니다.

첫번째 열은 1에서 시작하고 2에서 끝납니다. 두번째 열은 2에서 시작하고 3에서 끝나며, 세번째 열은 3에서 시작하고 4에서 끝나죠. header는 전체 페이지에 걸쳐(span) 나타나기 위하여 1 / 4grid-column을 가지며, nav는 첫번째 열에만 걸쳐 나타나기 위하여 1 / 2grid-column을 가지고 있습니다.

그러나 일단 grid 문법에 익숙해지고 나면, 명백히 CSS 레이아웃 표현의 이상적인 방법으로 다가올 것입니다. grid 기반 레이아웃에는 딱 한가지 불안한 구석이 있는데 바로 브라우저 호환성입니다. 지난 한 해 동안 급격히 발전한 기술이기 때문이죠. CSS grid는 레이아웃을 위해 설계된 실질적인 첫번째 도구이기에 그 중요성이 과장이라 하기 어렵습니다. 한편으론, 웹 디자이너들은 늘 창의적인 레이아웃을 만드는데 보수적이었습니다. 여태까지의 도구들은 부숴지기 쉽고, 차선책으로 핵을 무더기로 써야하는 것들이었기 때문이죠. 그러나 이제 CSS grid가 있습니다. 창의적인 레이아웃 디자인의 새로운 파도를 일으킬 힘이 잠재되어 있습니다. 이전까지는 전혀 시도 할 수 없었던 그런것들을 말이죠-즐길 시간이예요!

c02.png

새로운 구문법을 위한 CSS 프리프로세서 사용하기

지금까지 레이아웃과 기본적인 스타일링을 위해 CSS를 사용해 봤습니다.
이제 CSS를 언어로 작업하는데에 있어 사용경험을 발전시켜 줄 도구를 알아보도록 합시다. CSS 프리프로세서(preprocessor, 전처리기)로 시작해 보죠.

CSS 프리프로세서는 다른 언어로 스타일링 코드를 쓸 수 있게 해줍니다. 다른 언어가 브라우저에서 해석 가능한 CSS로 변환되는 것이죠. 브라우저들이 새로운 기능을 구현하는데 미온적이었던 과거에는 이것이 매우 중요했습니다. 최초의 주류 CSS 프리프로세서는 2006년 출시 된 Sass였습니다. 새로운 축약형 구문(들여쓰기가 브라켓({, })을 대신하고, 세미콜론이 없는 등)을 제공했고 CSS엔 없는 보다 진보된 기능들도 있었습니다. 예를 들면 변수, 헬퍼 함수, 계산기능 같은 것들 말입니다. 여기 색깔 섹션에 대한 우리의 예제를 Sass의 변수로 구현한 코드가 있습니다:

$dark-color: #4a4a4a
$light-color: #f9f9f9
$side-color: #eee
body
  color: $dark-color
  
header, footer
  background-color: $dark-color
  color: $light-color
  
main
  background: $light-color
nav, aside
  background: $side-color

재사용 가능한 변수는 $ 심볼을 써서 정의합니다. 브라켓과 세미콜론은 없어졌으며 구문이 보기에 훨씬 깔끔해 보입니다. 더 깔끔해 보인다는 점은 그저 멋진 것이지만, 변수와 같은 기능은 당시로썬 혁명적인 수준이었죠. 깨끗하고 관리가능한 CSS를 작성할 수 있는 새로운 가능성을 열어주었으니까요.

Sass를 쓰기 위해서는 Ruby를 설치해야 합니다. Sass 코드를 보통의 CSS 코드로 바꿔주기 위한 프로그래밍 언어입니다. 설치하고 난 후에는 Sass gem을 설치해야하고, 그 후에는 커맨드 라인에 명령어를 입력하여 .sass 파일을 .css 파일로 변환 시킵니다. 여기 명령어의 예시가 있습니다:

sass --watch index.sass index.css

이 명령어는 index.sass에 작성된 Sass 코드를 index.css라는 보통의 CSS 파일로 변환시켜 줍니다(--watch 옵션은 입력 변화를 매번 저장을 할 때마다 명령어를 자동으로 실행시켜주므로 편리합니다).

이 과정은 빌드 과정이라고 불리오며 2006년 이전에는 상당한 진입 장벽이었습니다. 만약 Ruby 같은 프로그래밍 언어를 쓸 줄 안다면, 이런 과정은 무척 쉽습니다. 그러나 그 시절 많은 프론트엔드 개발자들은 오직 HTML과 CSS로만 일했습니다. 이런 도구는 필요로 하질 않았죠. 때문에 CSS 프리프로세서가 제공하는 기능을 쓰기 위해 하나의 생태계를 통째로 배워야 하는 것이 무척 중요합니다.

2009년, Less라는 CSS 프리프로세서가 출시되었습니다. 이 역시 Ruby로 작성 되었으며 Sass와 비슷한 기능을 제공했습니다. 가장 크게 다른 점은 문법으로, CSS와 보다 가깝게 설계되었습니다. 이 말인 즉 어떤 CSS 코드라도 Less 코드로써 유효 하다는 것입니다. 여기 똑같은 내용을 Less 구문으로 작성한 예제가 있습니다:

@dark-color: #4a4a4a;
@light-color: #f9f9f9;
@side-color: #eee;
body {
  color: @dark-color;
}
  
header, footer {
  background-color: @dark-color;
  color: @light-color;
}
  
main {
  background: @light-color;
}
nav, aside {
  background: @side-color;
}

($대신 @를 변수명 앞에 써야 되는 것 처럼) 거의 비슷하지만 CSS와 같은 컬리 브라켓과 세미콜론때문에 Sass처럼 예쁘지는 않습니다. 그러나 CSS와 비슷하다는 점 때문에 개발자들이 적응하기에 훨씬 편합니다. 2012년 Less는 컴파일링을 위해 Ruby를 사용하는 대신 JavaScript(정확히는 Node.js)를 사용하도록 다시 씌여졌습니다. 이는 루비를 사용할때보다 Less를 훨씬 빠르게 해줬고 이미 Node.js 워크플로우를 사용하고 있던 개발자들에겐 굉장히 매력적이었습니다.

이 코드를 보통의 CSS로 바꾸려면 우선 Node.js를 설치 하고 이후에 Less를 설치해야 합니다. 그리고 아래와 같은 명령어를 입력하면 됩니다.

lessc index.less index.css

이 명령어는 index.less의 Less 코드를 보통의 CSS코드로 변환하여 index.css파일에 저장합니다. lessc 명령은 파일의 변화를 감시하지 않는단 사실에 주의하세요(sass 명령과는 다르게도 말입니다), 즉 자동으로 .less파일을 감시하고 컴파일 하려면 다른 도구를 설치해야 된다는 말입니다. 과정이 조금 복잡해 질거예요. 다시 한 번 말씀드리지만 이는 커맨드 라인 도구에 익숙한 프로그래머들에겐 어렵지 않아요. 그치만 CSS 프리프로세서를 간편하게 사용하고픈 다른 사람들에게는 꽤 힘겨운 진입 장벽입니다.

Less가 인기를 얻은 것 처럼, Sass 개발자들도 새로운 문법을 도입하여 2010년 SCSS를 선보입니다(Less와 닮은 CSS의 상위 집합입니다). 또 Ruby Sass 엔진의 C/C++ 포트로 더 빠르고 다양한 언어를 사용 할 수 있게 해주는 LibSass를 출시 합니다.

다른 CSS 프리프로세서의 대안으로 Stylus가 있습니다. 2010년에 공개되었으며 Node.js로 작성되었고, Sass나 Less 보다 더 깔끔한 구문을 추구합니다. CSS 프리프로세서라 하면 주로 이 셋(Sass, Less, Stylus)을 가리킵니다. 이 들은 갈수록 서로의 기능을 모방하며 비슷해 지고 있기 때문에 셋 중 뭘 고른다 해도 나쁠게 없습니다.

그러나 어떤 사람들은 CSS 프리프로세서의 필요성에 대해 비관적입니다. 브라우저들이 마침내 프리프로세서들의 기능을 구현하고있기 때문입니다(변수나 계산기능등을 말입니다). 더 나아가서 CSS 포스트프로세서(postprocessor, 후처리기)라고 하는 또 다른 접근방법이 존재합니다. 이 녀석은 CSS 프리프로세서를 구시대의 유물로 만들어 버릴 수 있는 잠재력을 갖고 있습니다(여기에 논란이 없는 것은 아닙니다). 다음으로 이 포스트프로세서를 살펴보도록 합시다.

변형적인 기능을 위해 CSS 포스트프로세서 사용하기

CSS 포스트프로세서는 JavaScript를 이용해 CSS 코드를 분석하고 유효한 CSS로 변환시킵니다. 이러한 맥락에서 말하자면 CSS 프리프로세서와 굉장히 비슷합니다. 똑같은 문제를 풀기 위한 다른 접근법이라고 생각 할 수 있죠. 가장 중요한 차별점은 다음과 같습니다. CSS 프리프로세서가 무엇이 변환되어야 하는지 나타내기 위해 특별한 구문법을 사용해야 되는 것에 비해 CSS 포스트프로세서는 평범한 CSS를 해석하고 변환시킵니다. 특별한 구문법이 요구 되는 일 없이요. 직접 한 번 보는게 좋을것 같네요. 우리가 위에서 정의했던 헤더 태그들의 스타일 정의를 보도록 합시다:

h1, h2, h3, h4, h5, h6 {
  -ms-hyphens: auto; /* vendor-prefix */
  -moz-hyphens: auto; /* vendor-prefix */
  -webkit-hyphens: auto; /* vendor-prefix */
  hyphens: auto;
}

/* vendor-prefix */ 주석이 달린 행들은 벤더 프리픽스(prefix, 접두사)를 사용한 것입니다. 벤더 프리픽스는 브라우저가 최신 CSS 기능을 실험적으로 새로이 추가하거나 테스트하기 위해 사용되며, 정식 구현 전에 개발자들에게 이런 최신 기능을 사용해 볼 수 있는 방법을 제공합니다. -ms 프리픽스는 마이크로소프트 인터넷 익스플로러, -moz 프리픽스는 모질라 파이어폭스, -webkit 프리픽스는 웹킷 렌더링 엔진을 쓰는 브라우저(구글 크롬, 사파리, 신 버전의 오페라)를 위해 사용합니다.

이런 CSS 프로퍼티를 사용하기 위해서 각각의 벤더 프리픽스를 기억하고 매번 써 넣어줘야 한다는건 꽤 귀찮습니다. 자동으로 필요한 벤더 프리픽스를 넣어주는 도구가 있다면 좋을 것 같아요. CSS 프리프로세서를 사용해서 이걸 해결 할 수 있습니다. 예를 들어 아래와 SCSS를 아래와 같이 사용하는거죠:

@mixin hyphens($value) {
  -ms-hyphens: $value;
  -moz-hyphens: $value;
  -webkit-hyphens: $value;
  hyphens: $value;
}
h1, h2, h3, h4, h5, h6 {
  @include hyphens(auto);
}

위에서 Sass의 mixin 기능을 쓰고 있습니다. 한 뭉치의 CSS 코드 더미를 정의해놓고 언제 어디서고 재사용 할 수 있는 기능이죠. 이 코드가 보통의 CSS로 컴파일 되면 @include 구문은 매칭되는 @mixin 구문의 CSS로 대치 됩니다. 물론 이게 나쁜 해결책은 아닙니다. 그러나 매번 벤더 프리픽스가 필요한 CSS 프로퍼티가 필요하면 각각을 위한 mixin을 만들어 줘야만 합니다. 이 mixin 정의들은 관리가 필요합니다. 브라우저들이 해당 기능을 정식 지원하게 되면 더 이상 벤더 프리픽스를 쓸 필요가 없어지니까요.

mixin을 사용하는 대신 보통의 CSS를 쓰고 도구가 알아서 프리픽스가 필요한지 프로퍼티를 확인하고 적절히 대처 한다면 좋을 것 같습니다. CSS 포스트프로세서는 정확히 이런 일을 해줄 수 있습니다. 예를 들어, autoprefixer 플러그인과 함께 PostCSS를 사용하면 완전히 평범한 보통의 CSS를 어떠한 벤더 프리픽스 없이 쓸 수 있습니다. 포스트프로세서가 나머지 일들을 해주기 때문이죠:

h1, h2, h3, h4, h5, h6 {
  hyphens: auto;
}

위 코드에 CSS 포스트프로세서를 구동시키면 결과로써 hyphens: auto;행이 적절한 모든 종류의 벤더 프리픽스가 붙은 행들로 교체 될 거에요(autoprefixer 플러그인에 정의된 대로 바뀌는 것이지만 이 정의는 사용자가 직접 관리하는게 아니예요). 이 말은 호환성이나 특별한 구문법에 대해 어떠한 걱정도 필요 없이 보통의 CSS를 작성하면 된다는 것입니다. 끝내 주죠!

autoprefixer 말고도 PostCSS에 사용할 수 있는 다양하고 멋진 플러그인들이 있습니다. cssnext 플러그인은 실험적인 CSS 기능들을 사용 할 수 있게 해줍니다. CSS modules 플러그인은 이름 충돌을 피할 수 있도록 자동으로 클래스들을 바꿔 줍니다. stylelint 플러그인은 오류나 일관적이지 못한 CSS 컨벤션을 식별해 냅니다. 이 도구들은 작년, 길어봐야 재작년에 갓 실시되어 지금까지 볼 수 없었던 개발자들의 워크플로우를 선보였습니다!

하지만 포스트프로세서를 사용하려면 약간의 대가가 필요합니다. PostCSS와 같은 CSS 포스트프로세서를 설치하고 사용하는 일은 CSS 프리프로세서를 사용하는 일과 결부되어 비교되곤 합니다. 커맨드 라인으로 도구를 설치하고 사용해야 하는 것 뿐만 아니라, 개별의 플러그인을 설치하고 더 복잡한 규칙의 집합(어떤 브라우저를 목표로 삼을지 등)을 정의 해야만 합니다. PostCSS를 커맨드 라인에서 직접 구동시키는 대신 많은 개발자들이 Grunt, Gulp와 같은 설정 가능한 빌드 시스템이나 webpack 에 통합시켜 사용합니다. webpack은 프론트엔드 워크플로우에서 사용 할 수 있는 모든 종류의 빌드 도구들을 도와주는 녀석입니다.

이건 알아두세요: 이전에 한번도 사용해 보지 않았다면, 현대의 프론트엔드 빌드 시스템 작업에 필요한 모든 부분을 배우는 것은 견디기 어려운 일입니다. 조금 쉽게 시작하고 싶다면, 제가 쓴 아티클인 Modern JavaScript Explained For Dinosaurs를 참고해 주세요. (역주: 해당 아티클은 마찬가지로 본 역자가 번역해 놨습니다. 구닥다리 공룡을 위한 오늘날의 JavaScript) 프론트엔드 개발자가 최신 기능을 활용하는 데 필요한 모든 JavaScript 도구화를 다룹니다.

CSS 포스트프로세서를 둘러싼 몇몇 논쟁들은 가치가 없습니다. 어떤 논쟁은 용어의 혼란스러움에 대해서 말다툼 합니다(여기서는 이 모든 것들을 CSS 프리프로세서라고 불러야 한다 주장하고, 저기서는 전부 간단히 CSS 프로세서라 불러야 한다고 주장하는 등 말입니다). 어떤 사람들은 CSS 포스트프로세서가 CSS 프리프로세서의 필요성을 없애버렸다고 믿고, 어떤 사람들은 이 두가지가 반드시 함께 쓰여야 한다고 믿습니다. 좌우지간, CSS 포스트프로세서의 사용법을 배우는 일은 가치있습니다. CSS로 할 수 있는 일의 한계를 뛰어 넘는 것에 관심이 있다면 말입니다.

c03.png

관리용이성을 위한 CSS 방법론 적용하기

CSS 프리프로세서나 CSS 포스트프로세서와 같은 도구는 CSS 개발 경험을 향상을 지향하고 있습니다. 그러나 이 도구들 만으로는 거대한 CSS 코드베이스 유지관리의 문제점을 해결하기엔 충분치 못합니다. 사람들은 이를 위해 CSS 어떻게 작성해야 하는지에 대한 가이드라인 문서를 만들기 시작했습니다. 이 문서들을 일반적으로 CSS 방법론(methodology)라 부릅니다.

개별적인 CSS 방법론에 빠져보기 전에 오랜 시간 동안 무엇이 CSS의 유지관리를 어렵게 했는지 알아보는게 좋겠습니다. 가장 중요한 문제점은 CSS의 전역적 환경입니다. 우리가 정의하는 모든 스타일은 전역적으로 적용 됩니다. 페이지의 모든 부분에 말이죠. 이 때문에 자세한 이름 짓기 규정으로 유일한 클래스 이름들을 유지하거나 어떤 스타일이 어느 주어진 요소에든 적용되도록 특이성 규칙을 갖고 언쟁을 벌여야 하는 것이 일이 되어버립니다. CSS 방법론들은 커다란 코드베이스 위에서 이와 같은 고통들을 피할 수 있도록 CSS를 작성하는 조직법을 제공합니다. 자 대충 연대기 순으로 인기있는 방법론 몇가지를 살펴보도록 합시다.

OOCSS

OOCSS (Object Oriented CSS)는 2009년 처음 선보인 방법론으로 두개의 큰 원칙 하에 구성되었습니다. 첫번째 원칙은 구조와 겉모습을 분리시킨다 입니다. 이것은 (레이아웃과 같은) 구조를 정의하는 CSS와 (색깔, 폰트 등) 겉모습을 정의하는 CSS를 뒤섞어 작성해서는 안된다는 것입니다. 이를 통해 어플리케이션에 겉모습을 다시 입히는 일이 쉬워집니다. 두번째 원칙은 컨테이너와 내용을 분리하자는 것입니다. 이것은 요소를 재사용 가능한 객체로 생각함을 의미합니다. 이 중심 아이디어로 객체가 페이지내 어디있던 상관 없이 똑같이 보이게 됩니다.

OOCSS는 잘 설명 된 가이드라인을 제공합니다. 그러나 세부적인 접근에 대해서는 그닥 올바른 관점을 제시하지 못합니다. SMACSS와 같은 후속의 접근법들이 이 핵심 컨셉을 차용하고 좀 더 자세한 사항을 추가하여 시작하기에 쉽도록 만들었습니다.

SMACSS

SMACSS (Scalable and Modular Architecture for CSS)는 2011년 소개된 방법론으로 5개의 구분된 카테고리로 CSS를 작성하라 말합니다. 5개의 카테고리는 베이스 규칙, 레이아웃 규칙, 모듈, 상태(state) 규칙, 테마 규칙을 말합니다. SMACSS 방법론은 또한 몇가지 명명법(naming convention)을 추천하고 있습니다. 레이아웃 규칙에 대해, 반드시 클래스 이름 앞에 꼭 l- 접두어를 붙이거나 layout- 접두어를 붙이라고 말합니다. 상태 규칙에 대해서는 상태를 기술하는 접두어를 클래스 이름이 붙이라고 말합니다. is-hidden이나 is-collapsed와 같이 말입니다.

SMACSS는 OOCSS와 비교해 그 접근법에 있어 많은 명세를 갖고 있습니다. 그러나 마찬가지로 어떤 CSS 규칙이 어떤 카테고리에 속하는지 결정하는데에 숙고를 요구합니다. 이 후에 등장한 BEM과 같은 접근법은 이 결정법중 몇가지를 차용했습니다. 더 쉽게 적용이 가능 하도록 말이죠.

BEM

BEM (Block, Element, Modifier)은 2010년에 사용자 인터페이스를 독립된 블록으로 나누는 아이디어를 중심으로 구성되는 방법론으로써 소개되었습니다. 블록(block)이란 재사용 가능한 컴포넌트를 말합니다(예로 검색 폼을 다음과 같이 정의 합니다. <form class="search-form"></form>). 요소(Element)는 블록 보다 작으며 블록의 부분이고 그것 자체로는 재사용 할 수 없습니다(예로 검색 폼 안에 있는 버튼을 다음과 같이 정의 합니다. <button class="search-form__button">Search</button>). 모디파이어(Modifier, 수식어)는 블록이나 요소의 겉모습, 상태, 행위등을 정의하는 엔티티(entity, 개체)를 말합니다(예로 사용불가 상태의 검색 폼 버튼을 다음과 같이 정의 합니다. <button class="search-form__button search-form__button--disabled">Search</button>).

BEM 방법론은 쉽게 이해하기 쉽습니다. BEM의 구체적인 명명법은 입문자들이 복잡한 결정 없이 적용할 수 있습니다. 그러나 몇몇 불안한 점이 있는데 클래스 이름이 상당히 지저분해 지고 시멘틱 클래스 이름 짓기의 전통적인 명명 규칙을 따르지 않는다는 것입니다. 이 다음의 접근법인 Atomic CSS 같은 것은 이러한 비 전통적인 방식을 완전히 다른 수준에서 차용 합니다.

Atomic CSS

(Functional CSS 라는 이름으로도 익숙한) Atomic CSS는 2014년에 도입되었으며 단일 목적을 갖는 작은 클래스를 시각적 기능을 바탕으로 한 이름을 붙여 만드다는 아이디어를 중심으로 구성된 방법론 입니다. 이 접근법은 OOCSS, SMACSS, BEM의 완전한 대척점에 있습니다-페이지 위의 요소를 재사용 가능한 객체로 다루는 대신 Atomic CSS는 이런 객체지향적 관점을 모두 무시하고 각 요소들을 스타일링하는 재사용 가능한 단일 목적의 유틸리티 클래스를 사용합니다. 따라서 <button class="search-form__button">Search</button> 이렇게 쓰는 대신, <button class="f6 br3 ph3 pv2 white bg-purple hover-bg-light-purple">Search</button> 이렇게 씁니다.

이 예시를 처음 보고 공포심에 흠칫 했다면, 네 여러분은 혼자가 아닙니다-많은 사람들이 이 방법론을 보고 기존 CSS 모범 사례에 대한 위반이라 여겼습니다. 그러나 여러 다른 시나리오에서 이 모범 사례라는 것이 유효한지에 대한 의문으로 다수의 훌륭한 토론이 있었습니다. 이 아티클에서 전통적인 관심사 분리는 (심지어는 BEM 방법론을 사용할 때에도) HTML에 의존적인 CSS를 만드는 반면, 아토믹(atomic) 또는 펑셔널(functional) 접근법은 CSS에 의존하는 HTML을 만듦을 잘 보여주고 있습니다. 양쪽 모두 틀린것은 아닙니다. 다만 이 면밀한 조사에서 CSS와 HTML의 진정한 관심사 분리는 영원히 달성될 수 없음을 보여줍니다.

CSS in JS와 같은 다른 CSS 방법론은 실제로 CSS와 HTML이 언제나 서로에게 의존적임을 받아들입니다. 가장 논란이 치열할 방법론들중 하나로 이끕니다.

CSS in JS

CSS in JS는 2014년 소개되었습니다. 이 방법론은 CSS 스타일을 별도의 스타일 시트에 정의하지 않고 개개의 컴포넌트에 직접 넣는 방식으로 구성됩니다. 이 방식은 React JavaScript 프레임웍을 위한 접근법으로 도입되었습니다(React는 이미 별도의 HTML 파일 대신 JavaScript에서 직접 HTML 컴포넌트를 구성하는 방식으로 논란이 되었습니다). (역주: 엄밀히 말하면 React는 프레임워크가 아니라 라이브러리입니다.) 원래 이 방법론은 인라인 스타일을 사용했었습니다. 그러나 이후의 구현에서 JavaScript로 (컴포넌트의 유일한 클래스 이름을 바탕으로 하는)CSS를 생성하고 이것을 문서의 스타일 태그에 넣는 방식을 취하게 되었습니다.

CSS in JS 방법론은 다시 한번 관심사 분리라는 CSS 모범 사례에 정면으로 부딪혔습니다. 웹을 사용하는 방식이 시간이 흐름에 따라 극적으로 바뀌어 왔기 때문입니다. 본디 웹은 대부분 정적인 웹 사이트로 이루어져 있었습니다-여기서 HTML 콘텐트를 CSS 표현으로부터 분리함이 큰 설득력을 가졌습니다. 요즘에는 웹이 동적 웹 어플리케이션을 만드는데 사용됩니다-여기서 재사용 가능한 컴포넌트로 분리하자는 말이 유의미해 집니다.

CSS in JS 방법론의 목표는 컴포넌트를 캡슐화 된 HTML/CSS/JS로 구성하여 견고한 경계로 감쌀 수 있도록 정의하는데에 있습니다. 이런 컴포넌트 내의 CSS는 다른 컴포넌트들에게 영향을 끼칠 수 없습니다. React는 견고한 경계의 컴포넌트를 밀어준 최초의 대중적인 프레임워크 중 하나이며 Angular, Ember, Vue.js와 같은 다른 주류 프레임워크 많은 영향을 끼쳤습니다. CSS in JS 방법론이 비교적 새로운 것이며, 웹 어플리케이션 컴포넌트의 시대에 개발자가 CSS에 대한 새로운 모법 사례를 확립하기 위하여 많은 실험이 이뤄지고 있음을 알아 두는게 중요합니다.


수많은 방법론에 압도당하기 쉽지만 완벽한 하나의 접근법은 존재하지 않다는걸 알아두세요-특정한 CSS 코드베이스의 복잡성을 타개하기 위해 취사 선택 할 수 있는 도구들로 여겨주시길 바랍니다. 작업에 있어 선호에 따라 숙고하여 옵션을 선택하는 일과 최근 이 업계에서 일어난 실험들이 모든 개발자들에게 장기적으로 도움이 될 것입니다!

결론

자 오늘날의 CSS를 간단히 살펴 보셨습니다. 우리는 CSS로 기초 스타일링 하기를 타이포그래피를 위한 프로퍼티들로 살펴봤습니다. CSS로 레이아웃 잡기를 float, flexbox, grid를 기반으로 접근해 봤구요. 변수나 mixin 같은 새로운 구문법을 위한 CSS 프리프로세서 사용하기를 해봤고, 벤더 프리픽스 추가하기같은 변형적인 기능을 위해 CSS 포스트프로세서 사용하기를 해봤습니다. CSS 스타일의 전역적인 성질을 극복하기 위해 관리용이성을 위한 CSS 방법론 적용하기도 해봤네요. 고급 셀렉터, 트랜지션, 애니메이션, 모양, 동적인 변수등-목록이 끝없이 올라가네요... 이러한 CSS가 제공해야만 하는 수많은 기능들을 아직 파헤쳐보지 못했습니다. CSS를 다루는 데에는 많은 바탕이 있습니다-누구든 이걸 쉽다고 말한다면, 그 사람은 말하는 것의 반도 모를게 뻔합니다.

근래의 CSS는 분명이 작업하기에 무섭습니다. 빠른 속도로 계속 변하고 진화하기 때문입니다. 하지만 시간이 흐름에 따라 어떻게 진화해 왔는지 역사적 맥락을 기억하는 것이 중요합니다. 견고한 도구와 방법론을 구축하여 웹에서 CSS 모범 사례가 진화하도록 돕고 싶어 하는 똑똑한 사람들이 있습니다. 개발자가 된다는 것은 즐거운 일입니다. 여러분의 여정에 이 아티클이 로드맵으로써 도움을 주길 희망합니다!

c04.png

@ryanqnorthDinosaur Comics에 특별한 감사를 전합니다. 2003년(공룡들이 web을 지배하던 그때)부터 부조리에 대한 훌륭한 풍자를 제공해 줬습니다.

Sort:  

제가 알고 있는 것은 중생대시절의 정보였군요 ㅋㅋ

#kr 태그를 달지 않으시면 한국어 사용자에게 글이 잘 노출되지 않습니다. 스팀잇에 익숙해지실 때까지 #kr-newbie 태그를 사용하시는 것을 추천드립니다. #kr 커뮤니티에서 사용하는 태그 목록은 @myfan 님의 태그 정리글에서 확인하실 수 있습니다.
이지스팀잇 가이드북 을 보시면 앞으로 스팀잇 활동하시는데 도움이 되실겁니다.

오... 감사합니다!

Congratulations @march23hare! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 1 year!

Click here to view your Board

Do not miss the last post from @steemitboard:

Valentine challenge - Love is in the air!

Support SteemitBoard's project! Vote for its witness and get one more award!

Congratulations @march23hare! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 2 years!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Do not miss the last post from @steemitboard:

Valentine's day challenge - Give a badge to your beloved!
Vote for @Steemitboard as a witness to get one more award and increased upvotes!

Coin Marketplace

STEEM 0.20
TRX 0.15
JST 0.030
BTC 65809.66
ETH 2680.91
USDT 1.00
SBD 2.95