
Solid is a purely reactive library. It was designed from the ground up with a reactive core. It's influenced by reactive principles developed by previous libraries.
www.solidjs.com
말하신대로 로우레벨, 하이레벨로 나뉠 수 있습니다.
로우레벨은 또 scss, stylus와 같이 중첩된 셀렉터나 믹스인, 함수, 보간으로 css의 리터럴 구문 확장이나 조작을 개선하려는 패러다임과 tailwind, unocss처럼 재정의하거나, 축소하여 간결하게 디자인 시스템 토큰들을 만들려는 패러다임으로 나뉠 수 있습니다.
전처리기의 경우 조작은 js가 워낙 편하니 상위호환이고 셀렉터 문제도 대부분 css in js가 잘 다루어주고 있죠. 다만 scss의 property nesting, stylus의
property lookup등의 기능은 없어서 아쉬웠고요.
개인적으로 emotion의 object style을 선호하는데 zero runtime css in js에서 linaria는 지원하지 않고 vanilla extract는 selectors나 vars 처럼 쓸데없는 블럭
을 만들 필요가 있나 싶습니다.
atomic css의 경우 twin macro가 있으나 여전히 별로입니다. 저는 object style을 선호하기 때문에 tw(["flex", { w: 12, h: "md" }])처럼 합성 가능해야 한다는 거죠. 대시(-) 표시가 결국은 key-value값을 뜻하고 variant는 중첩 셀렉터나 다름없습니다.
거기다 tailwind는 사실상 만들어진 디자인 시스템 프리셋을 제공하는 수준이고요, unocss 보면 알겠지만 다들 유지보수하기 싫어하는 정규식을 사용하거나 variant 만들기 자체가 까다롭습니다.
vanilla extract의 sprinkles도 참고할만한 합니다. 조건을 붙일 수 있어서 좋아요.
하지만 key-value만 사용해야 하는 근본적인 API 한계로 tw(["flex", "visible"])와 같이 사용이 불가하기 때문에 tailwind류를 절대 대체할 수 없습니다.
다이나믹 룰도 불가한데 fela나 lucid처럼 함수를 이용하면 되지 않나 싶고요.
마지막으로 데드코드 최적화가 불가합니다.
이건 패키지 뜯어보니 미리 모든 조건에 따라 생성을 해놓던데.. lazy하게 처리하려 합니다.
이제 약간 더 의미론적으로 만들어진 하이레벨을 다루어볼까요
하이레벨은 크게 3가지로 나뉠 수 있습니다.
- 규약에 따라 UI 값을 변경 가능한 theme
- 리터럴 혹은 디자인 토큰을 조합하는 variant (tailwind나 unocss의 variant는 중첩 셀렉터 혹은 condition와 다를바가 없습니다)
- styled 컴포넌트
테마A는 배경이 파랑 텍스트가 노랑이고, 테마B를 사용하면 배경이 보라 텍스트가 하얀색으로 바뀌는 식이죠.
그런데 배경과 텍스트라는 규약이 정해져 있는겁니다.
atomic css가 bottom up이라면 theme는 top down인 셈이죠.
이것은 vanilla extract가 createTheme라고 잘 만들어놓은 터라 그리 건들고 싶지는 않습니다.
프리셋 규약은 Theme UI가 잘 만들어 두었어요.
variant는 스타일들을 모아 의미있게 만들어줍니다.
stitches 덕분에 유명해진 개념이고, vanilla extract에서는 recipe라는 이름입니다.
base인 스타일, 여러 variant 설정과 variant 기본값등을 세팅할 수 있어서 좋죠.
문제는 디자인 토큰 생성기인 atomic css와 같이 쓰기가 불편합니다.
음.. 그러니까 이런식으로 atomic css에서 생성해쓰자는 거죠.
const { recipe } = crateSprinkles(shadowRules, borderRules, paddingRules);
const button = recipe({
base: ["shadow", { rounded: "md" }],
variant: {
roundless: {
rounded: 0
},
size: {
small: { p: 3 },
large: { p: "lg" },
custom: (padding) => ({ p: padding })
}
}
});
const smallButton = button({ size: "small" })
const largeRoundlessButton = button(["roundless", size: "large"])
const customButton = button({ size: { custom: 5 } })
상태만 다루는 headless ui와 붙여쓰면 꽤 편할거라 생각됩니다.
https://jbee.io/react/headless-concept/
styled 컴포넌트는 유명하니 자세한 설명은 생략.
react나 solid같은 컴포넌트에 의존하는 편이며 stitches가 잘 만들어 놓았다고 생각됩니다.
역시 atomic css 리턴값의 구조분해 할당에서 받아 쓸수 있으면 좋을 듯요.
해당 댓글은 삭제되었습니다.
스벨트는 좀 템플릿 엔진 문법같긴 하드라
unocss
정규식 특유의 비직관성과 타입문제, stitches variant 같은 케이스는 안되서 불만이랄까
css in js는 어떤부분이 맘에 안드셨나요. 저는 컴포넌트형 css in js들은 약간 로우레벨 + 하이레벨을 동시에 다루는 애매한 포지션이라 생각되어서, 한번 더 랩핑한 형태가 필요하다 생각은 들었는데.. 어떤 형태로 구현하실지 궁금하네요.
solid는 jsx + signal형태구나만 생각하고 크게 안봤는데 저런 개념도 있네요. 굿굿..
댓글 쓰다가 길어져서 본문을 업데이트 했습니다. 결론은 로우레벨과 하이레벨을 동시에 다룰수 있는 포텐셜은 있으나 "잘" 다루지를 못하고 있어서 불편하다는 거에요!!
처음 들어본 다양한 솔루션들이 많네요 ㅎㅎ 자세한 설명 감사합니다. 저는 유연한 디자인 시스템을 만들기 위한 기반 시스템을 Theme UI와 비슷한 아이디어로 만드는게 어떨까 생각해보고있어요. Theme UI에서 제공하는 규약들이 그리 편하지 않아서 간단한 추상 레이어정도만 제공하는것으로.. + 스타일 처리는 styled component의 object기반 style을 사용하고 있습니다. 다만 object 기반의 style을 하다보면 css에서 처리하는 방식에 비해 불편한것들이 많았는데 말씀해주신 솔루션들 중에 생각해볼만한 API들이 몇개 있네요 ㅎㅎ
마지막에 headless ui를 통한 ui 상태관리 및 표현 대한 이야기도 해주신것같은데, 저는 하다보니 css와 별도 상태관리로 나누는게 오히려 더 불편한게 많더라구요. headless로 빼낼 수 있는 컴포넌트 패턴도 생각보다 다양하지 않고, 저런 컴포넌트를 만드려면 기준 기능들을 정해야할텐데 쉽게 기준포인트를 잡는다는것 자체가 리스크가 좀 있더라구요. (쉽게 깨질 수 있는 확률이 높다고 생각..)
앗 그건 저도 동의합니다. headless ui가 유용한 경우는 라이브러리를 받아서 커스텀할때 이야기이고 자체적으로 디자인 시스템을 구축해야한다면 처음부터 통합되게 만드는게 낫다고 생각합니다. 표현과 내용의 완전한 분리는 쉽지 않긴해요.
https://cva.style/docs/getting-started/variants
저도
일에 바빠 까먹다가.. 우연히 ui라이브러리를 알게되었는데..
요런 느낌과 비슷한것을 구현하시려는게 아닐까 해서 다시한번 찾아왔습니다.
CSS류 라이브러리들을 잘 써본적이 없어서 어떤 솔루션들이 있었고, 한계점이 있었는지 아직까지는 피부로 와닿지 않아 모호하네요 @.@ 하지만 덕분에 어디서부터 공부해봐야하는지는 찾을 수 있었던 것 같습니다. 갑자기 와서 감사인사 ㅎㅎ;ㅋㅋ
맞아요 거의 비슷하고, panda랑 형태는 더 비슷할 것 같네요. 다만 둘 다 atomic을 위한 정의부분이 미흡해서 아쉽긴하더라고요.
https://github.com/chakra-ui/panda
관련 라이브러리들을 가지고 몇번 만져보다보니 궁금했는데 선생님께서는 결국 저런걸 구현하려면 bottom-up으로 쌓아가는 방식이 atomic css 기반으로 스타일링 하는게 결과적으로 좋은 방향일 것 같다는 의미일까요? (제가 이해한 바로는) bottom-up으로 스타일을 쌓는 방식이라 하면 (1) js object로 하는 스타일링도 있을것이고, (2) styled-component처럼 템플릿 문법으로 컴포넌트화 하여 쌓는 방식도 있을 것같고, 아니면 (3) styled-system처럼 component에 styled props를 껴넣는 방식도 있을것이고.. 전통적인 방식인 (4)atomic css도 있을 것 같은데.. Bottom-up 방식에 따라서 top-down을 다루는 방식이 달라질 것 같아서요.
스타트업 레벨은 몰라도 퀄리티를 올리려다 보면 재구성이 필요한 순간이 올 것이라는 겁니다. 테일윈드가 타 디자인 시스템에 비해 자유롭긴해도 color, space등이 미리 구성된 디자인 시스템 입니다. 일단 형태와 표현에는 많은 발전이 있었어요. tailwind류는 .red로 매핑되던[결합도 감소] 시각적 형태에서 나아가 미디어 쿼리등을 인라인으로 사용가능하고 각종 property를 재정의한 사례입니다. stitch류는 .button이나 BEM처럼 각 클래스가 1개와 매핑되던 의미론을 넘어서 button({size: "large"}) 같이 응집력을 극대화한 사례입니다. 2가지로 쓰이던 class의 발전체인겁니다. 그러면 자연스럽게 두 세계의 장점을 가지고 오고 싶어해요. 말씀하신 CVA가 대표적인 예.
그런데 축은 여러가지죠. tailwind처럼 html inline과 같이 쓰기, 본문에 적은 것처럼 css-scss방식, typescript 방식처럼 프로그래밍 언어적 표현을 고려할 수 있습니다. 이중 typesafe하면서도 동적인 코드들과 연동을 생각하면 typescript방식이 가장 낫다가 제 생각입니다. Styled component처럼 쓸 수 있는 새로운 가능성도 열리고요. 거기서도 더 자연스러운 표현을 찾자면 "p-3" 처럼 인라인으로 쓰기보다 { p: 3 }이 더 이상적이라는거죠. 이게 CVA 표현력의 단점이라는거죠. 반면 panda나 vanilla extract는 "visible"처럼 단일값으로 쓰이면 좋은 유니크한 사례들을 atomic으로 쓰지 못해 여전히 표현력에 제약이 있습니다.
리터럴 문법쪽을 추가로 살펴봐도 복잡한 selectors를 요구하는 vanilla extract는 엉망이라 할 수 있고요, panda css의 경우 고민을 많이 해놨습니다. nested style이 아주 잘되어 있어요. conditional style 정말 편하고 pseudo에 _를 사용하기도 좋은 아이디어입니다. 프리셋이 강력해서 hstack같은 패턴 제공도 좋습니다. 기존 디자인 시스템이 패턴을 제공하지 않는 것과 다르게 중간 형태까지 신경쓰는 모습이에요. 다만 전반적으로 ad-hoc스럽게 문제를 해결합니다.
pseudo쪽이 대표적인데 뭐 이정도면 허용범위라고 보기는 합니다. 대신 token이라 하여 탑다운 테마 시스템이 있는데 "green.400"과 같이 문자열로 사용해서 아쉽습니다. 리터럴로 숫자를 넣어도 px로 변환안된거는 소소하게 아쉬운 부분이구요. 무엇보다 커스텀이 여전히 많이 어려워 보인다는게 아쉽네요. meta적인 면에서 말이죠. 사실 일반적인 상황에서는 크게 문제가 없어보여서 저도 만들지 말지 고민하고 있습니다. 지금 벌여놓은 일들이 많기도 하고요 ㅎㅎ
레이어와 같아서 js object-atommic-varient-styled component-styled system-with headless ui과 같은 식으로 쌓아올릴 수 있다고 보는 편이긴 합니다.
실제로 taileind가 의미론적이지 않아 다시 부트스트랩 형식으로 회귀한
https://daisyui.com/
같은 라이브러리가 나오며, headless ui와의 결합을 위해서
https://ui.shadcn.com/
가 나오고 있습니다.
저는 장기적으로 이 방향으로 갈거라고 보기는 합니다. 동적인게 필요하면 top-down방식이 하나 들어갈 수도 있을것 같긴합니다. 여기서는 vanilla extract-theme ui가 잘되어있는듯 싶긴해요.
상세한 답변 항상 감사드립니다. 약간 다른 방향이긴 하지만 저도 제가 뭘 필요로 했던건지 답변을 보면서 정리가 되었네요. 제가 궁극적으로 원하는건 type-safe atomic-css + type-safe variants with theme constaints 같은 형태였는데요. styled-[...] 조합으로 처리하면 제 니즈가 생각보다 충족이 될 것 같더라구요.
예를들면, github/primer
https://github.com/primer/react
구현체처럼 Box 컴포넌트, sx props만들어두면.. atomic-css + object styling과 비슷한 효과를 낼 수 있을 것 같고. variants 부분은 타입부터 구현까지 수정이 조금 필요할 수 도 있는데, 기본적으로 전달되는 데이터가 js object형태인데다가 styled-system 유틸들이 꽤 많아 아직까지는 괜찮은 것 같네요.. (제발...)
근데 소개해주신 panda css같은 경우는 개인 플젝할 때 빠르게 뭐 만들고 싶을 때 좋을 것 같아요 ㅎㅎ.. ad-hoc스럽게 문제를 풀어서 팀에 소개하기에는 부담이 있네용 ㅠ
네 styled system 되게 좋은것 같아요 깊이있게 의견을 나눌수 있어 재미있었습니다!!
해당 댓글은 삭제되었습니다.
오 약간 assembler css에 stitches variant 조합한 느낌도 나네요?
https://asmcss.com/
재미있는
접근인듯