본문 바로가기
CSS

css variables? css 변수 사용하기

by F.E.D 2021. 1. 11.

css variables 사용에 대해서 어떻게 생각하시나요?

 

오랫동안 요청되었지만 여전히 많이 사용되지 않는 계단식 변수에 대한 CSS 맞춤 속성은 협업 및 코드 재사용을위한 혁신적인 가능성을 제공합니다. 

 

그러나 오늘날 CSS 변수는 제대로 이해되지 않고 있습니다. 

이 글을 읽은 후 선언적 CSS 변수와 다른 프로그래밍 언어의 변수 간의 차이점과 그 기능을 활용하는 방법을 더 잘 이해하기를 바랍니다.

 

CSS 변수는 계단식으로 연결되고 상속되는 사용자 지정 속성입니다. -접두사로 시작하며 값에 대한 실제 규칙이 없습니다.

선언시 느슨하게 구문 분석되지만 사용자 지정이 아닌 속성에서 사용될 때까지 오류 처리가 수행되지 않습니다.

해당 값은 모든 CSS 속성에서 사용할 수있는 var (-name) 함수를 통해 참조됩니다.

var () 함수는 두 번째 인수 (변수가 설정되지 않은 경우 대체)도 지원합니다.

 

CSS 변수는 현재 전 세계 사용자의 93%에 대해 지원됩니다. 브라우저가 CSS 변수를 지원하지 않으면 var () 함수도 이해하지 못하며 두 번째 인수가 의미하는 바를 알지 못합니다.

대신 모든 새로운 CSS 기능에서 사용하는 것처럼 캐스케이드를 사용해야합니다. 다음 예를 살펴보세요.

background: red;
background: var(--accent-color, orange);

브라우저와 --accent-color 값에 따라 네 가지 가능한 결과가 있습니다. 

첫째, 브라우저가 CSS 변수를 지원하지 않는 경우 두 번째 줄을 무시하고 빨간색 배경을 적용합니다.

둘째, 브라우저가 CSS 변수를 지원하고 --accent-color가 설정된 경우 해당 색상이 배경이됩니다.

셋째, 브라우저가 CSS 변수를 지원하고 --accent-color가 설정되지 않은 경우 주황색이 사용됩니다. 이는 var () 폴백입니다.

넷째, 브라우저가 CSS 변수를 지원하고 --accent-color가 설정되었지만 속성에 대해 무의미한 값 (예 : 42deg)으로 설정된 경우 배경이 투명 해집니다.

 

background: red;
background: 42deg;

위와 같이 브라우저가 무시할 수 있도록 명시적으로 작성되어있으면 브라우저가 무시할 수 있습니다.

변수없이 42deg를 포함하는 코드 스니펫에서 브라우저는 구문 분석시 이를 버립니다.

그러나 변수를 사용하면 브라우저는 나중에까지 선언이 유효한지 여부를 알 수 없습니다.

그때까지 다른 모든 계단식 값을 버리고 (계산 된 값을 하나만 보유하므로) 초기 값 (이 경우에는 투명 함)으로 되돌립니다.

 

이전 브라우저의 대체 값은 간단한 사용 사례에서 작동하지만 CSS 기능 쿼리 (@supports 규칙)는 완전히 다른 CSS를 제공 할 수 있습니다. CSS 변수를 지원하지 않는 브라우저에서는 빨간색 배경을, 지원하는 브라우저에서는 녹색 배경을 설정하는 다음 예를 고려해보세요.

html { background: red; }

@supports (--css: variables) {
    html { background: green; }
}

CSS 전처리기는 기본적으로 한 번 실행되는 프로그램입니다.

정적 CSS 코드를 생성하여 전송하기 때문입니다.

명령형 프로그래밍 언어 변수와 유사하게 동작하며 실행 과정에서 어휘 범위 및 여러 값을 사용합니다.

선택기, 조건부, 속성, 값 등 스타일 시트의 모든 위치에서 사용할 수 있으며 값 또는 선택기의 일부만 생성 할 수도 있습니다.

반대로 CSS 변수는 값 및 전체 토큰에만 사용할 수 있습니다.

그들은 반응적이며 페이지의 전체 기간 동안 라이브 상태로 유지됩니다.

요소별로 동적 범위 지정을 사용하며 주어진 모든 상태에 대해 하나의 값만 있으므로 명령형 계산의 일부가 될 수 없습니다.

CSS 변수가 외부에서 설정되는 경우 (예 : HTML 또는 자바 스크립트를 통해) 길이나 비율과 같은 CSS 값이 아닌 순수한 데이터에 사용하세요.

 

전처리기의 변수 범위는 중첩된 중괄호 블록으로 압축됩니다.

그러나 CSS 변수는 속성이기 때문에 범위 지정은 DOM 기반입니다.

즉, CSS 변수는 범위가 아닌 요소별로 확인되며 일반 속성처럼 상속됩니다.

다음 CSS 변수의 예를 살펴보세요.

body {
    --shadow-color: gray;
}

button {
    box-shadow: .1em .1em .1em var(--shadow-color);
}

button:hover {
    --shadow-color: skyblue;
}

마우스를 오버하면 버튼의 회색 그림자가 하늘색이됩니다. 

이를 전처리기 언어 Sass로 변환 해 보겠습니다.

body {
    $shadow-color: gray;
}

button {
    box-shadow: .1em .1em .1em $shadow-color;
}

button:hover {
    $shadow-color: skyblue;
}

결과는 "6 행에 정의되지 않은 변수"라는 구문 오류입니다. 

Sass는 그것이 내부에 있는지 또는 button:hover도 버튼이라는 것을 모릅니다.

 

전처리기 변수와의 가장 중요한 차이점은 CSS 변수가 반응적이라는 것입니다.

페이지의 수명 내내 활성 상태로 유지되며 업데이트하면 이를 참조하는 모든 관계가 업데이트됩니다.

그런 의미에서 기존 프로그래밍 또는 전처리기 언어의 변수보다 Angular, Mavo, Vue와 같은 반응형 프레임워크의 속성과 더 유사합니다. 속성이기 때문에 CSS 속성을 업데이트하는 모든 메커니즘 (스타일 시트, 인라인 스타일, 자바 스크립트 포함)을 통해 업데이트 할 수 있습니다.

 

scss

.foo {
  $i: 1;
  z-index: $i;
  $i: $i + 1;
  z-index: $i;
}

 

variable

.foo {
  --i: 1;
  z-index: var(--i);
  --i: calc(var(--i) + 1);
  z-index: var(--i);
}

 

자바스크립트를 통한 변환도 자연스럽습니다.

var root = document.documentElement;

document.addEventListener("mousemove", evt => {
    let x = evt.clientX / innerWidth;
    let y = evt.clientY / innerHeight;

    root.style.setProperty("--mouse-x", x);
    root.style.setProperty("--mouse-y", y);
});

 

html {
    min-height: 100vh;
    --center: calc(100% * var(--mouse-x, .5)) calc(100% * var(--mouse-y, .5));
    background: radial-gradient(circle at var(--center), yellowgreen, transparent 3%),
        conic-gradient(at var(--center), yellowgreen, green, yellowgreen);
}

css 를 통한 수정도 쉬운편 입니다.

 

또한 CSS 변수는 캡슐화를 가능하게하므로 CSS 코드를 재사용하고 사용자 정의 할 수 있습니다.

.flat 클래스에 적용된 플랫 버튼 스타일을 만들었다고 가정해 보겠습니다.

button.flat {
    border: .1em solid black;
    background: transparent;
    color: black;
}

button.flat:hover {
    background: black;
    color: white;
}

위험 표시는 다음과 같다고 하죠

button.flat.danger {
    border-color: red;
    color: red;
}

button.flat.danger:hover {
    background: red;
    color: white;
}

왠지 중복 같죠?

 

중복을 방지하기 위해 색상을 변수로 교체해 보겠습니다.

button.flat {
    --color-initial: black;
    border: .1em solid var(--color, var(--color-initial));
    background: transparent;
    color: var(--color, var(--color-initial));
    transition: 1s;
}

button.flat:hover {
    box-shadow: 0 0 0 1em var(--color, var(--color-initial)) inset;
    color: white;
}

root를 통하여 변수 최상단의 기본값들을 설정할 수 있습니다.

:root {
    --base-color-hs: 335, 100%;
    --base-color: hsl(var(--base-color-hs), 50%);
    --base-color-light: hsl(var(--base-color-hs), 85%);
    --base-color-dark: hsl(var(--base-color-hs), 20%);
    --base-color-translucent: hsla(var(--base-color-hs), 50%, .5);
}

방해되는 상속을 제거할 수도 있습니다.

* {
    box-shadow: 0 0 .3em var(--subtle-glow) gold;
}

p {
    font: 200%/1 sans-serif;
    --subtle-glow: .05em;
}

위 같은 문제를 해결하려면 첫 번째 규칙에 --subtle-glow : initial을 추가하여 상속을 비활성화해야합니다.

직접 적용은 항상 상속된 규칙보다 우선하기 때문에 상속된 값을 재정의하지만

*의 낮은 특이성으로인해 요소에 지정된 모든 항목에 적용됩니다.

 

사용자 지정 속성은 CSS에 대한 강력하고 잘 지원되는 추가 기능이며 그 진정한 잠재력은 아직 완전히 탐구되지 않았습니다. 

 

 

출처 : increment.com/frontend/a-users-guide-to-css-variables/

댓글