최근 업계에서 많이 이야기되고 있는 TailwindCSS 가 있습니다.
그리고 Utility-first CSS, Atomic CSS, Functional CSS가 있습니다.
이 글은 CSS에 대한 전반적인 내용과 함께 Atomic css, Unocss에 관해 공유하려고 남깁니다.
Atomic css는 오래전부터 있었고 근래에 다시 재발견? 되었으며 다소 오해가 많은 패러다임이기에 조심스럽게 CSS유래와 함께 설명하며 풀어가려고 합니다.
CSS Language & Interaction
[1996] CSS1 https://www.w3.org/TR/REC-CSS1/
[1999] CSS3 https://www.w3.org/TR/CSS/
[2022] CSS4 작업 초안 작성
초창기 html에 스타일 입히는 방식이였던 inline-style
1990년 웹이 보편화 되면서 꾸미는 것을 원했고 이를 위해 Style이라는 것이 추가가 되었습니다.
그래서 태그에 style을 입력해서 조금 더 다양한 형태의 문서를 만들 수 있게 되었습니다.
이렇게 태그에 직접 style을 지정하는 방식을 inline-style이라고 합니다.
<h1 style="color:black;">타이틀</h1>
inline-style은 같은 코드 표현할때 너무 비대해지면서 가독성,유지보수가 어려웠습니다.
<p style="position:absolute;width:1px;height:1px;left:-100px;top:-100pxfont-weight: 400;font-family: 'Noto Sans KR', sans-serif;">문장1</p>
<p style="position:absolute;width:1px;height:1px;left:-100px;top:-100pxfont-weight: 400;font-family: 'Noto Sans KR', sans-serif;">문장2</p>
<p style="position:absolute;width:1px;height:1px;left:-100px;top:-100pxfont-weight: 400;font-family: 'Noto Sans KR', sans-serif;">문장3</p>
<p style="position:absolute;width:1px;height:1px;left:-100px;top:-100pxfont-weight: 400;font-family: 'Noto Sans KR', sans-serif;">문장4</p>
inline-style의 중복을 제거하기 위한 방법을 고안하게 되고 그래서 CSS를 만들게 됩니다.
CSS는 위와 같이 중복해서 쓰이던 inline-style을 별도의 Rule로 선언을 하고 필요한 곳에 반복적용을 하는 방식으로 만들어졌습니다.
컨텐츠와 서식의 분리관리
CSS와 html이 분리가 되면서 컨텐츠(html)와 서식(css)를 꼭 1:1로 매칭을 하지 않고 하나의 컨텐츠에 여러가지 스타일을 선택적으로 적용하였습니다.
- 컨텐츠수정 = HTML을 수정
- 서식이 변경 = CSS를 수정
유연하게 디자인을 적용할 수 있도록 HTML을 잘 구조화시키고
HTML 변화 없이 CSS만으로 여러가지 스타일 만드는것이 주요 과제였습니다.
2003년 5월 출시된 CSS 기반 디자인을 통해
html은 변하지 않고 CSS로만 디자인을 바꾸던https://en.wikipedia.org/wiki/CSS_Zen_Garden 이 있습니다.
HTML을 수정하지 않고 CSS만으로 디자인을 적용하려고 하다보니 스타일을 하나하나 원하는 엘리먼트를 선택해서 스타일을 적용하는 것은 쉬운일이 아니었습니다. 원하는 요소를 찾고 수정하기 위해서는 복잡한 Selector를 써야했고 Selector역시 세분화가 필요했습니다.
그래서 이렇게 복잡해진 Selector를 조금 더 쉽게 만들 수 있는 언어인 Sass와 같은 것들이 등장 하였습니다.
.class {
font-size:13px;
.class2 {
color:#3399ff;
}
}
CSS Preprocessors
[2006] Sass https://sass-lang.com/
[2009] LESS http://lesscss.org/
[2010] Sass (SCSS) https://sass-lang.com/
[2010] Stylus http://stylus-lang.com/
Ajax의 등장
Ajax가 보편화가 되면서 백엔드에서 HTML을 제외한 데이터만 전달을 할 수 있게 되면서 이제는 HTML의 편집권은 백엔드가 아니라 프론트엔드로 내려오게 됩니다.
HTML과 CSS를 동시에 편집을 할 수 있게 되면서 이제는 복잡하게 Selector를 쓸 필요가 없다는 것을 깨닫게 됩니다.
CSS에서 복잡한 Selector를 잘 쓰기 보다는 HTML에서 미리 잘 지어둔 class가 처리하는데 좋다고 변하게 됩니다.
그래서 이후에는 Selector를 어떻게 잘쓰는지 보다 어떻게 class 이름을 더 잘 지을 수 있는지로 흐름이 변하게 됩니다.
의미있는 이름 vs 시각적인 이름
복잡한 Selector보다는 단순한 Class Selector 사용이 보편화되면서 업무의 어려움이 이제 어떠한 이름을 지을 지가 되었습니다.
class 이름을 짓는 방식
- 의미를 기반으로 하는 .error, .title
- 기능이나 시각적 요소를 기반으로 하는 .red .bold
그러나 시각적 요소로 작성하는것에 문제가 생기기 시작합니다.
.blue {color:blue;}
디자인이 변경이 되어 blue가 black가 된다면??
.blue {color:black;}
스타일 변경시 CSS를 수정을 하는데 변경된 디자인에 맞게 CSS를 변경하다보니 시각적인 이름을로 짓게 될 경우 .blue { color: black} 라는 이상한 작성이 되게 되었습니다.
시각적인 이름 보다 의미에 맞는 시멘틱한 이름이 좋다.
이때 아래와 같은 방법론이 나타나게 됩니다.
시대가 흘러 이제는 웹 문서가 아니라 웹 어플리케이션의 시대가 왔습니다.
웹은 더 이상 문서나 홈페이지 형태가 아니라 웹으로도 어플리케이션을 만들게 되고 CMS와 같은 데이터를 다루는 백오피스등의 웹페이지의 요구사항이 커지게 되었습니다. 그러다보니 웹은 점차 어플리케이션의 형태로 발전을 하게 됩니다.
하지만 CSS는 웹 문서를 잘 꾸미기 위해서 설계되었습니다.
문제가 생기기 시작하였습니다.
- css를 수정했는데 엉뚱한 곳이 틀어져 보이는 문제
- 선택자가 안 먹고 우선순위가 잘 맞지않아 !important로 덮어써야 하는 경우
- 안쓰이는 코드 찾기 (특히 JS와 결합된 class)
CSS는 어플리케이션을 만들기 위해 설계가 된 것이 아닌데 JS는 Component와 Framework 기반의 개발방식으로 변해갔습니다. 당시에는 flexbox와 같은 어플리케이션을 위한 레이아웃 스펙은 존재하지 않았기에 float,table등을 억지로 사용하고 문서의 간격을 만들기 위한 결정적으로 큰 2가지 설계상 문제들이 존재했습니다.
1 .Global Scope: 전역변수 = 내가 수정한 코드가 모든 프로젝트에 영향을 줘서 관리비용 증가 및 기존에 사용한 이름을 피해가며 작성해야한다.
2. 작성된 순서대로 적용 원하는대로 되는 문제
- HTML에서 지정한 class순서가 아니라 CSS의 순서에 의한 우선순위가 결정.
- 코드 순서도 있지만 무엇보다 Selector가 복잡할수록 서식이 나중에 적용
- 다른 서식을 덮어 쓰기 위해서는 Selector를 더 복잡하게 작성
- 이걸 간단한하게 수정하려면 !important 사용
- !important를 한 속성을 덮어쓰려면 복잡한 Selector에 !important
CSS 방법론
처음부터 CSS를 작성하는 규칙을 잘 짜면 이러한 문제들을 해결할 수 있지 않을까? 하는 생각에서 나온 것이 CSS 방법론입니다.
SMACSS, OOCSS, BEM, ITCSS, ATOMIC CSS ...
CSS Methodologies
[2009] OOCSS http://oocss.org/
[2011] SMACSS http://smacss.com/
[2012] BEM http://getbem.com/
[2013] ACSS https://acss.io/
[2016] ITCSS https://itcss.io/
그러나 점점 발전해가며 점점 작성하는 방식이 바뀌며 BEM스타일을 많이 사용하게되었습니다.
BEM이란 CSS 방법론 중 하나로, Blcok, Element, Modifier 의 약자이다.
하지만 방법론만으로는 코드의 복잡성을 줄이며 생산성을 가져오는 것은 아니었습니다.
그래서 JS와 함께 사용 하는 방식으로 해결하고자 하였습니다.
CSS Modules, 2015
CSS의 범위를 컴포넌트를 벗어나지 않게하여 Global Scope 문제 해결
CSS의 문제인 Global Scope를 막기 위해 Component 단위에서 사용되는 CSS에 hash를 추가하여 CSS가 더 이상 Global하지 않도록 하는 방식을 통해서 해결을 하고자 하는 방법이 만들어졌습니다.
이후 React에서 Style을 다루는 불편함을 해소하기 위해서 JS에서 HTML을 쓰기 위해 JSX를 만든 것처럼 JS에서 style을 쓰기 위한 방법으로 CSS-in-JS 라는 방법이 등장하게 됩니다.
CSS-in-JS StyledComponent, 2016
CSS를 JS의 컴포넌트 방식으로 작성하게 되며 StyledComponent가 탄생
JS Tools & CSS-in-JS
[2013] PostCSS
[2014] Autoprefixer
[2014] Browserslist
[2014] JSS
[2015] CSS Modules
[2016] Styled Components
[2017] Emotion
https://2021.stateofcss.com/ko-KR/technologies
Atomic CSS
우리는 분명 CSS가 만들어지고 초기 자연 발생했던 .bold .hidden .red .text-right .mt10 과 같은 Class를 만들어서 분명히 편하게 사용했던 경험들이 있었습니다.
그러나 이러한 방식은 시멘틱과는 멀었습니다. 그렇기에 일종의 작업편의 나 편법으로 생각했습니다.
하지만 작업하기 편리했습니다.
bg-blue-100 w-32 h-32 .text-center .font-semibold
.mt-30 .pt-10 self-start flex-wrap mb-10
의미기반이 아닌 시각적 기능에 기반한 이름을 지은 변하지 않는 단일 클래스를 이용하자.
변하지 않는 CSS를 먼저 만들어두고 HTML에서 스타일을 작성하자
미리 만들어둔 시각적인 이름을 바탕으로 HTML에서 필요한 스타일을 적용하는 방식으로
개발하는 방법론
저희가 작업하며 제일 어려운것들은 무엇이였을까요?
- 이름짓기 - 프로젝트 코드, 디렉토리, 파일명, 클래스명, 변수명, 메소드명
- 구현시 불가능한 상황 이해 시키기
- 업무를 받았을때 끝나는 시간 산정하기
- 다른 작업방식의 본인의 작업방식과는 다른사람의 소스 작업하기
이러한것들이 힘든일이라 생각됩니다.
.header .link .gnb .button .footer
어떤모양인지 알수있을까요.?
.section-header .main-title .inner-wrap .footer-title
이러한 이름들 어떤 디자인인지 구분이 안됩니다.
의미론적 이름짓기 방식의 한계점이 오기 시작하였습니다.
기존
Atomic CSS
이름짓기도 어려운 CSS를 계속 만들어야 하고
만들어 놓은 CSS를 피해야 하니 점점 복잡해져가서 파일 크기가 점점 커지지만
재사용이 불가능하기에 매번 계속 작성해야하는 악순환...
시각적 기능 기반 쉬운 이름을 가지며
미리 만들어 두기 때문에 1번 외워두면 계속 재사용이 가능하며
CSS가 일정 크기 이상으로는 더이상 커지지 않습니다.
아토믹을 사용하게되면
- 컨벤션과 방법론 역할 해줌
- 이름에 대한 고민 해결
- 누구나 동일한 형태의 코드 스타일
- 레거시 의식 불필요
- 구조변경시에도 파악하기 쉬워짐
왜냐하면 local scope기 때문입니다.
이러한 장점이 있으나 atomic CSS는 주류가 되지 못하였습니다.
TailwindCSS도 AtomicCSS이라 볼수있습니다. 하지만 Utility-First 라고 이름을 지었습니다.
Functional CSS도 마찬가지입니다.
Utility-First, Atomic CSS, Functional CSS 는 사실상 모두 같은 것을 의미합니다
ATOMIC CSS의 단점?
- html에 스타일 코드 반복?
- 의미론적 구분이 없으면 컨텐츠 파악의 어려움?
- 컨텐츠와 서식의 분리를 위한 다양한 테마는?
- html의 지저분함은? 코드의 가독성?
- css의 사용이 줄어들고 html만 작성이면 css를 잊는거 아닌지?
WebFrameWork의 COMPONENT 기반 개발 시대이며 컴포넌트가 시멘틱과 중복방지 역할을 해줍니다.
디자인이 곧 아디덴티티인 시대이며 솔루션이 아니라 서비스의 시대입니다.
코드는 시멘틱하지 않아도 됩니다.
그리고 점점 발전해 나가고있습니다.
FunctionalCSS -> Atomic CSS -> Utility First -> on-demand Atomic CSS
그렇다면 왜 현재 인기가 제일 많은 TailwindCSS가 아니라 AtomicCSS 인지 시작해보겠습니다.
TailwindCSS 문제로 많이 지적되는것은 HTML의 가독성 문제를 꼽습니다.
그런데 이전 BEM방식도 초창기에는 가독성 문제를 지적받았습니다.
CSS Modules나 CSS in JS 역시 그 가독성이 높은 편은 아닙니다. 그럼에도 왜 가독성 이야기가 나오는 것일까요?
TailwindCSS의 장점으로 보면 단순히 편리한 class 모음 몇 가지가 아닙니다.
기존 프레임워크 및 개발 생태계와의 쉬운 통합, IDE 지원, 기존 방식과 적절히 결합해 줄 @apply과 같이 하이브리드한 브릿지 기능, 사람들이 우려하는 반복처리, 용량 문제 등 많습니다.
디자인 시스템을 구축하면서 작업하기에는 TailwindCSS만한것도 없다고 생각이 들었습니다.
유지보수 과정에서 디자인 시스템구축이 되어 미리 수치나 색상등을 지정하고 그 틀에서 벗어나지않는다면 효과적인 작업이 되었습니다.
이렇게 미리 맞춰두고 작업을 하는 것이 좋은 디자인과 좋은 설계라고 했지만 디자인의 확장성이 어렵게 되었습니다. 정해진 컬러, 정해진 간격 등 그 틀을 벗어나는 디자인을 하기 힘들어졌기 때문입니다.
그렇기때문에 최근에는 JIT(Just-In-Time)이라는 방식이 나오게되었습니다.
작업 속도의 저하도 발생이 되었었는데. TailwindCSS에서 만들어둔 inlineCSS의 이름들과 CSS 스펙과 이름의 차이 등이 발생하였고 무엇보다 모든 CSS의 기능을 쓸 수 있는 것은 아니었습니다.
작업자마다 다르겠지만 조건부 class 서식이나, Child Selector를 쓸 수도 없었습니다. 코드 가독성이 떨어지는 부분들은 inline이라서가 아니라 이렇게 조건부 class들이였습니다.
TailwindCSS의 의 아쉬운 점이라면
- 커스텀을 하려면 복잡한 설정을 해야만
한다.했었다. - 용량문제(크다). purge를 하면 되지만 속도가 느리다.
- w-16은 16px이 아니다. 4배수 계산 이슈 - 이미지를 해상도에 맞춰야할때 4배의 size가 들어가는 케이스
- HTML이 복잡해진다.
- 미묘하게 아쉬운 스펙과 문법 = 러닝 커브 발생 (특히 flexbox)
- 모든 CSS 기능을 제공하는 것이 아니다.
Runtime CSS in JS의 문제
React가 유행하면서 CSS in JS가 많은 인기를 얻었습니다. 리액트를 사용해봤다면 한번쯤은 styled-component나 emotion을 사용해본 경험이 있을 정도입니다. CSS in JS는 다음과 같은 장점이 있습니다.
- CSS에서 JS문법을 사용할 수 있어서 생산성 🔼
- 컴포넌트 파일에 관련된 코드들을 함께 둘 수 있음 (colocation)
- 기존에는 css와 js파일을 분리해야했다.
- className이 겹치지 않음을 보장한다.(지역 스코프 스타일)
하지만 모든 기술에는 단점도 존재합니다. 기존의 CSS in JS, 즉 런타임 CSS in JS는 성능을 저하시킬 수 있다는 것입니다. 런타임 CSS in JS는 런타임에 js파일이 실행되면서 style을 생성합니다. style 생성의 규모가 크고 빈번할 수록 성능이 저하될 수 있습니다. 더 구체적인 예시를 들어보겠습니다.
Runtime CSS in JS의 문제점을 해결하기 위해 Zero-runtime CSS in JS가 등장합니다. Linaria, Sttiches, Vanilla Extract등이 있습니다.
Vanilla Extract는 기본적으로 CSS Modules-in-TypeScript라고 생각하면 됩니다.
- 빌드타임에 ts파일을 css파일로 만듭니다. (sass와 같음)
- type-safe하게 theme를 다룰 수 있습니다.
- 프론트앤드 프레임워크에 구애받지 않습니다.
- Sttitches 처럼 variant 기반 스타일링을 구성할 수 있습니다.
styled-component에서는 잘못된 프로퍼티를 사용해도 타입 검사를 제대로 하지 못한다는 단점이 있습니다.(물론 객체형태로 사용하면 됩니다.) 그리고 개인적으로 거추장스러운 문법들이 있었습니다. 예를 들면 (props)=> props.theme.color 같은 것들이 있습니다. Vanilla Extract는 거추장스러운 문법은 버리고 객체형태로 이를 풀어갑니다.
Vanilla Extract는 기능적으로 높은 확장성을 가지고 있습니다. Tailwind CSS를 모방한 Sprinkles, Sttiches을 모방한 Recipes 그리고 Linaria를 모방한 dynamic을 제공합니다. Vanilla Extract의 조금 부족했던 사용성을 채워줍니다. 거의 모든 CSS in JS를 총망라 했다고 볼 수 있습니다.
UnoCSS 의 배경
Tailwind는 큰 용량의 utility CSS 생성 → 시작과 HMR 오래 걸림 → Windi CSS를 대안으로 사용 - Windi CSS - 0 dependency, on-demand → Tailwind보다 20~100x 빠름 → Tailwind가 JIT 엔진을 개발
기존 방식의 단점
- margin의 범위가 1~10으로 제한됨
- 한 개만 써도 10개의 CSS rule 생성
- margin 방향 갯수를 지원하려면 코드 x 5 (mb, mt, mr, ml, m)
- hover:나 focus: 같은 variant 지원하려면 코드 x N
Tailwind에서는 PurgeCSS로 해결 → prod에서만 해결
On-demand 방식
on-demand 방식에서는 생성 단계와 스캐닝 단계의 순서를 뒤집어 cost 절약함과 동시에 미리 생성하는 방식에서 해결하기 어려운 동적 need를 해결할 수 있는 유연함도 갖춤
- dev와 prod 둘 다 사용 가능 → 일관성 보장, HMR 더욱 효율적
UnoCSS
UnoCSS - the instant atomic CSS engine with maximum performance and flexibility.
“최대 성능과 유연성을 가진 즉석 Atomic CSS 엔진”
core utility가 없기 때문에 framework라기보다는 engine이다 → 모든 기능은 preset이나 inline configuration을 통해 제공됨
직관적이고 완벽한 커스터마이징 가능
UnoCSS의 목표 - 직관성과 커스터마이징
자신만의 utility를 단번에 정의 가능
정적 룰
rules: [
['m-1', { margin: '1px' }]
],
코드에서 m-1이 발견되면 아래 CSS 생성:
.m-1 { margin: 0.25rem; }
동적 룰
matcher를 RegExp로 바꾸고 body를 함수로 바꾸면 됨
rules: [
[/^m-(\\d+)$/, ([, d]) => ({ margin: `${d / 4}rem` })],
[/^p-(\\d+)$/, match => ({ padding: `${match[1] / 4}rem` })],
]
<div class="m-100">
<button class="m-3">
<icon class="p-5" />
My Button
</button>
</div>
위 코드가 있으면 아래 CSS가 생성됨
.m-100 { margin: 25rem; }
.m-3 { margin: 0.75rem; }
.p-5 { padding: 1.25rem; }
변형
variants: [
// support `hover:` for all rules
{
match: s => s.startsWith('hover:') ? s.slice(6) : null,
selector: s => `${s}:hover`,
},
// support `!` prefix to make the rule important
{
match: s => s.startsWith('!') ? s.slice(1) : null,
rewrite: (entries) => {
// append ` !important` to all css values
entries.forEach(e => e[1] += ' !important')
return entries
},
}
],
프리셋
Tailwind CSS, Windi CSS, Bootstrap 등 기존 프레임워크 방식과 호환되는 다양한 프리셋 제공
유연성
지금까지는 Tailwind의 행동을 따라하는 방법을 보여줬음
지금부터는 UnoCSS의 진정한 힘
속성화 모드
<button class="bg-blue-400 hover:bg-blue-500 text-sm text-white font-mono font-light py-2 px-4 rounded border-2 border-blue-200 dark:bg-blue-500 dark:hover:bg-blue-600">
Button
</button>
위 코드를 아래처럼 쓸 수 있음:
<button
bg="blue-400 hover:blue-500 dark:blue-500 dark:hover:blue-600"
text="sm white"
font="mono light"
p="y-2 x-4"
border="2 rounded blue-200"
>
Button
</button>
코드가 보기 편해짐
예를 들어, 동일한 접두사를 중복하지 않고 text-sm text-white그룹화할 수 있습니다 .text="sm white"
접두사 자체 참조
접두사와 동일한 유틸리티를 갖는 flex, grid, 와 같은 유틸리티 의 경우 특수 값이 제공됩니다.border~
예를 들어:
HTML
<button class="border border-red">
Button
</button>
다음과 같이 쓸 수 있습니다:
HTML
<button border="~ red">
Button
</button>
Valueless attributify
Windi CSS의 속성 모드 외에도 이 사전 설정은 값이 없는 속성도 지원합니다.
<div class="m-2 rounded text-teal-400" />
위 코드를 아래처럼 쓸 수 있음:
<div m-2 rounded text-teal-400 />
정보
참고: JSX를 사용하는 경우 UnoCSS에서 생성된 CSS가 속성과 일치하지 않도록 <div foo>변환될 수 있습니다 . 이 문제를 해결하려면 이 사전 설정을 사용해 <div foo={true}>볼 수 있습니다 .transformer-attributify-jsx
순수 CSS 아이콘
제작자가 아이콘에 진심, 순수 CSS만으로 아이콘 표시 가능
<!-- A basic anchor icon from Phosphor icons -->
<div class="i-ph-anchor-simple-thin" />
<!-- An orange alarm from Material Design Icons -->
<div class="i-mdi-alarm text-orange-400 hover:text-teal-400" />
<!-- A large Vue logo -->
<div class="i-logos-vue text-3xl" />
<!-- Sun in light mode, Moon in dark mode, from Carbon -->
<button class="i-carbon-sun dark:i-carbon-moon" />
<!-- Twemoji of laugh, turns to tear on hovering -->
<div class="i-twemoji-grinning-face-with-smiling-eyes hover:i-twemoji-face-with-tears-of-joy" />
- 변형을 사용하면 hover, 라이트/다크 모드 등 기반으로 아이콘 변경 가능
- 10,000+개의 아이콘 지원
- ?bgfor background-img- 아이콘을 배경 이미지로 렌더링합니다.
- ?maskfor mask- 아이콘을 마스크 이미지로 렌더링합니다.
<div class="w-full flex items-center justify-center gap-x-4 text-4xl p-2 mt-4"> <div class="i-vscode-icons:file-type-light-pnpm" /> <div class="i-vscode-icons:file-type-light-pnpm?mask text-red-300" /> </div>
예를 들어 배경 이미지로 렌더링될 vscode-icons:file-type-light-pnpm색상이 포함된 아이콘( 은 svg포함되지 않음 )입니다. 마스크 이미지로 렌더링하고 색상을 우회하는 데 currentColor사용됩니다 .vscode-icons:file-type-light-pnpm?mask
https://unocss.dev/presets/icons 아이콘
속성 충돌
속성 모드의 이름이 요소 또는 구성 요소의 속성과 충돌하는 경우 un-UnoCSS의 속성 모드에 특정한 접두사를 추가할 수 있습니다.
예를 들어:
HTML
<a text="red">This conflicts with links' `text` prop</a>
<!-- to -->
<a un-text="red">Text color to red</a>
접두사는 기본적으로 선택 사항입니다. 접두사 사용을 적용하려면 다음을 설정하세요.
TS
presetAttributify({
prefix: 'un-',
prefixedOnly: true, // <--
})
다음과 같은 방법으로 특정 속성에 대한 검색을 비활성화할 수도 있습니다.
TS
presetAttributify({
ignoreAttributes: [
'text'
// ...
]
})
TypeScript support (JSX/TSX)
Create shims.d.ts with the following content:
By default, the type includes common attributes from @unocss/preset-uno. If you need custom attributes, refer to the type source to implement your own type.
React
ts
import type { AttributifyAttributes } from '@unocss/preset-attributify'
declare module 'react' {
interface HTMLAttributes<T> extends AttributifyAttributes {}
}
스코프
Tailwind/Windi - preflight로 native element를 reset하고 CSS 변수 fallback 제공 → 다른 UI 프레임워크와 함께 사용하면 conflict 발생 가능
UnoCSS - preflight를 유저가 알아서 하게 함 (다른 프레임워크와 함께 사용 가능)
Vite plugin에 scoped-vue 모드 → 각 컴포넌트마다 scoped 스타일을 생성해 컴포넌트 라이브러리로 안전하게 만들 수 있음 (유저 CSS와 conflict 걱정 X)
<template>
<div class="m-2 rounded"><slot></div>
<template>
<!-- the following will be inject in the bundler -->
<style scoped>
.m-2{margin:0.5rem;}
.rounded{border-radius:0.25rem;}
</style>
예시
'etc' 카테고리의 다른 글
Iframe 높이 조절 (0) | 2023.11.23 |
---|---|
로그인 인증의 방식 (1) | 2023.11.23 |
퍼블리셔 면접 관련 질문 정리 (3) | 2023.11.20 |
프론트엔드 개발자 면접 질문 답변 (0) | 2023.11.15 |
웹뷰 구분 못하게 막기 (0) | 2023.11.14 |