Lambda
article thumbnail

웹 개발 작업에서 CSS를 통해 UI를 만드는 작업은 생각보다 까다로운 작업입니다. 분명 다른 작업에 비해 절대 난이도는 높지 않은거 같은데 생각보다 시간이 걸려 난처했던 경험은 프론트엔드 개발을 하시는 분들은 한번씩 있으실 겁니다. 

UI 개발은 결과물을 빨리 낼수록 디자인과 기획을 검증하는 시간을 줄일 수 있고 이는 곧 더 나은 제품을 만드는 결과로 이어지기에 CSS 개발의 생산성이 높아지는 방법에 대한 고민은 CSS의 첫 등장부터 현재까지 끊임없이 뜨거운 이슈로 다뤄지고 있습니다.

그 중 현재 CSS 프레임워크 중 가장 선두에 있으며 동시에 논란이 되고 있는 Tailwind CSS와 관련하여 향후 포스팅을 진행하기에 앞서 Tailwind CSS가 내세우는 Utility-First(본 포스팅에선 Atomic CSS로 다루겠습니다)에 대해 다루고 싶었습니다. 하지만 Atomic CSS는 현대에 와서 갑자기 등장한 패러다임이 아닙니다. Atomic CSS는 사실 오래전부터 있었지만 최근에 와서야 다시 재발견된 패러다임입니다.

 

오늘은 Atomic CSS가 '왜' 지금에 와서 채택이 되게 되었는지에 대해 CSS의 역사을 살펴보며 알아보겠습니다. 본 포스팅은 제가 CSS의 역사를 정리하는데 많이 도움을 받았던 테오님의 포스팅을 바탕으로 작성되었습니다. 전반적인 이야기의 흐름은 원문의 형태를 유지하되, 최대한 이해하기 쉬운 방식으로 전달하고자 노력하였습니다. 테오님이 본인의 포스팅의 소개글에 적어놓으신 것처럼 이 글이 현대 CSS에 대한 이해를 높이고 CSS 생산성을 높일 수 있는 방법에 대한 하나의 인사이트가 될 수 있기를 바랍니다.

 

CSS가 어려워진 이유

웹은 문서를 공유하기 위해서 만들어졌습니다. 그리고 그 문서를 조금 더 잘 보여주기 위해서 서식이 만들어졌습니다. 이러한 서식과 데이터가 복잡하게 공존하게 되면서 서식과 컨텐츠를 분리해야겠다는 의도에서 CSS가 탄생하게 되었습니다.

초기에는 문서와 서식을 잘 분리해서 보다 적은양의 코드를 통해서 같은 컨텐츠를 다양한 서식을 적용할 수 있도록 발전을 하였습니다. 그러나 웹 산업이 급격히 발전을 하게 되면서 웹은 단순히 문서의 역할을 너머 서비스와 어플리케이션의 형태로 발전을 하게 되었습니다.

문서에서 어플리케이션까지 웹 서비스의 범위가 확장이 됨에 따라 CSS에도 여러가지 요구사항들이 생겨났고 그에 맞는 여러 가지 좋은 스펙들이 발명이 되었습니다. 또한 그 과정에서 여러가지 시행착오를 겪기도 했었습니다. 특히 문서을 만들기 위해서 시작된 설계를 바탕으로 이후 어플리케이션을 위한 추가 방안을 마련하는 과정이 더욱 그랬습니다. 이렇게 이미 한번 만들어진 스펙은 되돌릴수가 없기에 좋았던 부분과 그렇지 못한 부분들을 우리는 함께 사용하고 있습니다.

또한 당시에는 시대에 맞게 의도대로 설계를 했지만 웹 산업이 급격하게 발전을 하면서 생겨난 새로운 요구사항을 이미 만들어진 스펙이나 설계가 못 따라오는 시기가 존재했고, 그 안에서 어떻게든 방법을 찾다 보니 의도와는 다른 방식으로 CSS 스펙을 차용해서 화면을 만들게 되었습니다.

안타깝게도 최초 문서를 위해 설계된 방법들은 여전히 어플리케이션을 제작하기 위한 개념과는 충돌하는 부분이 존재 하고 있습니다. 이러한 부분들은 현대 산업에서 큰 규모의 CSS를 이용한 프로젝트가 안정적으로 유지되기 어렵게 만드는 원인이 되고 있습니다. 

무조건 최신을 따르자니 새로운 스펙이 모든 브라우저에 보편적으로 적용이 되기까지에는 시간이 필요합니다. 하지만 특정 브라우저에는 제대로 보이지 않을 수도 있기에 무조건 새로운 스펙을 바로 도입할수도 없습니다. 그러니 기존의 방식 역시 알고는 있어야 하는 상황이 발생하게 됩니다.

당장의 최신 기술을 쓸 수 없고, 그렇다고 안정성만 추구해 계속 현재의 방법만 고수를 한다면 변화하는 웹 생태계에 따라가지 못한채 낡은 코드와 낡은 패러다임으로 인해 우리의 코드는 레거시가 되게 됩니다.

언제나 최신 기술을 바로 사용할 수 있는 것은 아닙니다.

그러기에 언제 새로운 스펙으로 갈아탈지, 어떤 기능이 나왔는지, 어떠한 관점과 기술들이 나왔는지 우리는 꾸준히 관찰을 하고 학습을 하여 적당한 시기에 더 나은 방법으로 꾸준히 업데이트를 해나가야만 합니다.

 

그러기 위해서 먼저 CSS 역사를 배워보자 !

어느 분야든 역사를 공부한다는 것은 지금 이것이 왜 이렇게 만들어져있으며 앞으로는 어떻게 될지 방향성을 예측해 볼 수 있는 좋은 공부가 됩니다. 특히 CSS의 경우 웹 문서로 출발해 홈페이지, 게시판 그리고 현재 웹 어플리케이션으로 넘어가는 과정에서 당시에는 CSS 스펙이 지원하지 않아서 만들어졌던 방법들이나 패러다임의 전환등이 많았기에 CSS를 지금 처음 배우는 사람들 입장에서는 혼란이 생길 수 있는 부분이 있습니다.

CSS뿐만 아니라 모든 변화는 필요에 의해 생깁니다. 그리고 그러한 필요는 그때 당시의 상황을 반영하게 됩니다. CSS의 역사를 이해함으로써 앞으로 CSS 관련 글들을 읽었을때 어떠한 갈래와 패러다임에 해당하는 내용인지 알 수 있는 넓은 시야가 생기는데 도움이 되었으면 좋겠습니다. 또한 앞으로 새로운 스펙이나 도구 기술등이 나왔을 때에도 어떠한 맥락에서 이게 만들어졌는지 이해할 수 있는 단초가 되어 줄거라 생각합니다.

CSS의 역사, styled-components와 Tailwind와 같은 익숙한 얼굴도 보인다.

 

문서를 공유하기 위해서 HTML이 만들어지다, 1990

웹은 HyperText라는 문서를 공유하기 위해서 만들어졌습니다. 그리고 이 문서를 만들기위해 HTML이라는 언어가 만들어졌습니다. HTML을 통해 미리 정의된 태그를 적절히 문서에 마크를 함으로써 적절한 서식이 입혀진 문서를 만들 수 있게 되었습니다.

이후 조금 더 커스텀한 서식을 입히고 싶은 요구로 인해 HTML에는 서식을 입힐 수 있는 기능이 만들어지게 됩니다.

가령, 내가 강조하는 서식에 빨간색과 밑줄을 추가로 넣고 싶은 경우에는 아래와 같은 방식으로 스타일에 빨간색과 밑줄을 추가할 수 있습니다.

<p>안녕! <strong style="color:red; text-decoration:underline">여기를 빨간색과 밑줄표기로 강조</strong>하고 싶어</p>

이렇게 태그에 직접 스타일을 입력하는 방식을 inline-style이라고 부릅니다.

 

inline-style의 문제점

이렇게 inline-style을 사용하게 되면 원하는 스타일로 커스텀하여 사용 할 수 있겠지만, 작성했던 모든 strong 태그를 찾아서 빨간색과 밑줄 관련 코드를 추가해야합니다.

그래서 아래와 같이 같은 코드를 매번 반복해서 작성을 해야하는 복잡한 문서가 만들어지게 됩니다.

<p>이 문장에서 <strong style="color:red; text-decoration:underline">중요한 부분</strong>입니다.</p>
...
<p>안녕! <strong style="color:red; text-decoration:underline">여기를 빨간색으로 강조</strong>하고 싶어</p>
...
<p>새로운 문장에서도 여전히 <strong style="color:red; text-decoration:underline">중요한 부분은</strong>존재합니다.</p>

그런데 여기서 빨간색이 마음에 들지 않아서 파란색으로 바꾸고 싶다면 어떻게 해야 할까요?

이미 다 만들어 놓은 서식에서 색깔 부분만 찾아내 빨간색을 파란색으로 일일이 다 바꿔야 할 것입니다. 찾아 바꾸기를 한다고 해도 글자색이 아닌 다른 색을 수정할 수도 있고, 실수로 본문에 있는 글자가 바뀔 수도 있는 문제가 발생을 합니다.

 

CSS가 만들어지다, 1996

그래서 HTML에서 스타일만 분리해내어 작성하여 반복적인 부분을 일괄적으로 적용을 해주는 방법을 생각해내게 됩니다.

inline-style이 기록된 부분들을 하나로 묶어 별도의 스타일을 선언(declarations) 해두고,HTML에서 원하는 태그를 찾아서 선택(selector) 하여 스타일을 적용하는 언어인 CSS를 만들게 되었습니다.

선택자(selector) 와 선언(declarations) 이 둘을 합쳐 CSS Ruleset이라고 부릅니다.
<p>이 문장에서 <strong>중요한 부분</strong>입니다.</p>
...
<p>안녕! <strong>여기를 빨간색으로 강조</strong>하고 싶어</p>
...
<p>새로운 문장에서도 여전히 <strong>중요한 부분은</strong>존재합니다.</p>
<style>
	strong { color: red; text-decoration:underline }
</style>

이렇듯 CSS는 반복해서 입력을 해야 했던 귀찮은 행동들을 대신 해주는 일종의 매크로와 같은 역할을 수행합니다.

 

😇 Cascade와 Specificity - 희망편 😇 

앞서 설명드린 매크로와 같이 CSS는 여러 개의 서식을 일괄적으로 적용을 방식을 사용하다 보니 CSS의 Ruleset의 적용 대상과 서식이 겹칠 경우에는 어떤 서식을 더 우선을 해야할지 규칙이 필요했습니다.

이러한 규칙을 CSS는 Cascade라는 특징을 가지고 만들어졌습니다. Cascade란 서식을 겹겹이 덧칠해 나가되 단순한 걸 먼저 구체적인 것은 나중에 라는 방법입니다. 반복적인 작업을 줄이기 위해서 기초가 되는 서식을 먼저 전체에 적용을 하고 점점 더 구체적인 서식들을 적용을 해 나가는 식으로 만들면 좋을 거라고 생각을 했습니다.

그래서 CSS는 작성된 순서가 아니라 CSS Rule이 가지고 있는 고유의 명시도(Specificity)에 따라서 우선순위가 다르게 적용을 할 수 있도록 설계가 되었습니다.

그리고 이 방법은 코드의 순서를 강제하지 않고 응집력이 높도록 코드를 작성할 수 있도록 도와줄 거라고 생각했습니다.

/* 아래 4가지 코드는 순서가 변해도 동일한 결과를 나타낸다 */
h1 { font-size: 2em; color: #000; font-family: Georgia}
.small { font-size: 1em }
[href] { color: red; }
#id { color: #ccc; }

/* 순서가 변경이 되어도 위 코드와 결과가 같다. */
#id { color: #ccc; }
.small { font-size: 1em }
h1 { font-size: 2em; color: #000; font-family: Georgia}
[href] { color: red; }

 

🔥 Cascade와 Specificity - 절망편 🔥

Specificity War !

하지만 Rule마다 고유한 명시도(Specificity)가 있다는 결정은 결과적으로 아주 좋지못한 설계가 되었습니다.

우리는 이 설계로 인해 기존의 CSS를 덮어쓰기 위해서 더 복잡한 Selector를 써야 하고, 복잡한 Selector를 덮어 쓰기 위해서는 더 더 복잡한 Selector를 써야 하고 !important와 같은 우선순위를 변경하는 코드를 남발하도록 만들었습니다.

추후 설명할 CSS의 방법론이나 CSS in JS, Atomic CSS와 같은 기술들은 이러한 한계를 극복하기 위해서 만들어졌다고 생각합니다.

 

게시판과 같은 웹서비스가 보편화

이후 웹 산업은 단순히 문서를 데이터를 교환하는 Form이 중심이 되면서 우리가 알고 있는 게시판이나 쇼핑몰과 같은 데이터를 주고받고 저장을 하는 매체로 성장을 하게 됩니다.

그래서 단순히 정적으로 서식과 함께 생성하던 문서에서 데이터들이 결합하여 동적으로 생성을 해야 하다보니 HTML를 작성하는 주체는 백엔드 개발자였습니다.

그러면서 게시판, 포럼, 장바구니, 로그인과 같은 기능이 필요한 페이지들은 백엔드를 중심으로 하는 솔루션의 형태로 발전하게 됩니다. 이러한 이유로 솔루션의 HTML을 CSS를 이용해서 디자인 하되, HTML을 건들지 않고 CSS만으로 디자인을 할 수 있는 방법이 중요해지게 됩니다.

 

CSS Zen Garden의 열풍, 2003

이러한 시멘틱한 HTML를 이용해서 하나의 컨텐츠에서 여러가지 CSS의 서식을 입힐 수 있도록 작성하는 것은 HTML5와 CSS3를 제대로 사용하는 하나의 기준이 되었고 이를 제대로 보여주는 사이트인 CSS Zen Garden이 등장하였습니다.

CSS Zen Garden은 시멘틱한 원본 HTML이 존재하고 디자이너가 CSS만으로 전혀 다른 스타일을 적용할 수 있다는 것을 보여줍니다.

 

같은 컨텐츠로 전혀 다른 디자인을 만들 수 있다 !

이러한 컨셉을 바탕으로 추후 CSS를 커스텀 할 수 있는 블로그나 워드 프레스와 같은 CMS 서비스들이 인기를 끌게 됩니다.

이때까지는 HTML을 먼저 만들고 CSS를 나중에 디자인을 커스텀할 수 있도록 하는 방법이 유효했지만 점점 하나의 웹페이지가 거대해지면서 하나의 컨텐츠를 여러 디자인으로 커스텀 하는 방식보다는 하나의 디자인과 컴포넌트를 중심으로 서비스를 키워나가는 형식으로 발전을 하게 됩니다.

그렇지만 CSS Style을 override하여 커스텀한 테마를 이용하여 홈페이지를 만드는 워드프레스와 같은 방식은 당연히 유효하며 실제로도 웹 페이지의 대다수를 차지하고 있습니다. 이것이 CSS를 어렵게 만드는 이유이기도 합니다.

시멘틱 패러다임은 HTML과 CSS의 학습의 교과서와 같은 항목이자 현재 가장 많이 쓰이고 있으면서도 최신 프론트엔드 개발 서비스와는 맞지 않는 부분이 있습니다. 어떠한 부분이 필요하고 어떠한 부분이 이제는 필요없는 지를 잘 구분 할 수 있어야 합니다.

 

Selector가 점점 더 복잡해진다..

HTML을 수정할 수 없으나 원하는 디자인을 만들기 위해서는 조금 더 정교하고 고도화된 Selector가 필요하게 됩니다. 그래서 CSS는 점점 더 Selector가 복잡해지는 방향으로 발전을 하게 됩니다.

하지만 이렇게 Selector가 복잡해지면 Specificity가 높아지게 되고 새로운 스타일을 그 뒤에 덮기 위해서는 더 높은 Specificity의 Selector가 필요하고 그러지 못할 경우에는 !important를 사용하게 되는 부작용이 있어 CSS가 어렵고 복잡해지는 원인으로 작용했습니다.

 

Sass의 등장, 2006

Selector를 복잡하게 사용해야 하고 CSS에서 반복해서 사용하는 글자 크기가 색상들을 작성을 하고 나서 수정이 용이하지 않다는 점을 해결하고 CSS를 확장하여 사용하고자 하는 시도가 만들어집니다.

Nested한 Selector와 variable를 등록할 수 있는 추가적인 문법으로 작성하면 CSS로 변환을 시켜주는 pre-processor인 Sass가 만들어집니다.

 

이후 2009년 less, 2010년 stylus와 같은 새로운 pre-processor들을 만들어지게 되었으나 sass가 계속 점유율 1위를 이어갔습니다.

Pre-processor는 CSS를 로직이 있는 언어로 접근하고 재사용을 하기 위한 방법을 모색했다는 데에 의미가 있습니다. 물론 CSS는 구조상 재사용이 거의 힘들기 때문에 실제로는 재사용을 거의 하지 못했습니다. 이후 Atomic CSS라는 방식을 통해서야 CSS를 재사용하기 위한 방법들이 발견되게 됩니다.

 

HTML5과 CSS3, 시멘틱이 중요해지다

하나의 변하지 않는 컨텐츠와 다양한 변경가능한 디자인이라는 컨셉을 통해 HTML과 CSS에는 시멘틱이라는 것이 중요해졌습니다.

시멘틱이란 시각적으로 어떻게 보일지가 아니라 의미에 중점을 두는 것입니다. HTML이 어떻게 보여질지는 HTML이 결정하는 것이 아니라 CSS에 의해 커스텀될 수 있어야 재사용성이 커지기 때문입니다.

 

뭐가 더 시멘틱할까 ?

이해를 돕기 위해 예시를 들어보겠습니다.

<div class="error">에러 메시지</div>
<div class="red">에러 메시지<div>
<div class="#ff0">에러 메시지</div>
<style>
	.error { color: #f00 }
	.red { color: #f00 }
	.\\#ff0 { color: #f00 }
</style>

여기에 동일한 서식을 가지는 .error.red.#f00 3가지 클래스 이름이 있습니다.

모두 빨간색으로 표기하는 서식이기에 결과는 같습니다.

이 중 어느 이름이 더 시멘틱 한걸까요 ? 아마 대부분 .error라는 이름이 더 시멘틱하다는 의견에 동의할 겁니다.

 

시멘틱해야 하는 이유

위와 같은 상황에서 에러 메시지의 색깔을 오렌지색으로 바꿔야 하는 요구사항이 생겼습니다.

이 경우 CSS를 어떻게 바꾸면 될까요? (단, HTML을 수정할 수가 없습니다.)

<div class="error">에러 메시지</div>
<div class="red">에러 메시지<div>
<div class="#ff0">에러 메시지</div>
<style>
	.error { color: #f90 }
	.red { color: #f90 }
	.\\#ff0 { color: #f90 }
</style>

.error { color: #f90 } 은 전혀 문제가 없어보입니다. 에러색이 오렌지색으로 변했으니까요.

.red는 어떨까요? 내가 아는 빨간색은 이제 아니게 되었지만 그쪽 계열(?)이라고 우겨볼수는 있으려나요? 파란색으로 바꿔달라고 하면 어떡하죠?

.#ff0은 이제 명백히 잘못된 디자인을 표기하게 될 겁니다.

이처럼 HTML을 수정할 수가 없다면 class의 이름이 시각적인 내용이기보다 의미를 나타내어야 디자인을 커스텀할 수 있는 영역이 다양해집니다.

 

jQuery, Ajax의 보편화, 2008

프론트엔드 개발에서 Ajax라는 혁신과 jQuery의 등장으로 인해 백엔드에선 HTML이 아니라 JSON을 만들게 되었습니다.

이제는 HTML이 백엔드에 있는게 아니기 때문에 HTML과 CSS를 함께 작성을 하고 데이터를 연동해서 출력하는 작업을 JS로 하는 방식으로 개발을 하게 됩니다. 사실상 현재의 프론트엔드 탄생의 순간입니다.

이때부터는 HTML와 CSS를 작업하는 주체가 백엔드에서 점점 프론트엔드로 옮겨지기 시작하면서 복잡한 Selector를 사용해야할 빈도가 줄어들기 시작했습니다.

HTML의 편집권이 프론트엔드로 서서히 옮겨오기 시작하면서 Selector를 복잡하게 만들기 보다는 HTML에 class를 추가하는 등의 HTML 수정을 통하여 단순한 Selector를 만드는 방식으로 발전을 하게 되었습니다.

 

웹 어플리케이션과 Framework, 2013

페이스북의 성장으로 인해 웹 어플리케이션이라는 영역이 확대되고 React를 비롯한 Web Framework가 만들어지면서(React는 라이브러리지만요) HTML를 작성하는 주체는 온전히 프론트엔드의 영역이 되기 시작하였습니다. 그러면서 페이지 단위의 문서 기반이 아니라 컴포넌트 기반의 개발 방식이 자리를 잡게 됩니다.

이렇게 JS의 개념이 발전하게 되면서 프론트엔드는 계속 발전하게 되었지만, CSS는 변화의 속도를 따라오지 못하게 됩니다.

문제의 비극은 여기서 출발을 하였습니다..

 

문서를 꾸미려고 만들었지, 앱을 꾸미려고 만든건 아니었어...

이미 웹 산업은 홈페이지를 넘어 웹 애플리케이션의 세상으로 넘어왔지만 CSS는 예전의 문서를 꾸미기 위한 스펙을 가지고 있었습니다. 그러다보니 문서를 꾸미기 위한 방법들로 애플리케이션을 만들게 되었습니다. 그러라고 만든 스펙이 아니다보니 온갖 방법을 동원해서 엘리먼트를 가운데 정렬을 하고자 합니다.

 

당시에는 '엘리멘트는 가운데 정렬하는 7가지 방법' 과 같은 컨텐츠들이 중요한 토픽이었습니다. 이는 현재까지도 meme으로 쓰입니다.

이러한 문제로 인해서 문서를 편하게 꾸미를 수 있도록 설계된 CSS는 어플리케이션스러운 UI와 컴포넌트 방식의 개발과는 맞지 않는 설계가 되어버렸습니다.

 

모듈과 컴포넌트 방식으로 개발

CSS의 가장 큰 문제점은 CSS가 global scope를 가지고 있다는 점과 Cascade의 Specificity입니다.

모든 문서에 일괄적으로 적용되기 위해서 만들어졌던 기능은 다른 컴포넌트 영역의 스타일을 수정할수도 있다는 문제가 되었습니다.

HTML을 만들고 CSS를 만들어 두면 이미 만들어진 CSS가 새로운 컴포넌트를 만들기 위한 제약사항이 되어버립니다. 새로운 HTML과 CSS를 만들기 위해서는 기존에 만든 CSS를 피해서 작성 해야 했습니다. 때로는 반대로 기존에 만들어진 CSS를 새롭게 덮어써야만 했습니다.

CSS의 Specificity관리와 모듈화가 중요해졌지만 CSS의 스펙은 변경할수가 없었기에 어떻게 하면 CSS를 잘 작성할 수 있을지에 대한 체계적인 방법론과 규칙이 논의되기 시작하였습니다.

 

CSS 방법론와 BEM, 2013

OOCSS, ITCSS, SMACSS 여러가지 방법론이 존재했지만 현재 방법론의 승자는 BEM이 되었습니다.

그래서 selector는 class방식으로만 작성하고, 네이밍 규칙은 BEM 방식으로 하는 것이 주류가 되었습니다.

BEM을 처음 들어볼 순 있지만 BEM으로 CSS를 작성해본 적이 없는 프론트 개발자는 없다 !

간단한 이름짓기 컨벤션을 통해서 협업할 때 같은 방식으로 이름을 작성할 수 있게 하면서 구조를 표현하고 Specificity를 하나로만 관리할 수 있게 해서 기존의 문제점을 해결하고자 하는 방식입니다.

처음에는 HTML이 복잡해지고 class이름이 너무 길다는 이유로 사람들에게 받아들여지지 않았지만, 결국엔 간결하고 직관적이며 배우기 쉬운 BEM이 대세가 되었습니다.

<div class="header">
	<div class="nav"></div>
</div>
<div class="nav"></div>
<style>
	.header .nav { (X) }
<!-- 
이렇게 하면
1. nav가 header 구조에 종속이 되어 nav위치에 따라 디자인이 제대로 나타나지 않을 수 있다.
2. Specificity가 올라가게된다.
-->
</style>

 

<div class="header">
	<div class="header__nav"></div>
</div>
<div class="header__nav"></div>
<style>
	.header__nav { (O) } 
<!-- 
이렇게 하면
1. 구조도 표현하면서 종속 관계가 없다.
2. Specificity가 하나로 관리된다.
-->
</style>

BEM이 가지는 장점을 정리하면 다음과 같습니다.

  1. 구조도 표현하면서도 종속 관계가 없다.
  2. Specificity가 하나로 관리된다.
  3. 그러면서 컨벤션이 단순해서 쉽게 기억할 수 있다.

 

Flexbox의 등장, 2013

 

아직까지도 사랑받는 Flexbox의 등장 !

웹 문서가 아니라 웹 애플리케이션으로 발전을 하는 과정에서 레이아웃를 하기 위한 CSS 스펙에 대한 요구사항은 꾸준히 있어왔습니다. 2008년부터 만들기 시작했던 레이아웃을 하기 위한 스펙은 여러번의 시행착오 끝에 드디어 2013년 정식 스펙으로 등장하게 됩니다.

Flexbox가 나오기 전까지 🔥 float나 table, absolute와 margin등을 이용해서 억지로 레이아웃을 만들던 방법들이 존재했고 이러한 방법들은 대체가능한 방법이 없었기에 여러가지 Tip과 같은 방법들로 방법이 공유되고 문서화되었습니다.

출시 당시에는 IE10이하 브라우저나 크롬, 사파리의 경우에도 이전 버전에서는 바로 호환되지 않았기에 당장에는 쓸 수가 없다보니 IE가 없는 모바일에서만 사용하고 크로스브라우징을 하는 등의 과도기가 있었지만, Flexbox는 이제는 웹 레이아웃을 하기 위해서는 제일 먼저 알아야 하는 가장 중요한 스펙이 되었습니다.

Flexbox는 문서를 위한 CSS와 어플리케이션 레이아웃을 하기 위한 방식이 분리되어 CSS 스펙으로 웹 애플리케이션 레이아웃을 할 수 있는 토대를 만들어 주었습니다.

🎯 2022년, Flexbox는 이제 웹의 모든 레이아웃의 표준입니다. float, margin, table, inline-block 등 옛날 방식으로 뭔가 정렬을 하는 방식들은 이제 배우지 않으셔도 되고 헷갈려 하지도 마시기 바라며 CSS를 한다면 Flexbox만큼은 꼭 학습하시는 것이 좋습니다.

 

Handoff툴의 등장! Zeplin, 2014

 

기존에는 디자이너가 퍼블리싱까지 포함을 해서 웹 디자이너라는 직군으로 일을 했다면 본격적으로 제플린이라는 핸드오프툴이 등장하면서 이쪽 씬의 판도가 변하게 되었습니다.

제플린은 기존에 디자이너가 사용하던 도구의 내용들을 통해 그동안 웹 디자인을 하기 필요한 스타일가이드나 요소 간의 간격, 배치에 대해서 이제는 툴에서 알아서 문서화와 소통 그리고 아카이브까지 해줌으로써 본격적으로 디자이너와 프론트엔드 개발자의 영역이 분리가 되어 각자의 영역에서 전문가가 될 수 있게 되었습니다.

이러한 핸드오프가 등장을 하고 나서부터는 CSS로 디자인을 잘하는 능력보다는 디자이너가 만들어 준 디자인을 Flexbox 등으로 적절한 구조를 만들고, 나아가 컴포넌트의 구조를 잘 만들어내는 능력이 더욱 중요해지게 되었습니다.

제플린과 같은 Handoff툴의 등장의미는 기존의 디자이너가 퍼블리싱을 함께 하던 구조에서 보다 디자인에 집중을 하고, 기존 퍼블리셔의 역할을 개발자가 대부분 가지고 와야 한다는 것을 의미합니다.

 

CSS 수고했어... 이제는 JS가 해결해볼게! CSS Modules, 2015

CSS의 Global Scope로 인해서 컴포넌트와 CSS간의 구조와 범위가 일치하지 않는 문제를 JS를 통해서 해결하고자 하는 움직임이 생겼습니다.

그 중 첫번째 도구인 CSS Modules는 컴포넌트에서 CSS를 불러와서 컴포넌트에서만 적용이 될 수 있도록 컴파일을 해주는 도구였습니다.

 

CSS Modules를 사용하면 이름이 해쉬값으로 부여됩니다 -> 시멘틱은 ..?

CSS Modules를 통해서 CSS의 가장 고질적인 문제인 Global Scope에 대한 해결이 이루어졌습니다. 이를 통해 CSS는 태생적인 문제를 극복을 할 수 있게 되었고 이후 본격적으로 JS와 CSS를 결합하고자 하는 시도가 이어졌습니다. 사실상 CSS Modules등을 쓴다면 기존의 BEM과 같은 방법론이 그렇게 필요하게 없게 되기도 하였습니다.

 

CSS in JS: Styled-Component, 2016

CSS는 다음과 같은 구조적인 문제를 지니고 있습니다.

 

위의 내용을 구체적으로 정리하면 다음과 같습니다. 

1. Global namespace: 모든 스타일이 global에 선언되어 중복되지 않는 class 이름을 적용해야 하는 문제

2. Dependencies: css와 JS간의 의존관계를 관리하기 힘든 문제

3. Dead Code Elimination: 기능 추가, 변경, 삭제 과정에서 불필요한 CSS를 제거하기 어려운 문제

4. Minification: 클래스 이름의 최소화 문제

5. Sharing Constants: JS 코드와 상태 값을 공유할 수 없는 문제

6. Non-deterministic Resolution: CSS 로드 순서에 따라 스타일 우선 순위가 달라지는 문제

7. Breaking Isolation: CSS의 외부 수정을 관리하기 어려운 문제(캡슐화)

특히 CSS의 Global Scope와 Specificity문제는 CSS의 구조상 해결을 할 수 없는 문제였습니다.

 

그렇다면 CSS를 JS를 통해서 만들게 되면 이러한 문제를 해결한 새로운 CSS를 만들어낼수 있지 않을까요 ? 

이러한 아이디어를 바탕으로 CSS in JS가 탄생하였습니다.

CSS-in-JS의 선두주자 styled-components

 

이러한 방식을 통해서 Specificity문제의 원흉인 Selector는 사라지게 되고 Property와 Value를 컴포넌트 구조에 맞게 작성을 하면 되게 되었습니다.

 

지금까지의 CSS는 틀렸다. Tailwind CSS, 2017

 

JS가 아닌 CSS 생태계에서 이를 해결하고자 새로운 패러다임을 얘기하는 CSS프레임워크가 나타났습니다. 그것은 Utiliy-First라고 불리는 방식의 Tailwind CSS 였습니다.

사실 Tailwind CSS는 새로운 개념은 아니었습니다. HTML과 CSS가 만들어졌을 초창기 부터 class에 유틸리한 이름을 붙여 개발하는 방식은 개발자들 사이에서 암암리에 행해지는 방식이었습니다.

하지만 시멘틱한 방식이 중요한 패러다임이 되면서 이러한 방식은 일종의 꼼수, 옳지 않은 방식으로 여겨졌기에 가급적 이렇게 쓰지 말라고 하는 안티 패턴이었습니다.

하지만 Tailwind CSS는 이러한 방식을 오히려 전면적으로 사용 하는 것을 권장하며 패러다임 쉬프트에 성공하였습니다. 당연히 이러한 방식은 당시에는 받아들이기 아주 힘든 패러다임이었습니다. 그래서 Tailwind의 경우에는 초반에 반대 의견이 굉장히 많았습니다.

Tailwind CSS가 받아들여지는데에는 예전과는 다른 다음과 같은 변화가 있었기에 가능했습니다.

  1. 웹 개발은 이제 대부분 솔루션 방식이 아니기 때문에 프론트가 직접 HTML과 CSS를 수정합니다.
  2. CSS로 개발하는 것보다 HTML을 다루는게 더 편하며 사이드 이펙트 또한 더 적습니다.
  3. 대부분 서비스들이 하나의 디자인 시스템을 가집니다.

Atomic한 CSS는 모두 같은 Specificity한 class로 구성이 되었으며 개발을 할때에도 새롭게 CSS를 작성하지 않아도 되기 때문에 추가적인 CSS의 관리가 필요하지 않다는 장점이 있습니다.

무엇보다 이름을 짓기 위한 고민을 하지 않아도 되며, 이미 만들어진 CSS는 서비스가 커지더라도 CSS의 양이 변화가 없기 때문에 대형 서비스 일 수록 CSS의 크기를 줄이는 이점이 존재합니다.

워드프레스와 같이 HTML이 미리 고정이 되어있고 테마를 제공해야하는 솔루션에서는 절대로 쓸 수 없는 기술이다보니 초창기 많은 사람들에게 좋지 않은 방식이라고 부정당했으나, 지금은 당당히 CSS의 구조적인 문제를 다룰수 있는 방법으로 인정을 받고 가장 인기 있는 프레임워크가 되었습니다.

 

CSS Variables의 등장, 2017

Sass나 Less와 같은 PreProcessor의 등장이유기도 했던 CSS에 변수를 쓸 수 있는 기능이 IE11를 제외하고는 모든 브라우저에서 사용을 할 수 있게 되었습니다.

IE11지원을 포기하고 새로운 CSS의 세상을 살기로 마음먹은 서비스들은 이제 더이상 Sass를 써야 할 이유가 사라졌습니다.

복잡한 Selector는 CSS 구조상 이제 필요가 없어졌고, CSS Variable은 이제 CSS의 기본 기능이 되었습니다. autoPrefixer의 경우는 PostCSS가 대신할 수 있게 되었고 mixin과 같은 기능들은 CSS in JS에서 더욱 잘 지원을 할 수 있게 되었습니다.

 

GridLayout의 등장, 2017

구상은 Flexbox보다도 훨씬 전에 논의가 되었지만 여러가지 버전을 거쳐서 2017년 드디어 Grid Layout이 등장하였습니다.

하지만 IE의 시간은 2015년도에 머물러 있었기에 새롭게 만들어진 Grid Layout스펙과 IE에서 사용가능한 Grid Layout의 경우 미묘하게 스펙이 달랐고, 이러한 이유로 GridLayout은 흥행을 실패하였습니다. 사람들은 IE11에서 골치아프게 크로스브라우징을 해야하는 GridLayout에 비해 Flexbox로 충분히 대부분의 레이아웃을 작업할 수 있었기에 Grid Layout은 실험적인 기능에 그치게 되었습니다.

 

IE11안녕~ 함께해서 더러웠고 다신 만나지 말자, 2020

MS에서 공식적으로 IE11의 지원종료를 발표하였습니다. 사람들은 이제 확실하게 IE11을 지원하지 않아도 된다는 사실을 통해서 그동안 2015년에 묶여있었던 5년치의 CSS를 한꺼번에 배워야했습니다.

이제는 새로운 CSS의 스펙을 곧 마음대로 쓸 수 있게 되었습니다. 흥행에 실패했던 GridLayout의 사용점유율도 10%에서 50%로 올라왔습니다.

아직 사용할 수 없는 수많은 스펙들이 새로 만들어지고 있습니다. 이제는 새롭게 지원해줄 스펙을 통해서 CSS를 더 좋게 만들 수 있는 방법들을 고민해볼 차례입니다.

 

Figma, sketch를 누르고 디자인툴 1위가 되다, 2020

디자인 툴에 대한 지각변동이 발생하게 됩니다. Figma가 1위가 된것은 아주 중요한 사건입니다. Figma는 디자이너뿐만 아니라 개발자와의 협업을 하기 위한 실시간 클라우드와 Zeplin과 같은 Handoff 기능을 함께 겸하고 있습니다.

Figma는 AutoLayout과 같은 개발자 관점에서의 도구를 가지고 있습니다. Figma가 점유율 1위를 차지하게 되면서 디자이너들이 대부분 선택하는 도구가 되었고, Zeplin대신 figma를 통해서 HandOff 및 디자인 리소스를 작업해야 하게 되었습니다.

 

CSS in JS의 대유행, 2021

Styled-Component의 흥행과 React의 압도적인 점유율로 인해 CSS in JS는 새로운 강자를 찾는 중입니다. 런타임에 CSS를 생성한다는 문제점을 극복하기 위해서 Zero-Time CSS, Near Zero CSS와 같은 컨셉을 들고 나오는 중입니다.

 

2021년 기준 새로운 기술들은 대부분 CSS in JS에 몰려 있습니다.

아직까지 절대적인 강자는 Styled-Component가 자리를 지키고 있지만 어떠한 라이브러리가 최종승자가 될지는 좀 더 지켜봐야 할 거 같습니다.

 

마치며

지금까지 Atomic CSS가 '왜' 지금에 와서 채택이 되게 되었는지에 대해 CSS의 역사을 살펴보며 알아보았습니다.

 

최근까지 저는 기존의 CSS 작업은 단순 노동에 가깝다고 생각했었습니다. 하지만 Tailwind CSS를 접하고 바로 바로 결과를 확인하며 CSS 작업을 할 수 있는 Tailwind의 Utility-First 방식에 큰 매력을 느끼게 되었습니다. 하지만 이와 같은 방식은 아직까지도 대다수의 개발자들에게 환영받지 못하고 있는 상황입니다. 

 

Tailwind CSS가 가지는 매력과 함께 그래서 Tailwind가 '왜' 등장한 것이며, '어떤 문제'를 개선하기 위해 등장한 것인가에 대한 조사를 진행하던 중 프론트 엔드 개발자 '테오'님의 CSS 관련 포스팅을 접하게 되었습니다. Atomic CSS에 대해 안 좋은 시선을 가지고 있는 개발자분들은 해당 아티클을 통해 Atomic CSS의 매력에 대해 알아볼 수 있을 거 같습니다. 

 

본 포스팅을 준비하며 향후 CSS 관련 포스팅의 방향에 대해 고민해보는 시간을 가졌습니다. 향후 CSS 포스팅은 크게 2가지 방향으로 진행될 예정입니다. 먼저 CSS3와 Flexbox, Gridlayout에 대해 딥다이브하는 포스팅을 다룰 예정입니다. 이와 동시에 Tailwind CSS에 대한 학습과 프로젝트 적용기에 대한 포스팅을 함께 진행해볼 예정입니다. 앞으로도 CSS 관련 포스팅을 꾸준히 업로드 할 수 있도록 노력하겠습니다.

 

마지막으로 테오님의 원문은 CSS에 대해 진지하게 고민해볼 수 있는 좋은 포스팅이라고 생각됩니다. 본 포스팅을 통해 CSS의 역사에 대해 관심이 생기신 분들은 꼭 한번 원문을 읽어보시는 것을 추천드리겠습니다. 

 

참고

https://velog.io/@teo/css-history-1

 

CSS 역사로 알아보는 CSS가 어려워진 이유

저는 사실 UI 구현하는 것보다는 효율적인 CSS가 무엇인지 몰라서 늘 불만스러워요… > 구현은 어떻게든 해서라도 얼추 되겠는데... 그게 좋은 코드같아보이지않아서ㅜㅜ 프롤로그 맞습니다. CSS

velog.io

https://tech.kakao.com/2022/05/20/on-demand-atomic-css-library/

 

내가 하면 더 잘 만들 것 같아서 만들어 본 세상 귀여운 on-demand Atomic CSS Library. -Part.1

- 내가 하면 더 잘 만들 것 같아서 만들어 본 세상 귀여운 on-demand Atomic CSS Library.최근에 CSS 계에서 주목받고 있는 TailwindCSS를 써보셨거나 들어보신 적이 있나요? 혹은 Utility-first CSS, Atomic CSS, Func

tech.kakao.com

'Tech > CSS' 카테고리의 다른 글

[CSS] Container 와 Wrapper 의 차이점  (2) 2023.09.11
profile

Lambda

@Lamue

포스팅이 좋았다면 "공감❤️" 또는 "구독👍🏻" 해주세요!