Skip to content

Bun 의 번들러는 다음 기능을 갖춘 CSS 를 내장 지원합니다:

  • 모든 브라우저에서 작동하도록 최신/미래 기능 트랜스파일 (벤더 프리픽싱 포함)
  • 축소
  • CSS 모듈
  • Tailwind(네이티브 번들러 플러그인을 통해)

트랜스파일

Bun 의 CSS 번들러를 사용하면 브라우저 호환성을 걱정하지 않고 최신/미래 CSS 기능을 사용할 수 있습니다. 기본적으로 활성화된 트랜스파일링 및 벤더 프리픽싱 기능 덕분입니다.

Bun 의 CSS 파서 및 번들러는 LightningCSS 를 직접 Rust → Zig 로 포팅한 것이며, 번들링 접근 방식은 esbuild 에서 영감을 받았습니다. 트랜스파일러는 현대 CSS 구문을 모든 브라우저에서 작동하는 하위 호환 가능한 형태로 변환합니다.

NOTE

LightningCSS 와 esbuild 의 저자들이 한 놀라운 작업에 큰 감사를 드립니다.

브라우저 호환성

기본적으로 Bun 의 CSS 번들러는 다음 브라우저를 대상으로 합니다:

  • ES2020
  • Edge 88+
  • Firefox 78+
  • Chrome 87+
  • Safari 14+

구문 낮추기

네스팅

CSS 네스팅 명세는 선택자를 서로 안에 네스팅하여 더 간결하고 직관적인 스타일시트를 작성할 수 있게 해줍니다. CSS 파일 전체에 부모 선택자를 반복하는 대신, 자식 스타일을 부모 블록 내에 직접 작성할 수 있습니다.

scss
/* 네스팅 사용 */
.card {
  background: white;
  border-radius: 4px;

  .title {
    font-size: 1.2rem;
    font-weight: bold;
  }

  .content {
    padding: 1rem;
  }
}

Bun 의 CSS 번들러는 이 네스팅된 구문을 모든 브라우저에서 작동하는 기존 플랫 CSS 로 자동 변환합니다:

css
/* 컴파일된 출력 */
.card {
  background: white;
  border-radius: 4px;
}

.card .title {
  font-size: 1.2rem;
  font-weight: bold;
}

.card .content {
  padding: 1rem;
}

미디어 쿼리 및 기타 at-rule 을 선택자 안에 네스팅하여 선택자 패턴을 반복할 필요를 없앨 수도 있습니다:

scss
.responsive-element {
  display: block;

  @media (min-width: 768px) {
    display: flex;
  }
}

이는 다음과 같이 컴파일됩니다:

css
.responsive-element {
  display: block;
}

@media (min-width: 768px) {
  .responsive-element {
    display: flex;
  }
}

색상 혼합

color-mix() 함수는 선택한 색상 공간에서 지정된 비율에 따라 두 색상을 혼합하는 쉬운 방법을 제공합니다. 이 강력한 기능을 사용하면 수동으로 결과 값을 계산하지 않고도 색상 변형을 만들 수 있습니다.

scss
.button {
  /* RGB 색상 공간에서 30/70 비율로 파랑과 빨강 혼합 */
  background-color: color-mix(in srgb, blue 30%, red);

  /* 호버 상태를 위한 더 밝은 변형 생성 */
  &:hover {
    background-color: color-mix(in srgb, blue 30%, red, white 20%);
  }
}

Bun 의 CSS 번들러는 모든 색상 값이 알려진 경우 (CSS 변수 아님) 빌드 타임에 이러한 색상 혼합을 평가하여 모든 브라우저에서 작동하는 정적 색상 값을 생성합니다:

css
.button {
  /* 정확한 결과 색상으로 계산됨 */
  background-color: #b31a1a;
}

.button:hover {
  background-color: #c54747;
}

이 기능은 전처리기나 사용자 지정 도구 없이도 프로그래밍 방식으로 파생된 음영, 색조 및 액센트를 가진 색상 시스템을 만드는 데 특히 유용합니다.

상대 색상

이제 CSS 는 상대 색상 구문을 사용하여 색상의 개별 구성 요소를 수정할 수 있습니다. 이 강력한 기능을 사용하면 전체 색상을 다시 계산하지 않고도 명도, 채도 또는 개별 채널과 같은 특정 속성을 조정하여 색상 변형을 만들 수 있습니다.

css
.theme-color {
  /* 기본 색상으로 시작하여 명도를 15% 증가 */
  --accent: lch(from purple calc(l + 15%) c h);

  /* 브랜드 블루를 가져와 채도가 낮은 버전 만들기 */
  --subtle-blue: oklch(from var(--brand-blue) l calc(c * 0.8) h);
}

Bun 의 CSS 번들러는 (CSS 변수를 사용하지 않는 경우) 빌드 타임에 이러한 상대 색상 수정을 계산하여 브라우저 호환성을 위한 정적 색상 값을 생성합니다:

css
.theme-color {
  --accent: lch(69.32% 58.34 328.37);
  --subtle-blue: oklch(60.92% 0.112 240.01);
}

이 접근 방식은 각 값을 하드코딩하는 대신 수학적 관계를 기반으로 테마 생성, 접근 가능한 색상 변형 생성 또는 색상 스케일 구축에 매우 유용합니다.

LAB 색상

현대 CSS 는 LAB, LCH, OKLAB, OKLCH 와 같은 지각적으로 균일한 색상 공간을 지원합니다. 이러한 색상 공간은 기존 RGB 를 초과하는 색상을 표현할 수 있어 더 생생하고 시각적으로 일관된 디자인을 가능하게 합니다.

css
.vibrant-element {
  /* sRGB 색역 경계를 초과하는 생생한 빨강 */
  color: lab(55% 78 35);

  /* 지각 색상 공간을 사용한 부드러운 그라디언트 */
  background: linear-gradient(to right, oklch(65% 0.25 10deg), oklch(65% 0.25 250deg));
}

Bun 의 CSS 번들러는 아직 지원하지 않는 브라우저를 위해 이러한 고급 색상 형식을 하위 호환 가능한 대안으로 자동 변환합니다:

css
.vibrant-element {
  /* 가장 가까운 RGB 근사치로 폴백 */
  color: #ff0f52;
  /* 더 넓은 색역 지원을 위한 브라우저용 P3 폴백 */
  color: color(display-p3 1 0.12 0.37);
  /* 지원하는 브라우저를 위한 원본 값 보존 */
  color: lab(55% 78 35);

  background: linear-gradient(to right, #cd4e15, #3887ab);
  background: linear-gradient(to right, oklch(65% 0.25 10deg), oklch(65% 0.25 250deg));
}

이러한 계층적 접근 방식은 모든 브라우저에서 최적의 색상 렌더링을 보장하면서도 디자인에 최신 색상 기술을 사용할 수 있게 해줍니다.

색상 함수

color() 함수는 전통적인 RGB 공간을 넘어 다양한 미리 정의된 색상 공간에서 색상을 지정하는 표준화된 방법을 제공합니다. 이를 통해 더 넓은 색역에 액세스하고 더 생생한 디자인을 만들 수 있습니다.

css
.vivid-element {
  /* 더 넓은 색역을 위한 Display P3 색상 공간 사용 */
  color: color(display-p3 1 0.1 0.3);

  /* A98 RGB 색상 공간 사용 */
  background-color: color(a98-rgb 0.44 0.5 0.37);
}

아직 이러한 고급 색상 함수를 지원하지 않는 브라우저의 경우, Bun 의 CSS 번들러는 적절한 RGB 폴백을 제공합니다:

css
.vivid-element {
  /* 최대 호환성을 위한 RGB 폴백 먼저 */
  color: #fa1a4c;
  /* 지원하는 브라우저를 위해 원본 유지 */
  color: color(display-p3 1 0.1 0.3);

  background-color: #6a805d;
  background-color: color(a98-rgb 0.44 0.5 0.37);
}

이 기능을 사용하면 모든 브라우저에서 디자인이 계속 작동하는 동시에 현대 색상 공간을 즉시 사용할 수 있으며, 지원하는 브라우저에서는 최적의 색상을, 다른 곳에서는 합리적인 근사치를 표시합니다.

HWB 색상

HWB(색조, 흰색, 검정) 색상 모델은 순수 색조에 얼마나 많은 흰색이나 검정을 혼합하는지에 따라 색상을 표현하는 직관적인 방법을 제공합니다. 많은 디자이너는 RGB 나 HSL 값을 조작하는 것보다 이 접근 방식이 색상 변형을 만드는 데 더 자연스럽다고 생각합니다.

css
.easy-theming {
  /* 흰색이나 검정이 추가되지 않은 순수 시안 */
  --primary: hwb(180 0% 0%);

  /* 동일한 색조, 20% 흰색 추가 (틴트) */
  --primary-light: hwb(180 20% 0%);

  /* 동일한 색조, 30% 검정 추가 (셰이드) */
  --primary-dark: hwb(180 0% 30%);

  /* 흰색과 검정 모두 추가된 뮤트 버전 */
  --primary-muted: hwb(180 30% 20%);
}

Bun 의 CSS 번들러는 모든 브라우저와의 호환성을 위해 HWB 색상을 RGB 로 자동 변환합니다:

css
.easy-theming {
  --primary: #00ffff;
  --primary-light: #33ffff;
  --primary-dark: #00b3b3;
  --primary-muted: #339999;
}

HWB 모델은 디자인 시스템에 대한 체계적인 색상 변형을 만드는 데 특히 유용하며, RGB 나 HSL 값을 직접 작업하는 것보다 일관된 틴트와 셰이드를 만드는 더 직관적인 접근 방식을 제공합니다.

색상 표기법

현대 CSS 는 색상을 표현하는 더 직관적이고 간결한 방법을 도입했습니다. 공백으로 구분된 색상 구문은 RGB 및 HSL 값에서 쉼표의 필요성을 없애고, 알파 채널이 있는 16 진수 색상은 투명도를 지정하는 간결한 방법을 제공합니다.

css
.modern-styling {
  /* 공백으로 구분된 RGB 표기법 (쉼표 없음) */
  color: rgb(50 100 200);

  /* 알파가 있는 공백으로 구분된 RGB */
  border-color: rgba(100 50 200 / 75%);

  /* 알파 채널이 있는 16 진수 (8 자리) */
  background-color: #00aaff80;

  /* 단순화된 표기법을 사용한 HSL */
  box-shadow: 0 5px 10px hsl(200 50% 30% / 40%);
}

Bun 의 CSS 번들러는 이전 브라우저와의 호환성을 위해 이러한 현대 색상 형식을 자동 변환합니다:

css
.modern-styling {
  /* 이전 브라우저를 위해 쉼표 형식으로 변환 */
  color: rgb(50, 100, 200);

  /* 알파 채널 적절히 처리 */
  border-color: rgba(100, 50, 200, 0.75);

  /* 필요시 hex+alpha 를 rgba 로 변환 */
  background-color: rgba(0, 170, 255, 0.5);

  box-shadow: 0 5px 10px rgba(38, 115, 153, 0.4);
}

이 변환 프로세스를 사용하면 더 깔끔하고 현대적인 CSS 를 작성하면서도 모든 브라우저에서 스타일이 올바르게 작동하도록 할 수 있습니다.

light-dark() 색상 함수

light-dark() 함수는 복잡한 미디어 쿼리 없이 사용자의 시스템 환경설정을 존중하는 색상 구성표를 구현하는 우아한 솔루션을 제공합니다. 이 함수는 두 개의 색상 값을 받아 현재 색상 구성표 컨텍스트에 따라 적절한 값을 자동으로 선택합니다.

css
:root {
  /* 색상 구성표 지원 정의 */
  color-scheme: light dark;
}

.themed-component {
  /* 시스템 환경설정에 따라 자동으로 올바른 색상 선택 */
  background-color: light-dark(#ffffff, #121212);
  color: light-dark(#333333, #eeeeee);
  border-color: light-dark(#dddddd, #555555);
}

/* 필요시 시스템 환경설정 재정의 */
.light-theme {
  color-scheme: light;
}

.dark-theme {
  color-scheme: dark;
}

아직 이 기능을 지원하지 않는 브라우저의 경우, Bun 의 CSS 번들러는 적절한 폴백과 함께 CSS 변수를 사용하도록 변환합니다:

css
:root {
  --lightningcss-light: initial;
  --lightningcss-dark: ;
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --lightningcss-light: ;
    --lightningcss-dark: initial;
  }
}

.light-theme {
  --lightningcss-light: initial;
  --lightningcss-dark: ;
  color-scheme: light;
}

.dark-theme {
  --lightningcss-light: ;
  --lightningcss-dark: initial;
  color-scheme: dark;
}

.themed-component {
  background-color: var(--lightningcss-light, #ffffff) var(--lightningcss-dark, #121212);
  color: var(--lightningcss-light, #333333) var(--lightningcss-dark, #eeeeee);
  border-color: var(--lightningcss-light, #dddddd) var(--lightningcss-dark, #555555);
}

이 접근 방식은 복잡한 미디어 쿼리를 작성하거나 스타일을 복제하지 않고도 라이트 및 다크 테마를 처리하는 깔끔한 방법을 제공하면서도 아직 기능을 네이티브로 지원하지 않는 브라우저와의 호환성을 유지합니다.

논리적 속성

CSS 논리적 속성을 사용하면 물리적 화면 방향 대신 문서의 작성 모드 및 텍스트 방향을 기준으로 레이아웃, 간격 및 크기를 정의할 수 있습니다. 이는 다양한 작성 시스템에 자동으로 적응하는 진정한 국제적 레이아웃을 만드는 데 중요합니다.

css
.multilingual-component {
  /* 작성 방향에 적응하는 마진 */
  margin-inline-start: 1rem;

  /* 텍스트 방향과 관계없이 의미 있는 패딩 */
  padding-block: 1rem 2rem;

  /* 상단 시작 모서리에 대한 border-radius */
  border-start-start-radius: 4px;

  /* 작성 모드를 존중하는 크기 */
  inline-size: 80%;
  block-size: auto;
}

논리적 속성을 완전히 지원하지 않는 브라우저의 경우, Bun 의 CSS 번들러는 적절한 방향 조정을 통해 물리적 속성으로 컴파일합니다:

css
/* 왼쪽에서 오른쪽 언어용 */
.multilingual-component:dir(ltr) {
  margin-left: 1rem;
  padding-top: 1rem;
  padding-bottom: 2rem;
  border-top-left-radius: 4px;
  width: 80%;
  height: auto;
}

/* 오른쪽에서 왼쪽 언어용 */
.multilingual-component:dir(rtl) {
  margin-right: 1rem;
  padding-top: 1rem;
  padding-bottom: 2rem;
  border-top-right-radius: 4px;
  width: 80%;
  height: auto;
}

:dir() 선택자가 지원되지 않는 경우, 모든 브라우저 및 작성 시스템에서 레이아웃이 올바르게 작동하도록 추가 폴백이 자동으로 생성됩니다. 이는 이전 브라우저와의 호환성을 유지하면서 국제화된 디자인을 만드는 것을 훨씬 간단하게 만듭니다.

:dir() 선택자

:dir() 의사 클래스 선택자는 텍스트 방향 (RTL 또는 LTR) 에 따라 요소를 스타일링할 수 있게 해주며, JavaScript 없이도 방향 인식 디자인을 만드는 강력한 방법을 제공합니다. 이 선택자는 문서나 명시적 방향 속성에 의해 결정된 방향성을 기반으로 요소와 일치합니다.

css
/* 텍스트 방향에 따라 다른 스타일 적용 */
.nav-arrow:dir(ltr) {
  transform: rotate(0deg);
}

.nav-arrow:dir(rtl) {
  transform: rotate(180deg);
}

/* 텍스트 흐름에 따라 요소 위치 지정 */
.sidebar:dir(ltr) {
  border-right: 1px solid #ddd;
}

.sidebar:dir(rtl) {
  border-left: 1px solid #ddd;
}

아직 :dir() 선택자를 지원하지 않는 브라우저의 경우, Bun 의 CSS 번들러는 적절한 언어 매핑과 함께 더 널리 지원되는 :lang() 선택자로 변환합니다:

css
/* 폴백으로 언어 기반 선택자 사용하도록 변환 */
.nav-arrow:lang(en, fr, de, es, it, pt, nl) {
  transform: rotate(0deg);
}

.nav-arrow:lang(ar, he, fa, ur) {
  transform: rotate(180deg);
}

.sidebar:lang(en, fr, de, es, it, pt, nl) {
  border-right: 1px solid #ddd;
}

.sidebar:lang(ar, he, fa, ur) {
  border-left: 1px solid #ddd;
}

이 변환을 사용하면 :dir() 선택자를 네이티브로 지원하지 않는 브라우저에서도 안정적으로 작동하는 방향 인식 CSS 를 작성할 수 있습니다. :lang() 에 여러 인수가 지원되지 않는 경우 추가 폴백이 자동으로 제공됩니다.

:lang() 선택자

:lang() 의사 클래스 선택자는 요소가 속한 언어를 기반으로 요소를 타겟팅할 수 있게 해주며, 언어별 스타일링을 쉽게 적용할 수 있습니다. 현대 CSS 는 :lang() 선택자가 여러 언어 코드를 받아들일 수 있게 하여, 언어별 규칙을 더 효율적으로 그룹화할 수 있습니다.

css
/* CJK 언어용 타이포그래피 조정 */
:lang(zh, ja, ko) {
  line-height: 1.8;
  font-size: 1.05em;
}

/* 언어 그룹별 다른 인용 스타일 */
blockquote:lang(fr, it, es, pt) {
  font-style: italic;
}

blockquote:lang(de, nl, da, sv) {
  font-weight: 500;
}

:lang() 선택자에서 여러 인수를 지원하지 않는 브라우저의 경우, Bun 의 CSS 번들러는 이 구문을 :is() 선택자를 사용하여 동일한 동작을 유지하도록 변환합니다:

css
/* 더 나은 브라우저 지원을 위해 :is() 로 그룹화된 여러 언어 */
:is(:lang(zh), :lang(ja), :lang(ko)) {
  line-height: 1.8;
  font-size: 1.05em;
}

blockquote:is(:lang(fr), :lang(it), :lang(es), :lang(pt)) {
  font-style: italic;
}

blockquote:is(:lang(de), :lang(nl), :lang(da), :lang(sv)) {
  font-weight: 500;
}

필요한 경우 Bun 은 :is() 에 대한 추가 폴백도 제공하여 모든 브라우저에서 언어별 스타일이 작동하도록 합니다. 이 접근 방식은 서로 다른 언어 그룹에 대한 명확한 타이포그래피 및 스타일 규칙을 가진 국제화된 디자인을 만드는 것을 단순화합니다.

:is() 선택자

:is() 의사 클래스 함수 (이전 :matches()) 는 여러 선택자를 함께 그룹화하여 더 간결하고 읽기 쉬운 선택자를 만들 수 있게 해줍니다. 인수로서 선택자 목록을 받아 해당 목록의 선택자 중 하나가 일치하면 일치하며, CSS 의 반복을 크게 줄입니다.

css
/* 별도로 작성하는 대신 */
/* 
.article h1,
.article h2,
.article h3 {
  margin-top: 1.5em;
}
*/

/* 이렇게 작성할 수 있습니다 */
.article :is(h1, h2, h3) {
  margin-top: 1.5em;
}

/* 여러 그룹이 있는 복잡한 예 */
:is(header, main, footer) :is(h1, h2, .title) {
  font-family: "Heading Font", sans-serif;
}

:is() 를 지원하지 않는 브라우저의 경우, Bun 의 CSS 번들러는 벤더 프리픽스 대안을 사용하여 폴백을 제공합니다:

css
/* -webkit-any 를 사용한 폴백 */
.article :-webkit-any(h1, h2, h3) {
  margin-top: 1.5em;
}

/* -moz-any 를 사용한 폴백 */
.article :-moz-any(h1, h2, h3) {
  margin-top: 1.5em;
}

/* 현대 브라우저를 위해 원본 보존 */
.article :is(h1, h2, h3) {
  margin-top: 1.5em;
}

/* 폴백이 있는 복잡한 예 */
:-webkit-any(header, main, footer) :-webkit-any(h1, h2, .title) {
  font-family: "Heading Font", sans-serif;
}

:-moz-any(header, main, footer) :-moz-any(h1, h2, .title) {
  font-family: "Heading Font", sans-serif;
}

:is(header, main, footer) :is(h1, h2, .title) {
  font-family: "Heading Font", sans-serif;
}

:not() 선택자

:not() 의사 클래스는 특정 선택자와 일치하는 요소를 제외할 수 있게 해줍니다. 현대 버전의 이 선택자는 여러 인수를 받아들여 하나의 간결한 선택자로 여러 패턴을 제외할 수 있습니다.

css
/* primary 및 secondary 변형을 제외한 모든 버튼 선택 */
button:not(.primary, .secondary) {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
}

/* 사이드바나 푸터 내부를 제외한 모든 제목에 스타일 적용 */
h2:not(.sidebar *, footer *) {
  margin-top: 2em;
}

:not() 에서 여러 인수를 지원하지 않는 브라우저의 경우, Bun 의 CSS 번들러는 이 구문을 더 호환 가능한 형태로 변환하면서 동일한 동작을 유지합니다:

css
/* 호환성을 위해 :is() 를 사용한 :not 으로 변환 */
button:not(:is(.primary, .secondary)) {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
}

h2:not(:is(.sidebar *, footer *)) {
  margin-top: 2em;
}

:is() 가 지원되지 않는 경우 Bun 은 추가 폴백을 생성할 수 있습니다:

css
/* 최대 호환성을 위한 추가 폴백 */
button:not(:-webkit-any(.primary, .secondary)) {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
}

button:not(:-moz-any(.primary, .secondary)) {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
}

button:not(:is(.primary, .secondary)) {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
}

이 변환은 원래 선택자의 특정성과 동작을 유지하면서 모든 브라우저에서 부정 선택자가 올바르게 작동하도록 보장합니다.

수학 함수

CSS 에는 스타일시트에서 직접 복잡한 계산을 수행할 수 있는 풍부한 수학 함수 세트가 포함되어 있습니다. 여기에는 표준 수학 함수 (round(), mod(), rem(), abs(), sign()), 삼각함수 (sin(), cos(), tan(), asin(), acos(), atan(), atan2()), 지수 함수 (pow(), sqrt(), exp(), log(), hypot()) 가 포함됩니다.

css
.dynamic-sizing {
  /* 값을 최소 및 최대 사이에서 제한 */
  width: clamp(200px, 50%, 800px);

  /* 가장 가까운 배수로 반올림 */
  padding: round(14.8px, 5px);

  /* 애니메이션 또는 레이아웃을 위한 삼각법 */
  transform: rotate(calc(sin(45deg) * 50deg));

  /* 여러 함수를 사용한 복잡한 수학 */
  --scale-factor: pow(1.25, 3);
  font-size: calc(16px * var(--scale-factor));
}

Bun 의 CSS 번들러는 모든 값이 알려진 상수 (변수 아님) 인 경우 빌드 타임에 이러한 수학 식을 평가하여 최적화된 출력을 생성합니다:

css
.dynamic-sizing {
  width: clamp(200px, 50%, 800px);
  padding: 15px;
  transform: rotate(35.36deg);
  --scale-factor: 1.953125;
  font-size: calc(16px * var(--scale-factor));
}

이 접근 방식을 사용하면 의미 있는 수학적 관계를 가진 더 표현력 있고 유지 관리하기 쉬운 CSS 를 작성한 후 최대 브라우저 호환성 및 성능을 위해 최적화된 값으로 컴파일할 수 있습니다.

미디어 쿼리 범위

현대 CSS 는 미디어 쿼리를 위한 직관적인 범위 구문을 지원합니다. <, >, <=, >= 와 같은 비교 연산자를 사용하여 더 장황한 min-max- 접두사 대신 중단점을 지정할 수 있습니다. 이 구문은 더 읽기 쉽고 값과 범위에 대해 일반적으로 생각하는 방식과 일치합니다.

css
/* 비교 연산자를 사용한 현대 구문 */
@media (width >= 768px) {
  .container {
    max-width: 720px;
  }
}

/* <= 와 >= 를 사용한 포함 범위 */
@media (768px <= width <= 1199px) {
  .sidebar {
    display: flex;
  }
}

/* < 와 > 를 사용한 배타적 범위 */
@media (width > 320px) and (width < 768px) {
  .mobile-only {
    display: block;
  }
}

Bun 의 CSS 번들러는 모든 브라우저와의 호환성을 위해 이러한 현대 범위 쿼리를 기존 미디어 쿼리 구문으로 변환합니다:

css
/* 기존 min/max 구문으로 변환 */
@media (min-width: 768px) {
  .container {
    max-width: 720px;
  }
}

@media (min-width: 768px) and (max-width: 1199px) {
  .sidebar {
    display: flex;
  }
}

@media (min-width: 321px) and (max-width: 767px) {
  .mobile-only {
    display: block;
  }
}

이를 통해 더 직관적이고 수학적인 미디어 쿼리를 작성하면서도 모든 브라우저 (현대 범위 구문을 지원하지 않는 브라우저 포함) 에서 스타일시트가 올바르게 작동하도록 할 수 있습니다.

단축형

CSS 는 코드 가독성과 유지 관리성을 향상시키는 여러 현대 단축형 속성을 도입했습니다. Bun 의 CSS 번들러는 필요한 경우 긴 형식으로 변환하여 이러한 편리한 단축형이 모든 브라우저에서 작동하도록 보장합니다.

css
/* 정렬 단축형 */
.flex-container {
  /* align-items 와 justify-items 를 위한 단축형 */
  place-items: center start;

  /* align-content 와 justify-content 를 위한 단축형 */
  place-content: space-between center;
}

.grid-item {
  /* align-self 와 justify-self 를 위한 단축형 */
  place-self: end center;
}

/* 두 값 overflow */
.content-box {
  /* 첫 번째 값은 가로, 두 번째 값은 세로 */
  overflow: hidden auto;
}

/* 향상된 text-decoration */
.fancy-link {
  /* 여러 텍스트 장식 속성 결합 */
  text-decoration: underline dotted blue 2px;
}

/* 두 값 display 구문 */
.component {
  /* 외부 display 타입 + 내부 display 타입 */
  display: inline flex;
}

이러한 현대 단축형을 지원하지 않는 브라우저의 경우, Bun 은 구성 요소 긴 형식 속성으로 변환합니다:

css
.flex-container {
  /* 확장된 정렬 속성 */
  align-items: center;
  justify-items: start;

  align-content: space-between;
  justify-content: center;
}

.grid-item {
  align-self: end;
  justify-self: center;
}

.content-box {
  /* 별도의 overflow 속성 */
  overflow-x: hidden;
  overflow-y: auto;
}

.fancy-link {
  /* 개별 텍스트 장식 속성 */
  text-decoration-line: underline;
  text-decoration-style: dotted;
  text-decoration-color: blue;
  text-decoration-thickness: 2px;
}

.component {
  /* 단일 값 display */
  display: inline-flex;
}

이 변환은 스타일시트가 깔끔하고 유지 관리하기 쉽게 유지하면서도 가능한 가장 넓은 브라우저 호환성을 제공합니다.

이중 위치 그라디언트

이중 위치 그라디언트 구문은 인접한 위치에 동일한 색상을 지정하여 그라디언트에서 하드 색상 정지를 만들 수 있게 해주는 현대 CSS 기능입니다. 이는 부드러운 페이드 대신 날카로운 전환을 만들어 스트라이프, 색상 밴드 및 기타 다색 디자인을 만드는 데 유용합니다.

css
.striped-background {
  /* 30%-40% 에서 녹색에서 빨강으로 날카로운 전환 생성 */
  background: linear-gradient(
    to right,
    yellow 0%,
    green 20%,
    green 30%,
    red 30%,
    /* 이중 위치가 하드 슆 생성 */ red 70%,
    blue 70%,
    blue 100%
  );
}

.progress-bar {
  /* 별개의 색상 섹션 생성 */
  background: linear-gradient(
    to right,
    #4caf50 0% 25%,
    /* 0% 에서 25% 까지 녹색 */ #ffc107 25% 50%,
    /* 25% 에서 50% 까지 노랑 */ #2196f3 50% 75%,
    /* 50% 에서 75% 까지 파랑 */ #9c27b0 75% 100% /* 75% 에서 100% 까지 보라 */
  );
}

이 구문을 지원하지 않는 브라우저의 경우, Bun 의 CSS 번들러는 색상 정지를 복제하여 기존 형식으로 자동 변환합니다:

css
.striped-background {
  background: linear-gradient(
    to right,
    yellow 0%,
    green 20%,
    green 30%,
    red 30%,
    /* 두 색상 정지로 분할 */ red 70%,
    blue 70%,
    blue 100%
  );
}

.progress-bar {
  background: linear-gradient(
    to right,
    #4caf50 0%,
    #4caf50 25%,
    /* 녹색 섹션용 두 정지 */ #ffc107 25%,
    #ffc107 50%,
    /* 노랑 섹션용 두 정지 */ #2196f3 50%,
    #2196f3 75%,
    /* 파랑 섹션용 두 정지 */ #9c27b0 75%,
    #9c27b0 100% /* 보라 섹션용 두 정지 */
  );
}

이 변환을 사용하면 소스 코드에서 더 깔끔한 이중 위치 구문을 사용하면서도 모든 브라우저에서 그라디언트가 올바르게 표시되도록 할 수 있습니다.

system-ui 폰트

system-ui 제네릭 폰트 패밀리를 사용하면 장치의 네이티브 UI 폰트를 사용하여 운영 체제와 더 통합된 느낌을 주는 인터페이스를 만들 수 있습니다. 이는 각 플랫폼마다 다른 폰트 스택을 지정하지 않고도 더 네이티브한 모양과 느낌을 제공합니다.

css
.native-interface {
  /* 시스템의 기본 UI 폰트 사용 */
  font-family: system-ui;
}

.fallback-aware {
  /* 명시적 폴백이 있는 시스템 UI 폰트 */
  font-family: system-ui, sans-serif;
}

system-ui 를 지원하지 않는 브라우저의 경우, Bun 의 CSS 번들러는 포괄적인 크로스 플랫폼 폰트 스택으로 자동 확장합니다:

css
.native-interface {
  /* 모든 주요 플랫폼을 지원하도록 확장 */
  font-family:
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    Roboto,
    "Noto Sans",
    Ubuntu,
    Cantarell,
    "Helvetica Neue";
}

.fallback-aware {
  /* 확장된 스택 뒤에 원래 폴백 유지 */
  font-family:
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    Roboto,
    "Noto Sans",
    Ubuntu,
    Cantarell,
    "Helvetica Neue",
    sans-serif;
}

이 접근 방식을 사용하면 소스 코드에서 단순히 system-ui 만 작성하는 간편함을 누리면서도 인터페이스가 모든 운영 체제 및 브라우저에 올바르게 적응하도록 할 수 있습니다. 확장된 폰트 스택에는 macOS/iOS, Windows, Android, Linux 에 대한 적절한 시스템 폰트와 이전 브라우저를 위한 폴백이 포함됩니다.

CSS 모듈

Bun 의 번들러는 일반 CSS 외에도 다음 기능을 지원하는 CSS 모듈 번들링을 지원합니다:

  • 설정 없이 CSS 모듈 파일 (.module.css) 자동 감지
  • 컴포지션 (composes 속성)
  • CSS 모듈을 JSX/TSX 로 가져오기
  • CSS 모듈의 잘못된 사용에 대한 경고/오류

CSS 모듈은 모든 클래스 이름과 애니메이션이 파일 범위로 지정되는 CSS 파일 (.module.css 확장자) 입니다. CSS 선언이 기본적으로 전역 범위로 지정되기 때문에 클래스 이름 충돌을 피하는 데 도움이 됩니다.

내부적으로 Bun 의 번들러는 로컬로 범위가 지정된 클래스 이름을 고유한 식별자로 변환합니다.

시작하기

.module.css 확장자를 가진 CSS 파일을 만듭니다:

css
.button {
  color: red;
}
css
.button {
  color: blue;
}

그런 다음 이 파일을 TSX 파일 등으로 가져올 수 있습니다:

tsx
import styles from "./styles.module.css";
import otherStyles from "./other-styles.module.css";

export default function App() {
  return (
    <>
      <button className={styles.button}>빨간 버튼!</button>
      <button className={otherStyles.button}>파란 버튼!</button>
    </>
  );
}

CSS 모듈 파일을 가져오면 스타일 객체는 모든 클래스 이름을 키로, 고유한 식별자를 값으로 가진 객체가 됩니다:

ts
import styles from "./styles.module.css";
import otherStyles from "./other-styles.module.css";

console.log(styles);
console.log(otherStyles);

출력은 다음과 같습니다:

ts
{
  button: "button_123";
}

{
  button: "button_456";
}

보시다시피 클래스 이름은 파일마다 고유하여 충돌을 피합니다!

컴포지션

CSS 모듈을 사용하면 클래스 선택자를 함께 컴포즈할 수 있습니다. 이를 통해 여러 클래스에서 스타일 규칙을 재사용할 수 있습니다.

예를 들어:

css
.button {
  composes: background;
  color: red;
}

.background {
  background-color: blue;
}

는 다음과 같이 작성하는 것과 동일합니다:

css
.button {
  background-color: blue;
  color: red;
}

.background {
  background-color: blue;
}

composes 를 사용할 때 기억해야 할 몇 가지 규칙이 있습니다:

css
#button {
  // 무효! `#button` 은 클래스 선택자가 아닙니다
  composes: background;
}

.button,
.button-secondary {
  // 무효! `.button, .button-secondary` 는 간단한 선택자가 아닙니다
  composes: background;
}

별도 CSS 모듈 파일에서 컴포즈

별도 CSS 모듈 파일에서 컴포즈할 수도 있습니다:

css
.background {
  background-color: blue;
}
css
.button {
  composes: background from "./background.module.css";
  color: red;
}

Bun by www.bunjs.com.cn 편집