💡 CHECK
- 사전에 테마를 몇 가지 지정해두고 사용자가 선택하게 하는지?
- 테마 별로 컬러 지정 필요 (기본, 다크테마, 라이트테마 등등)
- 최상단 html에 클래스를 부여하면, 테마에 맞춰 일괄 변경됨
- 사용자가 컬러 하나를 선택하면 그 컬러에 따라 채도/명도/밝기 등 단위로 일괄 변경되도록 설정하는지?
- 컬러 하나로 응용이 가능한 기술 검토 필요
- 색상의 채도 / 밝기 조절 (hsla)을 설정하는 방법
- 사전에 변경할 요소를 지정해서 그 단위만 사용자가 하나하나 설정하는 건지?
- 어떤 요소만 컬러를 변경되도록 할지 논의 필요
css var()
함수는 사용자 지정 속성, css 변수의 값을 다른 속성의 값으로 지정할 때 사용한다.
→ SCSS의 변수 선언과 유사하다. ($primary: #08c;
)
// var(값을 가져올 사용자 지정 속성의 이름, 대체 값-속성이 유효하지 않으면 디폴트 값)
var(<custom-property-name>, <declaration-value>)
// 예시
var(--header-color, blue);
<custom-property-name>
<declaration-value>
[예시 1]
:root{
--main-bg-color: pink;
}
body{
background-color: var(--main-bg-color)
}
[예시 2]
.component .header{
color: var(--header-color, blue);
}
.component .text{
color: var(--text-color, black);
}
.component {
--text-color: #080;
}
[예시]
// 선언
@mixin 믹스인명($매개변수){
// ...
}
@function 함수명($매개변수){
@return 값;
}
// 호출
.style{
@include 믹스인명(인수);
}
.style{
함수명(인수)
}
[예시]
$theme-colors: (
'primary': (
'base': #384ea9,
'light': #e4efff,
'dark': #273677
),
'accent': (
'base': #f08110,
'light': #ff8100,
'dark': #e47f17
),
'foreground': (
'base': #393939,
'light': #6e6e6e,
'dark': #111
),
'background': (
'base': #f8f5f5,
'light': #fff,
'dark': #ddd
)
);
@function theme-color($key: 'primary', $variant: 'base') {
$map: map-get($theme-colors, $key);
@return map-get($map, $variant);
}
.sample{
background-color: theme-color('foreground', 'light');
// #6e6e6e
}
map-get(map, key)
map-get($theme-colors, "primary", "base")
// #384ea9
map.get($theme-colors, "primary", "base")
// #384ea9
map-get($theme-colors, "primary", "like")
// null
map-has-key(map, key)
map-has-key($theme-colors, "primary", "base")
// true
map.has-key($theme-colors, "primary", "base")
// true
map-keys(map)
$font-weights: ("regular": 400, "medium": 500, "bold": 700);
map-key($font-weights)
// "regular", "medium", "bold"
map.key($font-weights)
// "regular", "medium", "bold"
map-values(map)
$font-weights: ("regular": 400, "medium": 500, "bold": 700);
map-values($font-weights)
// "400", "500", "700"
map.values($font-weights)
// "400", "500", "700"
map-merge(map1, map2…)
[예시 1]
$font-sizes: ("small": 12px, "normal": 18px, "large": 24px)
$font-sizes2: ("x-large": 30px, "xx-large": 36px)
map-merge($font-sizes, $font-sizes2);
map.merge($font-sizes, $font-sizes2);
// "small": 12px, "normal": 18px, "large": 24px, "x-large": 30px, "xx-large": 36px
[예시 2]
$fonts: (
"Helvetica": (
"weights": (
"lightest": 100,
"light": 300
)
)
);
$heavy-weights: ("medium": 500, "bold": 700);
map.merge($fonts, "Helvetica", "weights", $heavy-weights);
// (
// "Helvetica": (
// "weights": (
// "lightest": 100,
// "light": 300,
// "medium": 500,
// "bold": 700
// )
// )
// )
map-remove(map, key..)
$font-weights: ("regular": 400, "medium": 500, "bold": 700);
@debug map.remove($font-weights, "regular"); // ("medium": 500, "bold": 700)
@debug map.remove($font-weights, "regular", "bold"); // ("medium": 500)
@debug map.remove($font-weights, "bolder");
// ("regular": 400, "medium": 500, "bold": 700)
_set-color.scss
$primary: var(--primary-color, #D92962);
$secondary: var(--secondary-color, #091f63);
$tertiary: var(--tertiary-color, #0B78C8);
$negative: var(--negative-color, #EB1000);
$config: (
default: (
primary: $primary,
secondary: $secondary,
tertiary: $tertiary,
negative: $negative
),
dark: (
primary: #000,
secondary: red,
tertiary: #fff,
negative: red
),
light: (
primary: blue,
secondary: yellow,
tertiary: purple,
negative: pink
)
);
_set-theme.scss
@function setColor($map, $object, $style) {
@if map-has-key($map, $object) {
@return map-get(map-get($map, $object), $style);
}
@warn "The key ´#{$object} is not available in the map.";
@return null;
}
@mixin setTheme($key){
--primary-color: #{setColor($config, $key, primary)};
--secondary-color: #{setColor($config, $key, secondary)};
--tertiary-color: #{setColor($config, $key, tertiary)};
--negative-color: #{setColor($config, $key, negative)};
}
@each $theme in default, dark, light{
html.#{$theme}-theme{
@include setTheme($theme);
}
}
<html class="dark-theme"></html>
A successful sass theme structure
import { useEffect } from "react";
import "../styles/globals.scss";
import type { AppProps } from "next/app";
import Head from "next/head";
function MyApp({ Component, pageProps }: AppProps) {
useEffect(() => {
document.documentElement.setAttribute("data-theme", "light");
}, []);
return (
<>
<Head>
<title>MeetMeet</title>
<meta charSet="utf-8"></meta>
</Head>
<Component {...pageProps} />
</>
);
}
export default MyApp;
color.scss
)$text-color-1: #232323;
$bg-color-1: #fff;
$btn-color-1: #FE016C;
$text-color-2: #fff;
$bg-color-2: #232323;
$btn-color-2: #FFBD07;
theme.scss
)@use "./color.scss" as *;
html[data-theme="light"] {
--color-text: #{$text-color-1};
--color-background: #{$bg-color-1};
--color-btn : #{$btn-color-1};
}
html[data-theme="dark"] {
--color-text: #{$text-color-2};
--color-background: #{$bg-color-2};
--color-btn : #{$btn-color-2};
}
@use "./themes.scss" as *;
html,
body {
background-color: var(--color-background);
}
a {
color: var(--color-text);
text-decoration: none;
}
button {
backrgound-color: var(--color-btn);
}
* {
box-sizing: border-box;
}
// ...
https://velog.io/@aeong98/SCSS로-다크모드-구현해보기
* hue(색조: 0-360)
- 120: 빨간색
- 240: 녹색
* saturation(채도: 0-100%)
- 0%: 회색
- 100%: 풀컬러
*lightness(밝기: 0-100%)
- 0%: 검은 색
- 100%: 흰색
*alpha(투명도: 0-1)
기본 —base-blue 변수를 사용해서 블루 색상 계층 별로 정의할 수 있다.
:root{
--base-blue: 222, 89%;
--main-blue: hsla(var(--base-blue), 55%, 100%);
--secondary-blue: hsla(var(--base-blue), 45%, 100%);
--main-blue-transparent: hsla(var(--base-blue), 55%, 10%);
// ...
--palette-blue-50: hsla(var(--base-blue), 50%, 100%);
// ...
--primary: hsla(var(--palette-blue-50), 100%);
--emphasis: hsla(var(--palette-blue-50), 8%);
}
안녕하세요! 비슷한 고민을 하던 차에 큰 도움이 되었습니다. 감사합니다! 한가지 여쭤보고 싶은데요
css var()와 scss 함수를 사용해서 테마를 설정하기 <- 이 부분을 따라서 해봤는데
dark / light 같은 경우에 CSS 변수들의 등록이 잘 되는데요,
default 에서 --primary-color: var(--primary-color, #D92962); 이런 식으로 변환이 되는데
테마에 적용시킬 색상 변수가 다시 테마를 참조하고 있어서 그런지 대체값으로도 적용이 안되더라구요
이부분 동일하게 겪으셨는지, 대안으로 어떻게 생각하시는지 궁금합니다.