Mantine PostCSS preset

Mantine PostCSS preset

postcss-preset-mantine은 스타일 작성에 도움이 되는 여러 CSS 함수와 믹스인을 제공해요. 꼭 사용해야 하는 것은 아니지만 강력히 권장돼요. 스타일이 들어간 모든 데모는 이 preset이 설치되어 있다고 가정해요.

postcss-preset-mantine은 다음 PostCSS 플러그인을 포함해요:

  • postcss-nested

  • Mantine 전용 믹스인을 가진 postcss-mixins

  • em/rem 함수를 가진 커스텀 플러그인

출처: 문서

본문

설치

postcss-preset-mantine을 dev dependency로 설치해요:

yarn add --dev postcss-preset-mantine

사용법

PostCSS 설정은 빌드 도구/프레임워크에 따라 다를 수 있다는 점에 주의하세요. 자세한 내용은 전용 프레임워크 가이드를 확인하세요. postcss.config.cjs 파일(보통 프로젝트 루트에 위치)에 postcss-preset-mantine을 추가해요:

module.exports = {
  plugins: {
    'postcss-preset-mantine': {},
  },
};

완료! 이제 preset의 모든 기능을 사용할 수 있어요.

rem/em 함수

rem과 em 함수는 픽셀을 rem/em 단위로 변환하는 데 사용할 수 있어요. 16px = 1rem, 16px = 1em이에요. em 값은 미디어 쿼리에서, rem은 그 외의 곳에서 사용하도록 되어 있어요. 단위 변환에 대해 더 자세히 알고 싶으면 이 가이드를 확인하세요.

.demo {
  font-size: rem(16px);

  @media (min-width: em(320px)) {
    font-size: rem(32px);
  }
}

다음으로 변환돼요:

.demo {
  font-size: calc(1rem * var(--mantine-scale));

  @media (min-width: 20em) {
    font-size: calc(2rem * var(--mantine-scale));
  }
}

px를 rem으로 자동 변환

autoRem 옵션을 사용하면 .css 파일의 모든 픽셀 값을 rem 단위로 자동 변환할 수 있어요:

module.exports = {
  plugins: {
    'postcss-preset-mantine': {
      autoRem: true,
    },
  },
};

이 옵션은 rem 함수와 비슷하게 동작해요. 다음 코드는:

.demo {
  font-size: 16px;

  @media (min-width: 320px) {
    font-size: 32px;
  }
}

다음으로 변환돼요:

.demo {
  font-size: calc(1rem * var(--mantine-scale));

  @media (min-width: 320px) {
    font-size: calc(2rem * var(--mantine-scale));
  }
}

autoRem은 CSS 속성만 변환하고 @media 쿼리의 값은 자동으로 변환되지 않는다는 점에 주의하세요 – 변환하려면 여전히 em 함수를 사용해야 해요.

autoRem 옵션은 다음 경우에는 값을 변환하지 않아요:

  • calc(), var(), clamp(), url() 함수 안의 값

  • content 속성의 값

  • rgb(), rgba(), hsl(), hsla() 색상을 포함하는 값

위 값들을 rem 단위로 변환하려면 rem 함수를 수동으로 사용해야 해요.

dark와 light 믹스인

dark와 light 믹스인은 dark 또는 light 색상 체계에서만 적용되는 스타일을 만드는 데 사용할 수 있어요.

.demo {
  @mixin light {
    color: red;
  }

  @mixin dark {
    color: blue;
  }
}

다음으로 변환돼요:

[data-mantine-color-scheme='light'] .demo {
  color: red;
}

[data-mantine-color-scheme='dark'] .demo {
  color: blue;
}

보통 light와 dark 믹스인을 동시에 사용할 필요는 없어요. light 색상 체계의 스타일을 정의한 다음 dark 믹스인으로 dark 색상 체계에서 이를 재정의하는 것이 더 쉬워요.

.demo {
  // Value for light color scheme
  color: red;

  @mixin dark {
    // Value for dark color scheme
    color: blue;
  }
}

:root/html 요소에서 light/dark 색상 체계의 값을 정의하려면 light-root와 dark-root 믹스인을 대신 사용해요:

:root {
  @mixin light-root {
    --color: red;
  }

  @mixin dark-root {
    --color: blue;
  }
}

smaller-than과 larger-than 믹스인

smaller-than과 larger-than 믹스인은 화면이 지정된 breakpoint보다 작거나 클 때만 적용되는 스타일을 만드는 데 사용할 수 있어요.

.demo {
  @mixin smaller-than 320px {
    color: red;
  }

  @mixin larger-than 320px {
    color: blue;
  }
}

다음으로 변환돼요:

// Breakpoint values are converted to em units
// In smaller-than mixin 0.1px is subtracted from breakpoint value
// to avoid intersection with larger-than mixin
@media (max-width: 19.99375em) {
  .demo {
    color: red;
  }
}

@media (min-width: 20em) {
  .demo {
    color: blue;
  }
}

smaller-than과 larger-than 믹스인을 mantine breakpoints와 함께 사용할 수도 있어요:

.demo {
  @mixin smaller-than $mantine-breakpoint-sm {
    color: red;
  }

  @mixin larger-than $mantine-breakpoint-sm {
    color: blue;
  }
}

light-dark 함수

light-dark 함수는 light와 dark 믹스인의 대안이에요. 두 개의 인자를 받아요: 첫 번째 인자는 light 색상 체계에서 적용되는 규칙이고, 두 번째 인자는 dark 색상 체계에서 적용되는 규칙이에요.

.demo {
  color: light-dark(red, blue);
}

다음으로 변환돼요:

.demo {
  color: red;
}

[data-mantine-color-scheme='dark'] .demo {
  color: blue;
}

light-dark 함수는 :root/html 요소에서는 동작하지 않는다는 점에 주의하세요. light-root와 dark-root 믹스인을 대신 사용하세요:

// ❌ Does not work
:root {
  --color: light-dark(red, blue);
}

// ✅ Works
:root {
  @mixin light-root {
    --color: red;
  }

  @mixin dark-root {
    --color: blue;
  }
}

alpha 함수

alpha 함수는 색상에 alpha 채널을 추가하는 데 사용할 수 있어요. color-mix를 사용하며 일부 구형 브라우저에서는 지원되지 않는다는 점에 주의하세요.

.demo {
  color: alpha(var(--mantine-color-red-4), 0.5);
  border: 1px solid alpha(#ffc, 0.2);
}

다음으로 변환돼요:

.demo {
  color: color-mix(
    in srgb,
    var(--mantine-color-red-4),
    transparent 50%
  );
  border: 1px solid color-mix(in srgb, #ffc, transparent 80%);
}

lighten, darken 함수

lighten과 darken 함수는 alpha 함수와 비슷하게 동작하지만, alpha 채널을 추가하는 대신 color-mix로 색상에 흰색 또는 검은색을 추가해요.

.demo {
  color: lighten(var(--mantine-color-red-4), 0.5);
  border: 1px solid darken(#ffc, 0.2);
}

다음으로 변환돼요:

.demo {
  color: color-mix(in srgb, var(--mantine-color-red-4), white 50%);
  border: 1px solid color-mix(in srgb, #ffc, black 20%);
}

hover 믹스인

hover 믹스인은 hover 시 적용되는 스타일을 만드는 데 사용할 수 있어요.

.demo {
  @mixin hover {
    color: orange;
  }
}

다음으로 변환돼요:

@media (hover: hover) {
  .demo:hover {
    color: orange;
  }
}

@media (hover: none) {
  .demo:active {
    color: orange;
  }
}

rtl/ltr 믹스인

rtl 믹스인은 부모 요소(보통 ``)에 dir="rtl"이 설정되었을 때 적용되는 스타일을 만드는 데 사용할 수 있어요.

.demo {
  margin-left: 1rem;

  @mixin rtl {
    margin-left: 0;
    margin-right: 1rem;
  }
}

다음으로 변환돼요:

.demo {
  margin-left: 1rem;
}

[dir='rtl'] .demo {
  margin-left: 0;
  margin-right: 1rem;
}

ltr 믹스인은 dir="ltr"에 대해 같은 방식으로 동작해요:

.demo {
  margin-left: 1rem;

  @mixin ltr {
    margin-left: 0;
    margin-right: 1rem;
  }
}

다음으로 변환돼요:

.demo {
  margin-left: 1rem;
}

[dir='ltr'] .demo {
  margin-left: 0;
  margin-right: 1rem;
}

not-rtl/not-ltr 믹스인

not-rtl/not-ltr 믹스인은 방향이 반대 값으로 설정되거나 아예 설정되지 않았을 때 적용되는 스타일을 만드는 데 사용할 수 있어요. 예를 들어 not-rtl 스타일은 dir="ltr"일 때나 dir이 전혀 설정되지 않았을 때 적용돼요.

.demo {
  @mixin not-rtl {
    margin-right: 1rem;
  }
}

다음으로 변환돼요:

:root:not([dir='rtl']) .demo {
  margin-right: 1rem;
}

where-* 믹스인

where-* 믹스인은 light, dark, rtl, hover 믹스인의 대안이에요. 똑같이 동작하지만 생성되는 CSS의 특이성(specificity)이 낮아요. 이 믹스인들은 스타일을 쉽게 재정의하고 싶을 때 유용해요. 예를 들어 라이브러리나 확장을 만들 때요.

where-light 믹스인 사용 예시:

.demo {
  @mixin where-light {
    color: red;
  }
}

다음으로 변환돼요:

:where([data-mantine-color-scheme='light']) .demo {
  color: red;
}

커스텀 믹스인

preset에 포함되지 않은 커스텀 믹스인을 mixins 옵션에 지정해서 정의할 수 있어요. 믹스인 문법에 대해 알아보려면 postcss-mixins 문서를 참고하세요.

clearfix와 circle 믹스인을 추가하는 예시:

module.exports = {
  plugins: {
    'postcss-preset-mantine': {
      autoRem: true,
      mixins: {
        clearfix: {
          '&::after': {
            content: '""',
            display: 'table',
            clear: 'both',
          },
        },
        circle: (_mixin, size) => ({
          borderRadius: '50%',
          width: size,
          height: size,
        }),
      },
    },
    // ... Other plugins
  },
};

그러면 스타일에서 이 믹스인들을 사용할 수 있어요:

.demo {
  @mixin clearfix;
  @mixin circle 100px;
}

특정 기능 비활성화

preset의 특정 기능을 false로 설정해 비활성화할 수 있어요:

module.exports = {
  'postcss-preset-mantine': {
    features: {
      // Turn off `light-dark` function
      lightDarkFunction: false,

      // Turn off `postcss-nested` plugin
      nested: false,

      // Turn off `lighten`, `darken` and `alpha` functions
      colorMixAlpha: false,

      // Turn off `rem` and `em` functions
      remEmFunctions: false,

      // Turn off `postcss-mixins` plugin
      mixins: false,
    },
  },
};

더 알아보기 (Learn more)