CSS 함수로 스타일 반복 줄이기

웹 기능: @function

대규모 스타일시트를 유지관리하면 특히 그라데이션이나 반응형 레이아웃 패턴과 같은 디자인 시스템 토큰을 처리할 때 반복적인 로직이 발생하는 경우가 많습니다.

CSS @function at-rule을 사용하면 이 로직을 재사용 가능한 매개변수화된 함수로 캡슐화하여 CSS를 더 유지보수하기 쉽고 일관되며 DRY (Don't Repeat Yourself)하게 만들 수 있습니다.

@function 문법

맞춤 함수는 @function 규칙을 사용하여 정의되며, 그 뒤에 대시로 구분된 이름과 매개변수 목록이 옵니다. 이 함수는 result 속성을 사용하여 값을 반환합니다.

@function --my-function(--input1 <length>, --input2: default-value) returns <length> {
  /* Logic goes here */
  result: var(--input1);
}

주요 개념

  • 매개변수: 이중 대시 (--)로 시작해야 합니다.
  • 기본값: 콜론 (:)을 사용하여 기본값을 제공할 수 있습니다.
  • 결과: result 속성은 함수가 반환하는 값을 결정합니다. 함수 본문에 선언된 마지막 result가 우선 적용됩니다.
  • 범위 지정: 함수 내에 정의된 매개변수와 변수는 로컬 범위로 지정됩니다.
  • 유형: 매개변수와 반환된 값이 대괄호 표기법 (예: <color>)을 사용하여 CSS 유형과 일치하도록 요구하고 type 함수 (예: type(<number> | <percentage>))를 사용하여 여러 유형을 허용할 수 있습니다.

실제 사례

1. 디자인 시스템 토큰 (그라데이션)

그라데이션 로직을 캡슐화하여 앱 전체에서 일관된 색상 그라데이션을 보장합니다. --angle는 재정의할 수 있는 일관성을 제공하기 위해 기본값을 제공합니다.

@function --fancy-gradient(--start-color <color>, --end-color <color>, --angle: 98deg) returns <image>{
  result: linear-gradient(in oklab var(--angle), var(--start-color), var(--end-color) );
}

.card {
  background: --fancy-gradient(#ed73d7, #5d87e9);
}

2. 조건부 레이아웃 로직

@media 또는 기타 쿼리를 함수 내에서 직접 사용하여 환경에 따라 다른 값을 반환할 수 있습니다. 함수에서 조건부 로직을 사용할 때 @function는 result의 첫 번째 값에서 '반환'되지 않고 CSS 계단식 구조를 따르며 화면 크기, 컨테이너 크기 또는 기타 쿼리를 기반으로 일치하는 마지막 값으로 확인됩니다.

@function --grid-template(--count <number>){
  /* MANDATORY: Put default value first. */
  result: 1fr; /* Default: stack */
  @media (min-width: 800px) {
    result: repeat(var(--count), 1fr); /* Grid on larger screens */
  }
}

main {
  display: grid;
  grid-template-columns: --grid-template(2);
}

권장사항

  • 대시 이름 사용: 항상 함수 이름과 파라미터 앞에 --를 붙입니다.
  • 기본값 제공: 적절한 기본값을 제공하여 함수를 더 강력하게 만듭니다.
  • 간단하게 유지: 실제로 반복되거나 복잡한 로직에 함수를 사용합니다. 간단한 속성-값 쌍을 과도하게 설계하지 마세요.
  • 유형 사용: 매개변수와 반환 값이 예상 유형인지 확인합니다.
  • 사전 컴파일된 대안 고려: 사용자 입력, 미디어 쿼리 또는 기타 클라이언트 측 변형에 의존하지 않는 함수의 경우 CSS 사전 컴파일러를 사용하여 클라이언트에서 불필요한 작업을 수행하지 않도록 합니다.

대체 전략

CSS 함수를 지원하지 않는 브라우저에서는 CSS 함수를 사용하여 설정된 값이 유효하지 않습니다. 다른 브라우저를 지원하려면 먼저 속성의 대체 값을 제공하세요. CSS 함수를 지원하는 브라우저에서는 이 값이 재정의됩니다.

.card {
  /* Provide fallback, in this case a solid color. */
  background: #5d87e9;
  background: --fancy-gradient(#ed73d7, #5d87e9);
}

main {
  /* Provide fallback, in this case a simple stacked default. */
  grid-template-columns: 1fr;
  grid-template-columns: --grid-template(2);
}

다른 브라우저를 지원하면서 스타일 반복을 줄여야 하는 경우 Sass와 같은 함수가 있는 CSS 사전 컴파일러를 고려하세요.