프로젝트에서 사용할 색상을 구성할 때 도움이 되는 기본 도구가 변수입니다.
그동안 프론트엔드 개발자들은 전처리기preprocessor 변수(옮긴이)를 사용해서 프로젝트에서 사용하는 색상을 구성했습니다. 최근에는 많은 개발자가 색상 변수를 구성할 때 CSS 개발자 지정 속성CSS Custom Properties 방법을 선호합니다. 전처리기 변수 방식보다 가장 좋은 점은 프로젝트 컴파일 단계를 거치지 않고 실시간으로 작업할 수 있으며, 상속 및 값을 바로 재정의할 수 있는 캐스케이드cascade 모델(옮긴이)을 지원한다는 것입니다.
애플리케이션 색상 팔레트를 만들 때, CSS :root 의사 클래스(옮긴이)에 개발자가 색을 지정하는 속성 이름과 값을 추가해서 HTML 문서의 필요한 모든 곳에서 사용할 수 있습니다.
See the Pen <a href=’https://codepen.io/books-webactually/pen/bGBERgV’>bGBERgV</a> by webactually (<a href=’https://codepen.io/books-webactually’>@books-webactually</a>) on <a href=’https://codepen.io’>CodePen</a>.
개발자가 지정한 색 정의 속성
선택 사항이기는 하지만 CSS 개발자 지정 속성 방법이 애플리케이션 테마, 화이트 라벨, 브랜드 바꾸기, 일반 및 다크 모드 구성과 관련된 문제를 해결하는 데 도움이 될까요? 색상 대비를 높이기 위해 색 구성표를 조정해야 하는 경우 어떻게 해야 할까요? 지금까지 사용해온 방식을 사용한다면 변수의 각 값을 최신화해야 합니다.
개발자 지정 속성을 사용해서 색상 변수를 분리하는 방법에 대한 좀더 유연하고 믿을 만한 방식을 이 글에서 제안하고자 합니다. 이 방식은 앞서 말한 문제들을 대부분 해결할 수 있습니다.
색상 팔레트 설정하기
모든 웹사이트는 그 웹사이트에 적용될 색상 팔레트를 만드는 것에서부터 시작됩니다. 이런 팔레트는 색상환color wheel을 기반으로 합니다. 일반적으로 기본 팔레트는 색상 몇 개로 만듭니다. 이 색상을 기반으로 해서 추가적인 색상을 만듭니다. 팔레트를 한 번 생성하면 보통의 경우 그대로 유지하며 웹 애플리케이션을 실행하는 동안 바꾸지 않습니다. 색 이론color theory에 따르면 색상 팔레트를 만드는 몇 가지 방법이 있습니다.
- 단색 구성표(한 가지 기본 색상)
- 보완 방식(두 가지 기본 색상)
- 삼원색 방식(세 가지 기본 색상)
- 사원색 방식(네 가지 기본 색상)
- 인접 패턴(두세 개의 기본 색상)
저는 개발할 때 페일톤Paletton이라는 서비스를 사용해서 삼원색 색상 팔레트를 만듭니다.
이제 팔레트를 이루는 기본 세 가지 색이 준비되었습니다. 이 색들을 기반으로 해서 저는 색상 간 차이를 계산합니다. 이때 calc 함수(옮긴이)와 같이 HSL(HSL 색상 참조; 옮긴이) 형식을 사용하면 아주 유용합니다. 밝은색 값을 변경해서 팔레트에 몇 가지 추가 색상을 생성할 수 있습니다.
See the Pen <a href=’https://codepen.io/books-webactually/pen/MWbKvWG’>MWbKvWG</a> by webactually (<a href=’https://codepen.io/books-webactually’>@books-webactually</a>) on <a href=’https://codepen.io’>CodePen</a>.
HSL 팔레트
기본 색상만 수정해서 팔레트를 변경할 수 있습니다. 나머지 색들은 자동으로 다시 계산됩니다.
HEX 형식이든 RGB 형식이든 어떤 형식을 더 좋아하는지는 중요하지 않습니다. SCSS나 색상 조정(color-adjust
) 함수와 같은 전처리기의 기능으로 프로젝트를 컴파일하는 단계에서 팔레트를 만들 수 있습니다. 앞서 언급했듯이 이 단계는 대부분 고정되어 있습니다. 애플리케이션이 실행 중일 때, 팔레트를 변경하는 경우는 매우 드뭅니다. 전처리기로 계산하는 이유입니다.
참고: 각 색상에 대해 HEX와 RGB를 모두 생성하는 것이 좋습니다. 이렇게 하면 나중에 알파 채널로 작성할 수 있습니다.
See the Pen <a href=’https://codepen.io/smashingmag/pen/oNxgQqv’>SCSS Palette</a> by Smashing Magazine (<a href=’https://codepen.io/smashingmag’>@smashingmag</a>) on <a href=’https://codepen.io’>CodePen</a>.
SCSS 팔레트
변수 이름으로 직접 색상을 지정할 수 있는 유일한 단계가 팔레트입니다.
테마 또는 기능 색상 정의하기
팔레트를 준비한 후 다음 단계는 기능 색상입니다. 이 단계에서 색상 값 그 자체는 중요하지 않습니다. 그 색을 적용하는 기능이 중요합니다. 기본 또는 앱 브랜드 색상, 테두리 색상, 어두운 배경의 텍스트 색상, 밝은 배경의 텍스트 색상, 버튼 배경, 링크 색상, 호버 링크 색상, 힌트 텍스트 색상 등이 그런 사례입니다.
앞서 말한 것들은 모든 웹사이트나 애플리케이션에서 아주 일반적입니다. 이렇게 색상이 애플리케이션의 특정 색상 테마에 영향을 미칩니다. 이때 팔레트에서 신중하게 색을 선택합니다. 따라서 쉽게 다른 색상 팔레트를 사용함으로써 애플리케이션 테마를 변경할 수 있습니다.
아래 예제에서 button 태그, a 태그, input 태그 세 개를 이용해서 일반적인 UI 화면을 만들었습니다. 앞에서 생성한 팔레트 값을 포함하는 기능 변수를 사용하여 색상을 지정합니다. 조건에 따른 애플리케이션 테마 변경을 담당하는 주요 기능 변수는 primary-color 변수입니다.
예제 화면 상단에 있는 세 개의 버튼을 사용하여 화면의 세 개 태그 테마를 바꿀 수 있습니다. 변경 시 해당하는 CSSOM API(setProperty)를 사용합니다.
See the Pen <a href=’https://codepen.io/books-webactually/pen/xxRZLVN’>xxRZLVN</a> by webactually (<a href=’https://codepen.io/books-webactually’>@books-webactually</a>) on <a href=’https://codepen.io’>CodePen</a>.
기능 색상
이 방법은 애플리케이션 테마뿐만 아니라 웹 페이지마다 다른 색상 테마를 적용할 때도 유용합니다. 예를 들어 zubry.by 웹사이트에서 저자는 모든 페이지의 로고, 제목, 컨트롤 및 텍스트를 선택할 때 공통 스타일 시트와 기능 변수 --page-color
를 사용했습니다. 그리고 각 페이지만의 스타일에서 이 변수를 재정의하여 페이지를 개별 기본 색상으로 설정했습니다.
컴포넌트 색상 사용
큰 웹 프로젝트의 경우 항상 작게 쪼개는 것이 필요합니다. 모든 것을 작은 컴포넌트로 나누고 여러 페이지에서 재사용합니다. 각 컴포넌트 요소는 일반적으로 BEM(옮긴이) 또는 CSS 모듈로 쪼개거나 다른 접근 방식을 사용했더라도 그것과는 상관없다는 것을 의미하는 고유한 스타일을 가지고 있습니다. 이런 소스 코드는 로컬 범위이며 재사용이 가능하다는 것이 중요합니다.
일반적으로 컴포넌트 수준에서 색상 변수를 사용하는 두 가지 경우를 이야기하고자 합니다.
첫 번째는 애플리케이션 스타일 가이드에 따라 기본 브랜드 버튼, 보조 버튼 등과 같이 용도에 따라 버튼이 다른 경우 컴포넌트를 여러 곳에서 사용할 때입니다.
두 번째는 버튼 호버, 활성 및 초점 상태와 같은 색상이 다른 여러 상태를 가진 컴포넌트가 있는 경우입니다. 입력 또는 선택 필드에 대한 정상 및 유효하지 않은 상태 등등입니다.
컴포넌트 변수가 유용하면서도 드문 경우가 “화이트 라벨” 기능입니다. “화이트 라벨”은 사용자가 사용자 인터페이스의 일부를 지정하거나 브랜딩하여 클라이언트와의 상호작용 경험을 개선할 수 있는 서비스 기능입니다. 사용자가 서비스 또는 이메일 템플릿을 통해 고객과 공유하는 전자문서가 그 사례입니다. 이 경우 컴포넌트 수준의 변수는 애플리케이션 색상 테마의 나머지 부분과는 별도로 특정 컴포넌트를 구성하는 데 도움이 됩니다.
아래 예제에서는 이제 기본 브랜드 버튼의 색상 지정을 위한 컨트롤을 추가했습니다. 컴포넌트 수준의 색상 변수를 사용하여 UI 컨트롤을 서로 별도로 구성할 수 있습니다.
See the Pen <a href=’https://codepen.io/books-webactually/pen/oNYbeYg’>oNYbeYg</a> by webactually (<a href=’https://codepen.io/books-webactually’>@books-webactually</a>) on <a href=’https://codepen.io’>CodePen</a>.
컴포넌트 색상
변수가 가진 레벨을 확인하는 방법은 무엇일까요?
저는 테마 또는 기능 수준에서 루트에 넣을 수 있는 것을 이해하는 방법과 컴포넌트의 수준에서 남길 수 있는 방법에 대한 궁금증을 갖고 있었습니다. 여러분이 작업하는 상황을 고려하지 않으면 답하기 어려운 훌륭한 질문입니다.
불행히도 프로그래밍과 동일한 접근 방식은 색상과 스타일에는 적용할 수 없습니다. 세 개의 같은 소스 코드 부분이 있다면 그때마다 다시 작성해야 합니다.
색상은 컴포넌트에서 컴포넌트로 반복해 사용할 수 있지만 규칙이라는 의미는 아닙니다. 이러한 컴포넌트 사이에는 관계가 있을 수 없습니다. 예를 들어, input 태그의 테두리와 기본 button 태그의 배경입니다. 그렇습니다. 위의 예제가 그런 경우이지만 다음 예제를 확인해보겠습니다.
See the Pen <a href=’https://codepen.io/books-webactually/pen/ExNPvNJ’>ExNPvNJ</a> by webactually (<a href=’https://codepen.io/books-webactually’>@books-webactually</a>) on <a href=’https://codepen.io’>CodePen</a>.
색상 나누기 – 팔레트
어두운 회색 색상이 반복됩니다. input 태그의 테두리, 가까운 아이콘의 채우기 색상 및 보조 button 태그의 배경입니다. 그러나 이러한 컴포넌트는 서로 연결되지 않습니다. input 태그의 테두리 색상이 변경되면 보조 button 태그의 배경은 변경되지 않습니다. 이런 경우 팔레트에서 단지 변수를 여기에 유지해야 합니다.
녹색은 어떨까요? 기본 또는 브랜드 색상으로 명확하게 정의할 수 있으며, 메인 버튼의 색상이 변경되면 첫 번째 레벨의 링크와 헤더 색상도 변경될 수 있습니다.
빨간색은 어떻습니까? input 태그의 잘못된 상태, 오류 메시지 및 button 태그는 전체 애플리케이션 수준에서 동일한 색상을 갖습니다. 이것이 패턴입니다. 이제 루트 섹션에서 몇 가지 일반적인 기능 변수를 정의할 수 있습니다.
See the Pen <a href=’https://codepen.io/books-webactually/pen/mdOVMWr’>mdOVMWr</a> by webactually (<a href=’https://codepen.io/books-webactually’>@books-webactually</a>) on <a href=’https://codepen.io’>CodePen</a>.
색상 나누기 – 기능 색상
컴포넌트의 색상 수준에 관해서는 사용자 지정 속성을 사용하여 사용자 정의를 할 수 있는 컴포넌트를 쉽게 식별할 수 있습니다.
버튼은 다른 설정, 다른 사용 사례에 대한 배경 색상 및 텍스트 변경으로 반복됩니다. primary, secondary, tertiary, destructive or negative가 그 경우입니다.
input 태그에는 배경 및 테두리 색상이 다른 잘못된 상태와 정상의 두 상태가 있습니다. 따라서 이러한 설정을 해당 컴포넌트 수준에서 색상 변수에 넣겠습니다.
나머지 컴포넌트의 경우 로컬 색상 변수를 정의할 필요가 없으며 중복됩니다.
See the Pen <a href=’https://codepen.io/books-webactually/pen/ZEBQJem’>ZEBQJem</a> by webactually (<a href=’https://codepen.io/books-webactually’>@books-webactually</a>) on <a href=’https://codepen.io’>CodePen</a>.
색상 나누기 – 컴포넌트
프로젝트의 패턴 언어를 알아야 합니다. 아마도 디자인 팀과 UX는 그 패턴 언어로 개발하고 있을 것입니다. 개발자는 완전히 시각적 언어의 전체 개념을 이해해야 합니다. 무엇이 일반적인지 구별할 수 있고, 기능 수준에 있어야 하며, 로컬 범위에 존재해야 합니다.
그러나 모든 것이 그렇게 복잡하지 않습니다. 명확하게 알 수 있습니다. 페이지의 일반적인 배경, 기본 텍스트의 배경 및 색상은 대부분의 경우 애플리케이션의 테마를 설정하는 것입니다. 다크 모드나 일반 모드와 같은 특정 모드의 구성을 담당하는 항목을 수집하는 것이 매우 편리합니다.
루트에 모든 것을 넣지 않는 이유는?
저는 이 질문과 같은 경험을 한 적이 있습니다. 저와 우리 팀은 Lition 프로젝트에서 웹 애플리케이션에는 IE11을 지원해야 하지만 웹사이트에는 필요하지 않다는 현실에 직면했습니다. 프로젝트 사이에 공통 UI 키트를 사용하였으며 모든 루트에 모든 변수를 넣기로 결정했습니다. 이렇게 하면 모든 수준에서 변수를 재정의할 수 있습니다.
또한 웹 애플리케이션 및 IE11의 경우, 이 접근 방식으로 다음 후처리 플러그인을 통해 소스 코드를 간단히 전달하고 프로젝트의 모든 UI 컴포넌트에 그 변수를 변환했습니다. 이 방법은 후처리가 캐스케이드 모델의 세부 사항을 이해할 수 없기 때문에 모든 변수가 루트 섹션에 정의된 경우에만 가능합니다.
지금은 이것이 올바른 방법이 아니라는 점을 이해하고 있습니다. 첫째, 컴포넌트 색상을 루트에 넣으면 문제가 있을 때 분리해서 처리한다는 원리를 준수하지 않게 됩니다. 따라서 스타일시트에서 중복된 CSS로 끝날 수 있습니다. 예를 들어 각 컴포넌트에 고유한 스타일이 있는 컴포넌트 폴더가 있습니다. 루트 섹션에 색상 변수를 설명하는 공통 스타일시트도 있습니다. 버튼 컴포넌트를 제거하기로 결정합니다. 이 경우 공통 스타일 파일에서 button 태그와 연결된 변수도 제거해야 합니다.
둘째, 성능 면에서 최선의 방법이 아닙니다. 그렇습니다. 색상 변경으로 인해 리플로/레이아웃이 아닌 다시 그려주는 과정만 발생합니다. 그 자체로 비용이 많이 드는 것은 아니지만 가장 높은 수준에서 일부 변경하면 변경 사항이 작은 로컬 영역에 있을 때보다 전체 트리를 확인하는 데 더 많은 자원을 사용합니다. 자세한 내용은 리시 린하르트Lisi Linhart의 CSS 변수의 성능 벤치마크에서 확인할 수 있습니다.
제가 현재 작업하고 있는 프로젝트인 Tispr에서 팀과 저는 분할을 사용하고 높은 수준에서만 팔레트와 기능 색상, 루트에 모든 것을 입력하지 않습니다. 또한 이 문제는 해당 폴리필polyfill로 해결되기 때문에 우리는 IE11을 두려워하지도 않습니다. npm 모듈 ie11-custom-properties를 설치하고 애플리케이션 자바스크립트 번들에 라이브러리를 불러오기 하면 됩니다.
See the Pen <a href=’https://codepen.io/books-webactually/pen/yLVeobx’>yLVeobx</a> by webactually (<a href=’https://codepen.io/books-webactually’>@books-webactually</a>) on <a href=’https://codepen.io’>CodePen</a>.
또는 스크립트 태그별로 모듈을 추가합니다.
See the Pen <a href=’https://codepen.io/books-webactually/pen/vYyLJZK’>vYyLJZK</a> by webactually (<a href=’https://codepen.io/books-webactually’>@books-webactually</a>) on <a href=’https://codepen.io’>CodePen</a>.
또한 CDN을 사용해서 npm을 사용하지 않고도 라이브러리를 추가할 수 있습니다. 이 폴리필 작업은 IE11이 캐스케이드를 기반으로 속성을 정의하고 읽을 수 있는 사용자 지정 속성에 대한 최소한의 지원이 있다는 사실에 근거합니다. 이중 대시(//)
로 시작하는 속성에서는 불가능하지만 벤더 접두사와 유사한 방식인 단일 대시(/
)로는 가능합니다. 레퍼지터리 문서에서 몇 가지 제한 사항 및 자세한 내용을 볼 수 있습니다. 다른 브라우저는 이 폴리필을 무시합니다.
다음은 Tispr 웹 애플리케이션의 팔레트와 사용자 계약, 송장 또는 제안과 같은 전자문서에 대한 “화이트 라벨” 기능의 컨트롤입니다.
자바스크립트에 색상 변수를 저장하는 것은 어떨까요?
자바스크립트 소스 코드에 팔레트 및 기능 변수를 저장하는 것이 좋지 않을까 하는 것도 좋은 질문입니다. 동적으로 변경하고 나중에 인라인 스타일을 통해 색상을 재정의할 수 있습니다. 이 방법은 사용할 수는 있지만 특정 요소에 접근하고 색상 속성을 변경해야 하기 때문에 최적화가 다소 부족합니다. CSS 변수를 사용하면 변숫값과 같은 단일 속성만 변경합니다.
자바스크립트에는 색상으로 작업할 수 있는 기본 함수나 API가 없습니다. CSS 색상 모듈 5를 보면 기본 색상에서 만들 수 있는 색상이나 계산하는 여러 가지 방법이 있습니다. 미래의 관점에서 볼 때 CSS 사용자 지정 속성은 자바스크립트 변수보다 풍부하고 유연합니다. 또한 자바스크립트 변수를 사용하면 캐스케이드 방식으로 상속을 사용할 가능성이 없으며 이것이 주요 단점입니다.
결론
색상을 세 가지 수준인 팔레트, 기능 색상 및 컴포넌트 색상으로 나누면 프로젝트를 개발하는 동안 변경이나 새로운 요구 사항에 좀더 쉽게 적응할 수 있습니다. 개발자가 지정할 수 있는 CSS 속성이 색상을 구분할 때 적절한 도구라고 생각입니다. 웹 페이지의 스타일을 적용할 때 CSS 방식, 전처리기 방식, 자바스크립트 방식 모두 같은 역할을 합니다.
경험을 통해 이런 방법을 알게 되었습니다. 저만 알고 있는 방법이 아닙니다. 새러 수에이던Sara Soueidan도 자신의 글에서 변수를 글로벌 및 컴포넌트 수준으로 나누는 유사한 접근 방식을 설명했습니다.
또한 레아 버로Lea Verou의 글도 추천합니다. 이 글에서는 색상이라는 용어로만 설명하지 않고 CSS 변수를 적용할 수 있는 경우를 알려줍니다.
에릭 마이어, 사라 와터 보에처의 《사람을 배려하는 디자인》
우리는 제품 사용자가 누가 될지, 제품을 사용할 때 어떤 감정일지 정확히 알 수 없습니다. 하지만 미리 스트레스 케이스를 고민하고 연민으로 디자인한다면 더 많은 사용자가 다양한 상황에서 도움받을 수 있습니다. 여러분이 디자이너건, 개발자건, 기획자건 실패할 수도 있는 디자인을 세상에 선보이기 전에 테스트할 수 있습니다. 모든 사용자를 만나볼 수는 없지만 이 책을 통해 더 넓은 범주의 사람을 위한 배려하는 디자인을 만들 수 있을 것입니다.
books@webactually.com
최고의 게시글입니다 많은 도움이 되었습니다!!