CSS 사용자 정의 속성 사용을 시작할 때입니다.

게시 됨: 2022-03-10
빠른 요약 ↬ 오늘날 CSS 전처리기는 웹 개발의 표준입니다. 전처리기의 주요 장점 중 하나는 변수를 사용할 수 있다는 것입니다. 이렇게 하면 코드 복사 및 붙여넣기를 방지할 수 있으며 개발 및 리팩토링이 간소화됩니다.

전처리기를 사용하여 색상, 글꼴 기본 설정, 레이아웃 세부 정보를 저장합니다. 대부분 CSS에서 사용하는 모든 것입니다.

사용자 정의 요소에 대한 자세한 소개

웹 구성 요소와 웹 구성 요소가 웹 개발을 어떻게 변화시킬지에 대해 들어본 적이 있을 것입니다. 의 가장 혁신적인 기술은 고유한 동작 및 속성을 사용하여 고유한 요소를 정의하는 방법인 Custom Elements입니다. 소개 읽기 →

그러나 전처리기 변수에는 몇 가지 제한 사항이 있습니다.

  • 동적으로 변경할 수 없습니다.
  • 그들은 DOM의 구조를 알지 못합니다.
  • JavaScript에서 읽거나 변경할 수 없습니다.

이러한 문제 및 기타 문제에 대한 은총알로 커뮤니티는 CSS 사용자 지정 속성을 발명했습니다. 기본적으로 이들은 CSS 변수처럼 보이고 작동하며 작동 방식은 이름에 반영됩니다.

사용자 정의 속성은 웹 개발의 새로운 지평을 열고 있습니다.

점프 후 더! 아래에서 계속 읽기 ↓

사용자 정의 속성을 선언하고 사용하는 구문

새로운 전처리기나 프레임워크로 시작할 때 일반적인 문제는 새로운 구문을 배워야 한다는 것입니다.

각 전처리기는 변수를 선언하는 다른 방법이 필요합니다. 일반적으로 예약된 기호로 시작합니다(예: Sass의 $ 및 LESS의 @ ).

CSS 사용자 정의 속성은 동일한 방식으로 진행되었으며 선언을 도입하기 위해 -​- 를 사용합니다. 하지만 여기서 좋은 점은 이 구문을 한 번만 배우고 여러 브라우저에서 재사용할 수 있다는 것입니다!

"기존 구문을 재사용하지 않는 이유는 무엇입니까?"라고 물을 수 있습니다.

이유가있다. 간단히 말해서 모든 전처리기에서 사용자 정의 속성을 사용할 수 있는 방법을 제공하는 것입니다. 이런 식으로 사용자 정의 속성을 제공하고 사용할 수 있으며 전처리기가 이를 컴파일하지 않으므로 속성이 출력된 CSS로 직접 이동합니다. 그리고 , 네이티브 변수에서 전처리기 변수를 재사용할 수 있지만 나중에 설명하겠습니다.

(이름에 관하여: 그들의 아이디어와 목적이 매우 유사하기 때문에 정확한 이름은 CSS 사용자 정의 속성이지만 사용자 정의 속성을 CSS 변수라고 하는 경우가 있으며 더 읽으면 왜 이 이름이 가장 잘 설명되는지 이해할 수 있을 것입니다.)

따라서 color 또는 padding 과 같은 일반적인 CSS 속성 대신 변수를 선언하려면 -​- 로 시작하는 사용자 지정 이름 속성을 제공하기만 하면 됩니다.

 .box{ --box-color: #4d4e53; --box-padding: 0 10px; }

속성 값은 색상, 문자열, 레이아웃 값, 심지어 표현식과 같은 유효한 CSS 값일 수 있습니다.

다음은 유효한 사용자 정의 속성의 예입니다.

 :root{ --main-color: #4d4e53; --main-bg: rgb(255, 255, 255); --logo-border-color: rebeccapurple; --header-height: 68px; --content-padding: 10px 20px; --base-line-height: 1.428571429; --transition-duration: .35s; --external-link: "external link"; --margin-top: calc(2vh + 20px); /* Valid CSS custom properties can be reused later in, say, JavaScript. */ --foo: if(x > 5) this.width = 10; }

:root 가 무엇과 일치하는지 확실하지 않은 경우 HTML에서 html 과 동일하지만 더 높은 특이성을 가집니다.

다른 CSS 속성과 마찬가지로 사용자 정의 속성은 동일한 방식으로 계단식으로 배열되며 동적입니다. 즉, 언제든지 변경할 수 있으며 변경 사항은 브라우저에서 그에 따라 처리됩니다.

변수를 사용하려면 var() CSS 함수를 사용하고 내부에 속성 이름을 제공해야 합니다.

 .box{ --box-color:#4d4e53; --box-padding: 0 10px; padding: var(--box-padding); } .box div{ color: var(--box-color); }

선언 및 사용 사례

var() 함수는 기본값을 제공하는 편리한 방법입니다. 사용자 정의 속성이 정의되었는지 여부가 확실하지 않고 폴백으로 사용할 값을 제공하려는 경우 이 작업을 수행할 수 있습니다. 이것은 두 번째 매개변수를 함수에 전달하여 쉽게 수행할 수 있습니다.

 .box{ --box-color:#4d4e53; --box-padding: 0 10px; /* 10px is used because --box-margin is not defined. */ margin: var(--box-margin, 10px); }

예상대로 다른 변수를 재사용하여 새 변수를 선언할 수 있습니다.

 .box{ /* The --main-padding variable is used if --box-padding is not defined. */ padding: var(--box-padding, var(--main-padding)); --box-text: 'This is my box'; /* Equal to --box-highlight-text:'This is my box with highlight'; */ --box-highlight-text: var(--box-text)' with highlight'; }

연산: +, -, *, /

전처리기와 다른 언어에 익숙해지면서 변수로 작업할 때 기본 연산자를 사용할 수 있기를 원합니다. 이를 위해 CSS는 사용자 정의 속성 값이 변경된 후 브라우저가 표현식을 다시 계산하도록 하는 calc() 함수를 제공합니다.

 :root{ --indent-size: 10px; --indent-xl: calc(2*var(--indent-size)); --indent-l: calc(var(--indent-size) + 2px); --indent-s: calc(var(--indent-size) - 2px); --indent-xs: calc(var(--indent-size)/2); }

단위가 없는 값을 사용하려고 하면 문제가 기다립니다. 다시 말하지만, calc() 는 당신의 친구입니다. 그것 없이는 작동하지 않기 때문입니다:

 :root{ --spacer: 10; } .box{ padding: var(--spacer)px 0; /* DOESN'T work */ padding: calc(var(--spacer)*1px) 0; /* WORKS */ }

범위 및 상속

CSS 사용자 정의 속성 범위에 대해 이야기하기 전에 차이점을 더 잘 이해하기 위해 JavaScript와 전처리기 범위를 다시 살펴보겠습니다.

예를 들어 JavaScript 변수( var )의 경우 범위가 함수로 제한된다는 것을 알고 있습니다.

letconst 와 비슷한 상황이 있지만 블록 범위 지역 변수입니다.

JavaScript의 closure 는 외부(외부) 함수의 변수인 범위 체인에 액세스할 수 있는 함수입니다. 클로저에는 세 가지 범위 체인이 있으며 다음에 액세스할 수 있습니다.

  • 자체 범위(즉, 중괄호 사이에 정의된 변수),
  • 외부 함수의 변수,
  • 전역 변수.

(큰 버전 보기)

전처리기의 경우도 비슷합니다. 오늘날 가장 인기 있는 전처리기이기 때문에 Sass를 예로 들어 보겠습니다.

Sass에는 지역 및 전역의 두 가지 유형의 변수가 있습니다.

전역 변수는 선택기 또는 구성 외부에서 선언할 수 있습니다(예: mixin). 그렇지 않으면 변수는 로컬이 됩니다.

모든 중첩 코드 블록은 바깥쪽 변수에 액세스할 수 있습니다(JavaScript에서와 같이).

(큰 버전 보기)

이것은 Sass에서 변수의 범위가 코드의 구조에 완전히 의존한다는 것을 의미합니다.

그러나 CSS 사용자 정의 속성은 기본적으로 상속되며 다른 CSS 속성과 마찬가지로 계단식으로 적용됩니다.

또한 선택기 외부에서 사용자 정의 속성을 선언하는 전역 변수를 가질 수 없습니다. 이는 유효한 CSS가 아닙니다. CSS 사용자 정의 속성의 전역 범위는 실제로 :root 범위이므로 속성을 전역적으로 사용할 수 있습니다.

구문 지식을 사용하고 Sass 예제를 HTML 및 CSS에 적용해 보겠습니다. 네이티브 CSS 사용자 정의 속성을 사용하여 데모를 만들 것입니다. 먼저 HTML:

 global <div class="enclosing"> enclosing <div class="closure"> closure </div> </div>

CSS는 다음과 같습니다.

 :root { --globalVar: 10px; } .enclosing { --enclosingVar: 20px; } .enclosing .closure { --closureVar: 30px; font-size: calc(var(--closureVar) + var(--enclosingVar) + var(--globalVar)); /* 60px for now */ } 

CodePen에서 Serg Hospodarets(@malyw)의 Pen css-custom-properties-time-to-start-using 1을 참조하십시오.

CodePen에서 Serg Hospodarets(@malyw)의 Pen css-custom-properties-time-to-start-using 1을 참조하십시오.

사용자 정의 속성에 대한 변경 사항은 모든 인스턴스에 즉시 적용됩니다.

지금까지 이것이 Sass 변수와 어떻게 다른지 보지 못했습니다. 그러나 사용 후 변수를 다시 할당해 보겠습니다.

Sass의 경우 이것은 효과가 없습니다.

 .closure { $closureVar: 30px; // local variable font-size: $closureVar +$enclosingVar+ $globalVar; // 60px, $closureVar: 30px is used $closureVar: 50px; // local variable } 

CodePen에서 Serg Hospodarets(@malyw)의 Pen css-custom-properties-time-to-start-using 3을 참조하십시오.

CodePen에서 Serg Hospodarets(@malyw)의 Pen css-custom-properties-time-to-start-using 3을 참조하십시오.

그러나 CSS에서는 변경된 –closureVar 값에서 font-size 값이 다시 계산되기 때문에 계산된 값이 변경됩니다.

 .enclosing .closure { --closureVar: 30px; font-size: calc(var(--closureVar) + var(--enclosingVar) + var(--globalVar)); /* 80px for now, --closureVar: 50px is used */ --closureVar: 50px; } 

CodePen에서 Serg Hospodarets(@malyw)의 Pen css-custom-properties-time-to-start-using 2를 참조하십시오.

CodePen에서 Serg Hospodarets(@malyw)의 Pen css-custom-properties-time-to-start-using 2를 참조하십시오.

이것이 첫 번째 큰 차이점입니다. 사용자 정의 속성 값을 재할당하면 브라우저는 적용되는 모든 변수와 calc() 표현식 을 다시 계산합니다.

전처리기는 DOM의 구조를 인식하지 못합니다

highlighted 클래스가 있는 경우를 제외하고 블록에 대한 기본 font-size 를 사용하려고 한다고 가정합니다.

HTML은 다음과 같습니다.

 <div class="default"> default </div> <div class="default highlighted"> default highlighted </div>

CSS 사용자 정의 속성을 사용하여 이 작업을 수행해 보겠습니다.

 .highlighted { --highlighted-size: 30px; } .default { --default-size: 10px; /* Use default-size, except when highlighted-size is provided. */ font-size: var(--highlighted-size, var(--default-size)); }

default 클래스가 있는 두 번째 HTML 요소는 highlighted 표시된 클래스를 전달하므로 highlighted 클래스의 속성이 해당 요소에 적용됩니다.

이 경우 –highlighted-size: 30px; 그러면 할당되는 font-size 속성이 –highlighted-size 사용하게 됩니다.

모든 것이 간단하고 작동합니다.

CodePen에서 Serg Hospodarets(@malyw)의 Pen css-custom-properties-time-to-start-using 4를 참조하십시오.

CodePen에서 Serg Hospodarets(@malyw)의 Pen css-custom-properties-time-to-start-using 4를 참조하십시오.

이제 Sass를 사용하여 동일한 작업을 수행해 보겠습니다.

 .highlighted { $highlighted-size: 30px; } .default { $default-size: 10px; /* Use default-size, except when highlighted-size is provided. */ @if variable-exists(highlighted-size) { font-size: $highlighted-size; } @else { font-size: $default-size; } }

결과는 기본 크기가 다음 두 가지 모두에 적용됨을 보여줍니다.

CodePen에서 Serg Hospodarets(@malyw)의 Pen css-custom-properties-time-to-start-using 5를 참조하십시오.

CodePen에서 Serg Hospodarets(@malyw)의 Pen css-custom-properties-time-to-start-using 5를 참조하십시오.

이것은 모든 Sass 계산 및 처리가 컴파일 시간에 발생하기 때문에 발생하며 물론 코드 구조에 완전히 의존하여 DOM 구조에 대해 전혀 알지 못합니다.

보시다시피 사용자 정의 속성은 변수 범위 지정의 이점이 있으며 DOM의 구조를 인식하고 다른 CSS 속성과 동일한 규칙을 따르는 CSS 속성의 일반적인 계단식을 추가합니다.

두 번째 시사점은 CSS 사용자 정의 속성이 DOM의 구조를 인식하고 동적이라는 것 입니다.

CSS 전체 키워드 및 all 속성

CSS 사용자 정의 속성은 일반적인 CSS 사용자 정의 속성과 동일한 규칙을 따릅니다. 즉, 일반적인 CSS 키워드를 할당할 수 있습니다.

  • inherit
    이 CSS 키워드는 요소의 부모 값을 적용합니다.
  • initial
    이것은 CSS 사양에 정의된 초기 값을 적용합니다(빈 값 또는 CSS 사용자 정의 속성의 경우 아무 것도 없음).
  • unset
    속성이 정상적으로 상속되면(사용자 정의 속성의 경우와 같이) 상속된 값을 적용하고 속성이 일반적으로 상속되지 않는 경우 초기 값을 적용합니다.
  • revert
    이것은 속성을 사용자 에이전트의 스타일 시트에 의해 설정된 기본값으로 재설정합니다(CSS 사용자 정의 속성의 경우 빈 값).

다음은 예입니다.

 .common-values{ --border: inherit; --bgcolor: initial; --padding: unset; --animation: revert; }

다른 경우를 생각해보자. 구성 요소를 만들고 다른 스타일이나 사용자 정의 속성이 실수로 적용되지 않도록 하고 싶다고 가정해 보겠습니다(이 경우 일반적으로 모듈식 CSS 솔루션이 스타일에 사용됨).

하지만 이제 다른 방법이 있습니다. all CSS 속성을 사용하는 것입니다. 이 속기는 모든 CSS 속성을 재설정합니다.

CSS 키워드와 함께 다음을 수행할 수 있습니다.

 .my-wonderful-clean-component{ all: initial; }

이렇게 하면 구성 요소의 모든 스타일이 재설정됩니다.

불행히도 all 키워드는 사용자 정의 속성을 재설정하지 않습니다. 모든 CSS 사용자 정의 속성을 재설정하는 -​- 접두사를 추가할지 여부에 대한 논의가 진행 중입니다.

따라서 앞으로는 다음과 같이 전체 재설정을 수행할 수 있습니다.

 .my-wonderful-clean-component{ --: initial; /* reset all CSS custom properties */ all: initial; /* reset all other CSS styles */ }

CSS 사용자 정의 속성 사용 사례

사용자 정의 속성을 많이 사용합니다. 나는 그들 중 가장 흥미로운 것을 보여줄 것입니다.

존재하지 않는 CSS 규칙 에뮬레이션

이러한 CSS 변수의 이름은 "사용자 정의 속성"이므로 존재하지 않는 속성을 에뮬레이트하는 데 사용하지 않는 이유는 무엇입니까?

translateX/Y/Z , background-repeat-x/y (여전히 브라우저 간 호환되지 않음), box-shadow-color 있습니다.

마지막으로 작동하도록 합시다. 이 예에서는 마우스를 가져갈 때 상자 그림자의 색상을 변경해 보겠습니다. 우리는 DRY 규칙을 따르기를 원합니다(반복하지 마십시오). 따라서 :hover 섹션에서 box-shadow 의 전체 값을 반복하는 대신 색상만 변경할 것입니다. 구조를 위한 사용자 지정 속성:

 .test { --box-shadow-color: yellow; box-shadow: 0 0 30px var(--box-shadow-color); } .test:hover { --box-shadow-color: orange; /* Instead of: box-shadow: 0 0 30px orange; */ } 

CodePen에서 Serg Hospodarets(@malyw)의 CSS 사용자 정의 속성을 사용하여 펜 에뮬레이션 "box-shadow-color" CSS 속성을 참조하십시오.

CodePen에서 Serg Hospodarets(@malyw)의 CSS 사용자 정의 속성을 사용하여 펜 에뮬레이션 "box-shadow-color" CSS 속성을 참조하십시오.

색상 테마

사용자 정의 속성의 가장 일반적인 사용 사례 중 하나는 응용 프로그램의 색상 테마입니다. 사용자 지정 속성은 이러한 종류의 문제를 해결하기 위해 만들어졌습니다. 따라서 구성 요소에 대한 간단한 색상 테마를 제공하겠습니다(애플리케이션에 대해 동일한 단계를 따를 수 있음).

다음은 버튼 구성 요소에 대한 코드입니다.

 .btn { background-image: linear-gradient(to bottom, #3498db, #2980b9); text-shadow: 1px 1px 3px #777; box-shadow: 0px 1px 3px #777; border-radius: 28px; color: #ffffff; padding: 10px 20px 10px 20px; }

색상 테마를 반전한다고 가정해 보겠습니다.

첫 번째 단계는 모든 색상 변수를 CSS 사용자 정의 속성으로 확장하고 구성 요소를 다시 작성하는 것입니다. 따라서 결과는 동일합니다.

 .btn { --shadow-color: #777; --gradient-from-color: #3498db; --gradient-to-color: #2980b9; --color: #ffffff; background-image: linear-gradient( to bottom, var(--gradient-from-color), var(--gradient-to-color) ); text-shadow: 1px 1px 3px var(--shadow-color); box-shadow: 0px 1px 3px var(--shadow-color); border-radius: 28px; color: var(--color); padding: 10px 20px 10px 20px; }

이것은 우리에게 필요한 모든 것을 갖추고 있습니다. 이를 통해 색상 변수를 반전된 값으로 재정의하고 필요할 때 적용할 수 있습니다. 예를 들어 inverted HTML 클래스(예: body 요소)를 추가하고 적용될 때 색상을 변경할 수 있습니다.

 body.inverted .btn{ --shadow-color: #888888; --gradient-from-color: #CB6724; --gradient-to-color: #D67F46; --color: #000000; }

아래는 버튼을 클릭하여 전역 클래스를 추가 및 제거할 수 있는 데모입니다.

CodePen에서 Serg Hospodarets(@malyw)의 Pen css-custom-properties-time-to-start-using 9를 참조하십시오.

CodePen에서 Serg Hospodarets(@malyw)의 Pen css-custom-properties-time-to-start-using 9를 참조하십시오.

이 동작은 코드 복제의 오버헤드 없이 CSS 전처리기에서 달성할 수 없습니다. 전처리기를 사용하면 항상 실제 값과 규칙을 재정의해야 하므로 항상 CSS가 추가됩니다.

CSS 사용자 정의 속성을 사용하면 솔루션이 최대한 깨끗하고 변수 값만 재정의되기 때문에 복사 및 붙여넣기가 방지됩니다.

JavaScript에서 사용자 정의 속성 사용하기

이전에는 CSS에서 JavaScript로 데이터를 보내려면 CSS 출력에서 ​​일반 JSON을 통해 CSS 값을 작성한 다음 JavaScript에서 읽어야 하는 트릭에 의존해야 했습니다.

이제 일반적인 CSS 속성에 사용되는 잘 알려진 .getPropertyValue().setProperty() 메서드를 사용하여 JavaScript의 CSS 변수와 쉽게 상호 작용하고 읽고 쓸 수 있습니다.

 /** * Gives a CSS custom property value applied at the element * element {Element} * varName {String} without '--' * * For example: * readCssVar(document.querySelector('.box'), 'color'); */ function readCssVar(element, varName){ const elementStyles = getComputedStyle(element); return elementStyles.getPropertyValue(`--${varName}`).trim(); } /** * Writes a CSS custom property value at the element * element {Element} * varName {String} without '--' * * For example: * readCssVar(document.querySelector('.box'), 'color', 'white'); */ function writeCssVar(element, varName, value){ return element.style.setProperty(`--${varName}`, value); }

미디어 쿼리 값 목록이 있다고 가정해 보겠습니다.

 .breakpoints-data { --phone: 480px; --tablet: 800px; }

예를 들어 Window.matchMedia()와 같이 JavaScript에서만 재사용하기를 원하기 때문에 CSS에서 쉽게 가져올 수 있습니다.

 const breakpointsData = document.querySelector('.breakpoints-data'); // GET const phoneBreakpoint = getComputedStyle(breakpointsData) .getPropertyValue('--phone');

JavaScript에서 사용자 지정 속성을 할당하는 방법을 보여주기 위해 사용자 작업에 응답하는 대화형 3D CSS 큐브 데모를 만들었습니다.

별로 어렵지 않습니다. 간단한 배경을 추가한 다음 transform 속성에 대한 관련 값인 translateZ() , translateY() , rotateX()rotateY() 와 함께 5개의 큐브 면을 배치하기만 하면 됩니다.

올바른 관점을 제공하기 위해 페이지 래퍼에 다음을 추가했습니다.

 #world{ --translateZ:0; --rotateX:65; --rotateY:0; transform-style:preserve-3d; transform: translateZ(calc(var(--translateZ) * 1px)) rotateX(calc(var(--rotateX) * 1deg)) rotateY(calc(var(--rotateY) * 1deg)); }

누락된 유일한 것은 상호 작용입니다. 데모는 마우스가 움직일 때 X 및 Y 보기 각도( –rotateX–rotateY )를 변경해야 하고 마우스가 스크롤될 때 확대 및 축소해야 합니다( –translateZ ).

트릭을 수행하는 JavaScript는 다음과 같습니다.

 // Events onMouseMove(e) { this.worldXAngle = (.5 - (e.clientY / window.innerHeight)) * 180; this.worldYAngle = -(.5 - (e.clientX / window.innerWidth)) * 180; this.updateView(); }; onMouseWheel(e) { /*…*/ this.worldZ += delta * 5; this.updateView(); }; // JavaScript -> CSS updateView() { this.worldEl.style.setProperty('--translateZ', this.worldZ); this.worldEl.style.setProperty('--rotateX', this.worldXAngle); this.worldEl.style.setProperty('--rotateY', this.worldYAngle); };

이제 사용자가 마우스를 움직이면 데모가 보기를 변경합니다. 마우스를 움직이고 마우스 휠을 사용하여 확대 및 축소하여 이를 확인할 수 있습니다.

CodePen에서 Serg Hospodarets(@malyw)의 Pen css-custom-properties-time-to-start-using 10을 참조하십시오.

CodePen에서 Serg Hospodarets(@malyw)의 Pen css-custom-properties-time-to-start-using 10을 참조하십시오.

기본적으로 CSS 사용자 정의 속성 값을 변경했습니다. 다른 모든 것(회전 및 확대/축소)은 CSS에서 수행합니다.

팁: CSS 사용자 정의 속성 값을 디버그하는 가장 쉬운 방법 중 하나는 CSS 생성 콘텐츠(문자열과 같은 간단한 경우에 작동)에 콘텐츠를 표시하여 브라우저가 현재 적용된 값을 자동으로 표시하도록 하는 것입니다.

 body:after { content: '--screen-category : 'var(--screen-category); }

일반 CSS 데모(HTML 또는 JavaScript 없음)에서 확인할 수 있습니다. (브라우저가 변경된 CSS 사용자 정의 속성 값을 자동으로 반영하도록 창 크기를 조정합니다.)

브라우저 지원

CSS 사용자 정의 속성은 모든 주요 브라우저에서 지원됩니다.

(큰 버전 보기)

즉, 기본적으로 사용을 시작할 수 있습니다.

이전 브라우저를 지원해야 하는 경우 구문 및 사용 예제를 배우고 CSS 및 전처리기 변수를 병렬로 전환하거나 사용하는 가능한 방법을 고려할 수 있습니다.

물론 폴백이나 개선 사항을 제공하려면 CSS와 JavaScript 모두에서 지원을 감지할 수 있어야 합니다.

이것은 아주 쉽습니다. CSS의 경우 더미 기능 쿼리와 함께 @supports 조건을 사용할 수 있습니다.

 @supports ( (--a: 0)) { /* supported */ } @supports ( not (--a: 0)) { /* not supported */ }

JavaScript에서는 CSS.supports() 정적 메서드와 동일한 더미 사용자 정의 속성을 사용할 수 있습니다.

 const isSupported = window.CSS && window.CSS.supports && window.CSS.supports('--a', 0); if (isSupported) { /* supported */ } else { /* not supported */ }

우리가 보았듯이 CSS 사용자 정의 속성은 여전히 ​​모든 브라우저에서 사용할 수 있는 것은 아닙니다. 이를 알면 지원 여부를 확인하여 애플리케이션을 점진적으로 향상시킬 수 있습니다.

예를 들어, 두 개의 기본 CSS 파일을 생성할 수 있습니다. 하나는 CSS 사용자 정의 속성이 있고 다른 하나는 속성이 인라인되지 않고 속성이 인라인됩니다(이를 수행하는 방법에 대해서는 곧 논의할 예정입니다).

기본적으로 두 번째 항목을 로드합니다. 그런 다음 JavaScript에서 확인하고 사용자 정의 속성이 지원되는 경우 향상된 버전으로 전환하십시오.

 <!-- HTML --> <link href="without-css-custom-properties.css" rel="stylesheet" type="text/css" media="all" />
 // JavaScript if(isSupported){ removeCss('without-css-custom-properties.css'); loadCss('css-custom-properties.css'); // + conditionally apply some application enhancements // using the custom properties }

이것은 단지 예일 뿐입니다. 아래에서 볼 수 있듯이 더 나은 옵션이 있습니다.

사용을 시작하는 방법

최근 설문 조사에 따르면 Sass는 개발 커뮤니티에서 계속해서 선택하는 전처리기입니다.

따라서 CSS 사용자 정의 속성을 사용하기 시작하거나 Sass를 사용하여 준비하는 방법을 고려해 보겠습니다.

몇 가지 옵션이 있습니다.

1. 지원을 위해 코드를 수동으로 확인

사용자 정의 속성이 지원되는지 여부를 코드에서 수동으로 확인하는 이 방법의 한 가지 이점은 작동하고 지금 바로 수행할 수 있다는 것입니다(Sass로 전환했음을 잊지 마십시오).

 $color: red; :root { --color: red; } .box { @supports ( (--a: 0)) { color: var(--color); } @supports ( not (--a: 0)) { color: $color; } }

이 방법에는 많은 단점이 있습니다. 특히 코드가 복잡해지고 복사 및 붙여넣기를 유지 관리하기가 상당히 어려워집니다.

2. 결과 CSS를 자동으로 처리하는 플러그인 사용

PostCSS 생태계는 오늘날 수십 개의 플러그인을 제공합니다. 그들 중 몇 개는 결과 CSS 출력에서 ​​사용자 정의 속성(인라인 값)을 처리하고 전역 변수만 제공한다고 가정하고(즉, :root 선택기 내에서 CSS 사용자 정의 속성만 선언하거나 변경함) 작동하게 하므로 해당 값 쉽게 인라인 될 수 있습니다.

예는 postcss-custom-properties입니다.

이 플러그인은 다음과 같은 몇 가지 장점을 제공합니다. PostCSS의 모든 인프라와 호환됩니다. 많은 구성이 필요하지 않습니다.

그러나 단점이 있습니다. 플러그인을 사용하려면 CSS 사용자 정의 속성을 사용해야 하므로 Sass 변수에서 전환하기 위해 프로젝트를 준비할 경로가 없습니다. 또한 Sass가 CSS로 컴파일된 후에 수행되기 때문에 변환을 많이 제어할 수 없습니다. 마지막으로 플러그인은 많은 디버깅 정보를 제공하지 않습니다.

3. css-vars 믹스인

저는 대부분의 프로젝트에서 CSS 사용자 정의 속성을 사용하기 시작했으며 많은 전략을 시도했습니다.

  • cssnext를 사용하여 Sass에서 PostCSS로 전환합니다.
  • Sass 변수에서 순수 CSS 사용자 정의 속성으로 전환하십시오.
  • Sass에서 CSS 변수를 사용하여 지원 여부를 감지합니다.

그 경험의 결과로 저는 제 기준을 충족하는 솔루션을 찾기 시작했습니다.

  • Sass로 시작하기 쉬워야 합니다.
  • 사용이 간단해야 하며 구문은 가능한 한 기본 CSS 사용자 정의 속성에 가까워야 합니다.
  • 인라인 값에서 CSS 변수로 CSS 출력을 전환하는 것은 쉬워야 합니다.
  • CSS 사용자 정의 속성에 익숙한 팀 구성원은 솔루션을 사용할 수 있습니다.
  • 변수를 사용할 때 엣지 케이스에 대한 디버깅 정보를 얻을 수 있는 방법이 있어야 합니다.

그 결과 Github에서 찾을 수 있는 Sass 믹스인 css-vars를 만들었습니다. 그것을 사용하면 CSS 사용자 정의 속성 구문을 사용하여 시작할 수 있습니다.

css-vars Mixin 사용

변수를 선언하려면 다음과 같이 믹스인을 사용하세요.

 $white-color: #fff; $base-font-size: 10px; @include css-vars(( --main-color: #000, --main-bg: $white-color, --main-font-size: 1.5*$base-font-size, --padding-top: calc(2vh + 20px) ));

이러한 변수를 사용하려면 var() 함수를 사용하십시오.

 body { color: var(--main-color); background: var(--main-bg, #f00); font-size: var(--main-font-size); padding: var(--padding-top) 0 10px; }

이것은 한 곳(Sass에서)에서 모든 CSS 출력을 제어하고 구문에 익숙해지는 방법을 제공합니다. 또한 mixin과 함께 Sass 변수와 로직을 재사용할 수 있습니다.

지원하려는 모든 브라우저가 CSS 변수와 함께 작동할 때 다음을 추가하기만 하면 됩니다.

 $css-vars-use-native: true;

결과 CSS에서 변수 속성을 정렬하는 대신 믹스인은 사용자 정의 속성 등록을 시작하고 var() 인스턴스는 변환 없이 결과 CSS로 이동합니다. 즉, CSS 사용자 정의 속성으로 완전히 전환하고 우리가 논의한 모든 이점을 갖게 됩니다.

유용한 디버깅 정보를 켜려면 다음을 추가하세요.

 $css-vars-debug-log: true;

이것은 당신에게 줄 것입니다:

  • 변수가 할당되지 않았지만 사용되었을 때의 로그;
  • 변수가 재할당될 때의 로그;
  • 변수가 정의되지 않았지만 대신 사용되는 기본값이 전달되었을 때의 정보입니다.

결론

이제 구문, 장점, 좋은 사용 예 및 JavaScript에서 상호 작용하는 방법을 포함하여 CSS 사용자 정의 속성에 대해 더 많이 알게 되었습니다.

지원 여부를 감지하는 방법, CSS 전처리기 변수와 어떻게 다른지, 브라우저에서 지원될 때까지 기본 CSS 변수를 사용하는 방법을 배웠습니다.

지금이 CSS 사용자 정의 속성 사용을 시작하고 브라우저에서 기본 지원을 준비하기에 적절한 시기입니다.