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

이번 글에서는  Atomic CSS 패러다임이 어떻게 진화해 왔고 왜 TailwindCSS는 과거와 달리 사용할 수 있는지 그리고 어떤 점에서 아직은 아쉬운지 이야기해 보려고 합니다.


 

3부. TailwindCSS의 의의와 한계점

 

잘못된 방법이라고 믿고 있는 방법을 주류에 올려놓기 위한 노력들

TailwindCSS의 가장 큰 의의는 이러한 AtomicCSS 방식을 주류 패러다임에 편입 시키기 위해서 여러 가지 커뮤니티 활동과 함께 이 패러다임을 믿고 거대한 생태계를 만들어 낸 것입니다. 조금 더 AtomicCSS 방식의 미래와 장점을 한번 생각해 봅시다.


class 방식은 inline-style이 아니다.

“inline-style처럼 생겼지만 inline-style이 아닙니다.”

inline-styler과 달리 AtomicCSS는

1. 미디어 쿼리도 사용할 수 있고
2. 한 번에 여러 속성을 포함하는 스타일을 만들 수도 있고
3. 의사 선택자인 의사 요소를 추가할 수도 있습니다. (:hover, :active)
4. Selector와 함께 결합해서 사용할 수도 있으며
5. inline-style보다 훨씬 더 유연한 방식으로 제공할 수 있습니다.


jQuery가 몰락하고 WebFramework가 뜬 이유? – 관심의 분리는 무조건 좋은 것인가?

“콘텐츠와 서식 관심의 분리가 과연 반드시 좋은 것일까요?”

jQuery

HTML과 JS의 관심의 분리를 해야지!

html + JS

				
					<button id="button">click me!</button> <h1 id="title">title</h1>
 $("#button").on("click", (e) => {...} $("#h1").text("제목")
 const title = (prop) => {
return <h1>{prop.title}</h1>
}
				
			

WebFramework

관심이 같은 것끼리 모아두자!
HTML과 데이터를 하나의 템플릿에 넣으면 좋더라! = 컴포넌트

Component

				
					const Button = () => {
  const onClick = {...}
  return <button onClick={onClick}>click me!</button>
}
				
			

결국 HTML과 JS가 서로 종속성이 있기에 관심의 분리보다 구조로 결합하는 게 더 좋았던 것처럼 HTML과 CSS 역시 서로 간의 종속성을 갖는 것이 좋습니다.


시멘틱한 이름이 반드시 좋은 것일까?

“시멘틱하게 이름을 붙여야만 디자인 변경에 유연할까요?”

하지만 지난 10년간 CSS는 그 시멘틱한 방법안에서 복잡함과 CSS 관리의 어려움에 맞서왔지만 애플리케이션 개발 환경에서는 그러한 패러다임이 유효하지 않다는 것을 알게 되었을 뿐입니다.

디자인의 콘셉이 하나뿐이라면 컴포넌트 기반 프레임워크 환경이라면 시멘틱한 이름의 역할을 이제 컴포넌트가 충분히 상쇄를 해줄 수 있습니다.

지난 if(kakao) 이야기

https://if.kakao.com/session/89

앱만 만들던 사람들과 웹앱으로 변환했던 경험이 있었습니다. 당시 앱만 했던 사람들은 CSS를 훨씬 어려워했으며, inline, 관심의 분리, 시멘틱 아무 상관없이 attibute에 직접 값을 넣는 방식을 훨씬 더 선호했고 아무런 문제가 없었으며 서비스는 잘 오픈했습니다.


TailwindCSS 문제는 가독성이다?

“그렇게 하면 HTML이 너무 못생겨지고 가독성이 완전 떨어져요!”

대부분 사람들이 지적하는 TailwindCSS의 문제는 HTML의 가독성 문제를 꼽습니다. 그렇다면 현재 CSS의 주류 3인방의 코드는 어떨까?

현재 class 이름을 짓는 정석(?)에 가까운 BEM 방식도 초창기에는 가독성 문제를 지적받았습니다. CSS Modules나 CSS in JS 역시 그 가독성이 높은 편은 아닙니다. 언제나 새로운 것은 낯설기 마련이며 이제는 가독성보다 쓰기 편하고 문제가 생기지 않는 방향으로 가고 있다는 것을 알게 됩니다.


TailwindCSS의 의의와 한계점

하나의 콘텐츠에 여러 테마의 서식으로 적용해야 하는 기능이 필요하다면, 혹은 웹 프레임워크를 사용하지 않고 개발을 한다면 TailwindCSS는 맞지 않는 옷일 수도 있습니다. 하지만 현대의 웹 서비스 개발에서는 하나의 디자인을 중심으로 웹 프레임워크를 통해 개발을 할 경우가 훨씬 더 많습니다!

.bold .text-center .hidden .grid-6 .clearfix
초창기 이러한 Utility CSS는 그냥 일부 편리한 CSS였을 뿐이었습니다. 그리고 이러한 방식은 일부 수정을 간단하고 빠르게 처리하는 일종의 꼼수로 취급받았습니다. 그래서 이러한 방식은 그동안 주류 기술이 되지 못했습니다.

그러나 TailwindCSS의 경우 이러한 패러다임을 완전히 벗어나서 단순히 편리한 class 모음 몇 가지가 아니라 그 편리한 방식을 모든 곳에 적용하려는 방식으로 개발하고 기존의 실험적인 라이브러리를 넘어 기존 프레임워크 및 개발 생태계와의 쉬운 통합, IDE 지원, 기존 방식과 적절히 결합해 줄 @apply과 같이 하이브리드한 브릿지 기능, 사람들이 우려하는 반복처리, 용량 문제 등을 해결할 PurgeCSS와 같이 본격적인 대형 라이브러리의 행보를 보였습니다.

그 과정에서 많은 패러다임의 충돌이 있었고 Hater들도 존재했고, 저 역시 어렴풋이 이 방식이 좋을 수도 있겠다는 생각은 있었지만 작정하고 써 볼 생각은 안 했었는데 이러한 설득에 넘어가 저도 TailwindCSS를 현업에서 쓰기 위한 노력을 해봤습니다.


그러나 TailwindCSS를 현업에서 사용하지 못했던 이유

TailwindCSS를 현업에서 쓰기 위해 적용을 해보니 당시에는 몇 가지 문제들이 있었습니다.

🎨 변하지 않는 CSS를 먼저 만들어두고 HTML에서 스타일을 작성하자.
=> 하지만 디자인이 없으면 CSS를 먼저 만들지를 못합니다. 😭

그러니 초창기 TailwindCSS는 크기와 색상을 미리 만들어 둘 수밖에 없었습니다. 전부 다 만들어 둔다면 용량이 무한정 늘어나니 자주 쓰는 일부 크기와 색상만 만들어 두었습니다. 하지만 저는 대부분 실전에서 디자이너가 만들어 달라는 대로 작업을 해야 했기에 미리 지정된 크기와 색상으로 작업하지 않습니다.

이러한 부분들은 디자인을 받아 가며 수정을 하는 과정에서 미리 수치나 색상을 서로 맞춰두고 작업을 해야 한다는 의미였습니다.

TailwindCSS는 그것이 디자인 시스템이고 그렇게 맞춰두고 작업을 하는 것이 좋은 디자인과 좋은 설계라고 했지만 실전에서는 디자인의 수정과 개발의 작업을 불편하게 만들어 줄 뿐이었습니다. 실무에서는 디자인 시스템이 만들어지기 까지에는 많은 시행착오가 존재하게 되고 수많은 요구사항들을 정해진 몇 가지 팔레트로만 해결을 하는 것은 결코 쉬운 일이 아닙니다.

이것은 최근에 3.0이 출시되며 JIT(Just-In-Time)이라는 방식이 나오면서 해결을 합니다만 나중에 설명하겠습니다.

뿐만 아니라 w-12는 12px이 아니라 48px로 당시 머터리얼 디자인에서 사용하던 4px grid 기반의 체계는 계속 계산을 해서 개발 과정을 멈칫거리게 만들었습니다.

또한 TailwindCSS에서 만들어둔 inlineCSS의 이름은 CSS 스펙과 이름이 미묘하게 달라서 매번 문서를 봐야 했어요. CSS를 많이 했던 저의 개발 경험과 미묘하게 어긋남을 느꼈습니다.

무엇보다 모든 CSS의 기능을 쓸 수 있는 것은 아니었어요. 조건부 class 서식이나, Child Selector를 쓸 수도 없었습니다. 코드 가독성이 떨어지는 부분들은 inline이라서가 아니라 이렇게 조건부 class들이라는 것들도 알게 되었습니다.

결국 TailwindCSS가 기존 CSS 개발 경험을 완전히 대체를 할 수 없다 보니 디자인이 없는 프로토타입에는 유리하나 디자이너와 주로 협업을 하는 현업 환경에서 쓰기에는 상당히 부담이 되었습니다.

‘AtomicCSS는 좋은 것 같은데 TailwindCSS 자체는 아직 조금 아쉽다. 이거보다 더 좋은 AtomicCSS 프레임워크를 만들 수 있지 않을까?’
라는 생각에 “내가 현업에서 쓸 수 있는 CSS 프레임워크”라는 콘셉으로 한번 만들어보기로 하였습니다!

 

4부. AdorableCSS는 뭐가 다를까?

Atomic CSS 패러다임은 사실 괜찮은 건데 TailwindCSS가 아쉬운 거라면 더 괜찮은 AtomicCSS 라이브러리를 만들 수 있지 않을까?

TailwindCSS의 아쉬운 점 정리

    1. 커스텀을 하려면 복잡한 설정을 해야만 한다. 했었다.
    2. 용량이 크다. purge를 하면 되지만 속도가 느리다.
    3. w-16은 16px이 아니다. 4배수 계산 이슈.
    4. HTML이 복잡해진다.
    5. 미묘하게 아쉬운 스펙과 문법 = 러닝 커브 발생 (특히 flexbox)
    6. 모든 CSS 기능을 제공하는 것이 아니다.


🔥 PurgeCSS가 아니라 on-demand!

수치나 색상을 미리 만들어두지 말고 HTML이 변할 때마다 만들어 주면 되지 않을까? 이것을 떠올렸을 때는 이것만으로도 혁신이라고 생각했었습니다 😅

AtomicCSS 방법을 실전에서 쓸 수 있게 만들게 해준 일등공신 패러다임입니다. 미리 CSS를 만들어야만 사용이 가능했던 방식에서 이제 실시간으로 입력을 할 때마다 그에 준하는 style을 만들어 내면서 마치 진보된 inline-style처럼 함수처럼 쓸 수 있는 형태가 되어 이러한 방식의 실전성이 한층 더 높아졌습니다.

✨ AtomicCSS의 Next Level! ✨
이 내용이 이 글 전체에서 가장 중요한 이야기입니다. AtomicCSS는 on-demand라는 패러다임으로 인해 한 단계 진화했으며 앞으로의 발전이 기대가 되는 이유입니다.


[참고] Just-in-Time

기존에는 CSS를 미리 만들어두고 HTML에 적용을 하는 방식이었기에 미리 수치나 색상 등을 만들어야 했고 이 전후 관계로 인해서 이 방식은 초기 생산성이 높지 않았습니다. 이제는 번들툴과 MutationObserver 등을 이용하여 개발을 할 때에는 수정사항을 바탕으로 실시간으로 style을 생성할 수 있게 되어 수치나 색상 입력에 대해서 자유롭게 되었습니다.

특히 최근의 HMR(Hot Module Replace) 방식과 결합이 되어 정말 실시간으로 디자인을 수정을 하고 건드는 것은 큰 생산성을 가져다주고 있습니다.

또한 이후 빌드 과정에서는 다시 필요한 style만 생성하도록 하여 사용되지 않는 죽은 코드를 CSS에 포함하게 하는 문제 역시 해결할 수 있도록 해주고 있습니다.


HTML이 지저분하지 않도록 문법을 예쁘게 만들자

🤔 어떤 문법을 제공해야 할까!?

다시 배우지 않았으면 좋겠다.
수치나 값이 눈에 잘 보였으면 좋겠다.
타이핑은 많이 하지 않았으면 좋겠다.
가독성이 높았으면 좋겠다.
손에 익은 타이핑 방식이면 좋겠다.
px이 근본이었으면 좋겠다.

여러 가지 원칙들을 바탕으로 고심을 하면서 문법들을 한번 정리해 보았습니다.


타이핑을 줄이자 vs 러닝 커브를 없애자!

타이핑을 줄이면서도 CSS를 새로 배운지 않게 할 수 있도록 중간점을 찾는 고민을 많이 하였습니다.
  1. 이미 1~2글자로 줄여서 부르고 있는 것들은 최대한 짧게 줄인다.
    ex) class="w(32) h(32) r(8) p(10/16) m(4/8/10/12) z(9999) bg(#000) c(#fff) b(#480ff)"
    w = width
    h = height
    r = border-radius m = margin
    b = border
    p = padding
    z = z-index bg = background c = color
    mt = margin-top
    bbw = border-bottom-width pr = padding-right
 
  1. 유니크한 CSS value라면 그대로 쓴다.
    ex) .inline .block .none .visible .hidden .bold .underline .100 .200 .absolute .relative .sticky .fixed .border-box .content-box .space-between .space-around .pointer
  1. 긴 프로퍼티는 핵심만 남겨서 가급적 1번만
    ex) .text-left .text-right .text-center .snap-start .snap-x .pointer-events-none
  1. 모든 기본적인 CSS의 문법은 쓸 수 있게
    모든 CSS Prop:value 제공 .box-shadow(0/0/10/#000.2) // 띄어쓰기는 /로 구분
    모든 Selector 제공 >div.selected:touch-action(pan-y)
    모든 Pseudo 제공 >>a:nth-child(2n+1):hover:bg(red)!!

 
가장 많이 쓰는 flexbox는 편하게 쓰게 해주자!

tailwindCSS를 쓰면서 또 아쉬웠던 부분은 flexbox 및 layout 관련 문법들이었습니다. CSS에서 가장 많이 쓰이는 속성들인데 직관적이지 못한 방식들과 길어지는 타이핑으로 인해 복잡하게 보이게 만드는 주범이라고 생각을 했습니다.

items-* content-* justify-content-* justify-*
align-items? align-content? justify-content? justify-items?
flexbox를 다루다 보면 정말 헷갈리는 속성들! 조금 더 쉽게 다룰 수는 없을까?

이러한 문법은 가장 많이 쓰는 디자인 핸드오프 툴인 figma에서 영감을 받아 AutoLayout과 유사한 형태로 작성할 수 있게 하여 간결함과 생산성을 높였습니다.

flexbox와 figma의 AutoLayout

1. 방향 2. gap, 3. padding, 4. 배치


편리한 Positioning Layer

뿐만 아니라 absolute나 fixed를 이용한 배치의 경우도 빈번히 일어나는데 top:0; left:0; right:0; bottom:0; width:100%; height:100% 와 같은 배치 구문들도 보다 직관적인 방식을 제공하여 훨씬 던 간결하면서도 생산성 있는 문법을 제공하였습니다.

 


그 밖에도…

그 밖에도 여러 가지 진보된 AtomicCSS의 기조를 따르면서도 불편했었던 많은 부분들을 수정, 보완하는 방법들을 추가하였습니다.

TailwindCSS를 하다 보면 TailwindCSS로 할 수 없는 상황이 나오곤 했습니다. class 선택자나 자식 선택자나 복잡한 셀렉터를 써야 하는 경우도 마찬가지였습니다. 기본적으로 CSS에서 제공하는 모든 기능들을 제공하려고 하였습니다.

All-in-one package!

1. 모든 CSS Property 사용 가능
2.:nth-child, ::after 등 모든 pseudo 사용 가능
3. 모든 Selector 사용 가능

4. 모든 Media Query 사용 가능 (예정)

뿐만 아니라 적게 쓰고 짧게 축약하면서도 직관적으로 다 담을 수 있도록 만들어 보았습니다.

기타 센스 있는 문법들

w(32~100%) = min-width: 32px; max-width: 100%;
font(16/1.5/-1%) = font-size, line-height, letter-spacing
c(–primary) = color: var(–primary)
@w(~768): @media max-width(768) { … }
nowarp… = 말줄임…
ratio(3:2)

백문이 불여일견! 한번 보러 오세요 🙂

https://developer-1px.github.io/adorable-css/


⚡️ One More Thing! – figma plugin

아직 계속 개발 중이지만 figma의 AutoLayout로 작성한 경우 자동으로 AdorableCSS로 추출해 주는 플러그인을 만들었습니다. 이 플러그인으로 인해서 디자인을 CSS로 개발하는 생산성이 한층 더 높아졌습니다.

 

Handshake figma 플러그인 🤝


끝으로…

최초에는 콘텐츠와 서식이 한데 모여 있었습니다. 그리고 콘텐츠와 서식을 한데 모으면 중복 등을 관리하기가 어렵다는 것을 깨닫고 콘텐츠와 서식을 분리하려는 시도가 생겼습니다. 이렇게 CSS는 문서의 서식만을 별도로 꾸미기 위해서 태어났고 발전했습니다.

콘텐츠와 서식을 분리하니 하나의 콘텐츠에 여러 가지 서식을 적용할 수 있다는 것을 알게 되면서 하나의 콘텐츠에 여러가지 테마라는 방식을 통해서 CSS는 성장해나갔습니다. 그러면서 HTML과 CSS의 방향은 디자인을 위한 시각적인 정보보다는 콘텐츠의 의미를 중심으로 작성을 하는 시멘틱한 방법을 중심으로 발전을 했습니다.

그러나 웹은 예상보다 훨씬 더 규모가 커졌고 문서나 홈페이지가 아닌 대규모의 애플리케이션 역시 웹 산업에 속하게 되었습니다. 하나의 문서에 여러 가지 디자인을 적용할 수 있도록 설계되었고 발전해 온 CSS는 이러한 애플리케이션의 변화 방향에 맞지 않는 것들이 발견이 되면서 애플리케이션에서 CSS 작업은 골칫거리가 되었습니다.

이를 극복하기 위해서 BEM을 비롯한 다양한 방법론과 CSS Modules, CSS in JS까지 여러 가지 해결책들이 나오면서 CSS로 대규모 애플리케이션을 만들어내는 방법들이 자리를 잡아가는 중입니다.

한편에서는 이러한 변화에 따라 기존까지의 방식인 시멘틱한 CSS가 아니라 시각적인 방식으로 작성을 하는 CSS 패러다임을 다시 꺼내들려고 하고 있습니다. 콘텐츠에 직접 서식을 입히려고 하는 이 방식은 이미 최초에 좋지 않은 방식으로 여겨졌기에 주류가 되지 못했지만 시대가 변했습니다.

AtomicCSS 방식은 모든 상황에 다 좋은 더 최신화된 방법은 아닙니다. 다만 특정한 상황에서는 이러한 방법이 더 좋을 수도 있다는 점이 확인되었고 누군가는 이러한 방식을 쓰려고 하고 있고 누군가는 여전히 이 방식에 대해서 회의적입니다.

어쨌든 AtomicCSS는 각자의 방식으로 on-demand라는 방법을 통해 한 단계 진화를 했고 여전히 개선할 수 있는 여지와 발전 가능성이 있습니다. CSS in JS와는 달리 StateofCSS에는 아직 섹션은 없지만 생태계는 발전 중이기 한번 관심을 가지고 지켜봐 주었으면 좋겠습니다.


전통적인 CSS와 Atomic CSS와의 비교


Atomic CSS 생태계

최신 on-damand AtomicCSS!

최초의 Programming Atomic CSS Atomizer – https://acss.io/
제일 유명하지만 개인적으로 조금은 아쉬운… https://tailwindcss.com/
tailwindCSS를 그대로 사용하면서 JIT 모드를 먼저 도입한 https://windicss.org/
attribute를 이용한 자동 css https://unocss.antfu.me/
Just-in-time CSS https://asmcss.com/
MutationObserver를 이용한 VirtualCSS https://styles.master.co/
ㄴ 최근 관심을 가지고 보고 있는 중이랍니다.


끝으로…

“AtomicCSS is not Silver Bullet. But it is good enough.”

끝으로 AdorableCSS도 많은 관심 부탁드립니다. 깃헙 이슈에 개선 요구사항이나 문의사항 올려주시면 항시 대기 중이며 수정하고 있습니다.

이 글이 AtomicCSS 방식에 대한 인식의 개선과 함께 그리고 CSS에 대한 유용한 정보과 인사이트가 있고 도움이 되기를 바랍니다.

감사합니다. 🥳

 
카카오톡 공유 보내기 버튼

Latest Posts

제5회 Kakao Tech Meet에 초대합니다!

Kakao Tech Meet #5 트렌드와 경험 및 노하우를 자주, 지속적으로 공유하며 개발자 여러분과 함께 성장을 도모하고 긴밀한 네트워크를 형성하고자 합니다.  다섯 번째

테크밋 다시 달릴 준비!

(TMI: 이 글의 썸네일 이미지는 ChatGPT와 DALL・E로 제작했습니다. 🙂) 안녕하세요, Kakao Tech Meet(이하 테크밋)을 함께 만들어가는 슈크림입니다. 작년 5월에 테크밋을 처음 시작하고,