Dark Mode in Bulma

Dark Mode in Bulma (Bulma의 다크 모드)

현대 브라우저는 사용자의 테마 선호도가 light인지 dark인지 prefers-color-scheme 키워드로 감지할 수 있어요. Bulma는 여기에 더해 data-theme 속성과 theme-dark 클래스로 다크 모드를 제어해요.

출처: 문서

본문

현대 브라우저는 사용자가 테마 선호도를 light로 설정했는지 dark로 설정했는지 prefers-color-scheme 키워드를 사용해서 감지할 수 있어요.

이 값은 미디어 쿼리에서 사용해서 웹사이트 스타일을 그에 맞게 바꿀 수 있어요.

@media (prefers-color-scheme: dark) {
  :root {
    /* Update CSS variables */
  }
}

하지만 웹사이트가 이 선호도를 바꾸는 것은 불가능해요. 그래서 data-theme HTML 속성이나 theme-dark CSS 클래스를 추가하는 것이 더 좋아요.

Bulma는 이렇게 다크 테마를 정의해요.

@media (prefers-color-scheme: dark) {
  :root {
    /* Update CSS variables */
  }
}

[data-theme=dark],
.theme-dark {
  /* Update CSS variables */
}

이 규칙들에 따르면:

  • 사용자 선호도가 설정되지 않았다면 웹사이트는 기본적으로 라이트 모드예요.
  • 사용자가 light로 설정했다면 역시 라이트 모드예요.
  • 사용자가 dark로 설정했다면 웹사이트는 다크 모드예요.

페이지 일부에 다크 모드 강제하기

HTML 속성이나 CSS 클래스만 사용해서 페이지의 일부에 다크 모드를 적용할 수 있어요.

<div>
  This is in Light Mode if the user hasn't set a preference, or if their preference is set to <code>light</code>.
</div>

<div data-theme="dark">
  This is in Dark Mode
</div>

<div class="theme-dark">
  This is also in Dark Mode
</div>

전체 웹페이지에 다크 모드 강제하기

전체 웹페이지에 다크 모드를 적용하고 싶다면, <html> 요소에 속성이나 클래스를 설정하면 돼요.

<html data-theme="dark">
<!-- Or -->
<html class="theme-dark">

다크 테마가 만들어지는 방식

<code>sass/themes/dark.scss</code> 파일의 내용이에요.

@use "sass/utilities/initial-variables" as iv;
@use "sass/utilities/css-variables" as cv;
@use "sass/utilities/derived-variables" as dv;
@use "sass/themes/setup";

// The main lightness of this theme
$scheme-main-l: 11%;
$background-l: 14%;
$text-l: 71%;

// The main scheme color, used to make calculations
$scheme-main: hsl(iv.$scheme-h, iv.$scheme-s, $scheme-main-l);
$background: hsl(iv.$scheme-h, iv.$scheme-s, $background-l);
$text: hsl(iv.$scheme-h, iv.$scheme-s, $text-l);

@mixin dark-theme {
  // Required: update the lightness colors and hover/active states
  @include cv.register-vars(
    (
      "scheme-brightness": "dark",
      "scheme-main-l": $scheme-main-l,
      "scheme-main-bis-l": $scheme-main-l + 2%,
      "scheme-main-ter-l": $scheme-main-l + 4%,
      "background-l": $background-l,
      "border-weak-l": 21%,
      "border-l": 24%,
      "text-weak-l": 53%,
      "text-l": $text-l,
      "text-strong-l": 93%,
      "text-title-l": 100%,
      "hover-background-l-delta": 5%,
      "active-background-l-delta": 10%,
      "hover-border-l-delta": 10%,
      "active-border-l-delta": 20%,
      "hover-color-l-delta": 5%,
      "active-color-l-delta": 10%,
    )
  );

  // Required: update the "on scheme" colors since the main scheme color is changed
  // from white (100% lightness)
  // to black (11% lightness in this case)
  @each $name, $color in dv.$colors {
    @include cv.generate-on-scheme-colors($name, $color, $scheme-main);
  }

  // Optional: update the shadow color
  @include cv.register-hsl("shadow", white);
}

이 mixin은 CSS 변수 목록과 그 새 값을 출력해요.

이 테마를 prefers-color-scheme 미디어 쿼리와 함께 사용하려면 이렇게 작성해요.

@use "sass/utilities/css-variables" as cv;
@use "sass/themes/dark";

@include cv.system-theme($name: "dark") {
  @include dark.dark-theme;
}

이 테마를 [data-theme=dark]와 .theme-dark 셀렉터로 사용하려면 이렇게 작성해요.

@use "sass/utilities/css-variables" as cv;
@use "sass/themes/dark";
@use "sass/themes/setup";

@include cv.bulma-theme($name: "dark") {
  @include dark.dark-theme;
  @include setup.setup-theme;
}

bulma-theme() mixin

이 mixin으로 적절한 HTML 속성 셀렉터와 CSS 클래스 셀렉터를 모두 가진 CSS 규칙 세트를 생성할 수 있어요. 이름은 $name 매개변수로 정의돼요.

@use "sass/utilities/css-variables" as cv;

@include cv.bulma-theme($name: "my-theme") {
  // Your code
}

이것은 다음과 같이 출력돼요.

[data-theme=my-theme],
.theme-my-theme {
  /* Your code */
}

system-theme() mixin

이 mixin은 @media (prefers-color-scheme: $name) 미디어 쿼리를 생성해요.

@use "sass/utilities/css-variables" as cv;

@include cv.system-theme($name: "dark") {
  // Your code
}

이것은 다음과 같이 출력돼요.

@media (prefers-color-scheme: dark) {
  :root {
    /* Your code */
  }
}

register-vars() 함수

모든 Bulma CSS 변수는 bulma- 접두사로 시작해요. 이 접두사는 $cssvars-prefix: "bulma-"; Sass 변수로 정의돼요.

모든 CSS 변수에 이 접두사를 붙여 쓰는 것은 번거롭기 때문에, Bulma는 새 변수를 등록하는 Sass 함수 register-vars()를 제공해요.

이 함수는 name: value 쌍으로 이루어진 Sass map을 받아요.

@use "sass/utilities/css-variables" as cv;

$scheme-main-l: 11%;
$background-l: 14%;
$text-l: 71%;

@include cv.bulma-theme($name: "my-theme") {
  @include cv.register-vars(
    (
      "scheme-brightness": "dark",
      "scheme-main-l": $scheme-main-l,
      "scheme-main-bis-l": $scheme-main-l + 2%,
      "scheme-main-ter-l": $scheme-main-l + 4%,
      "background-l": $background-l,
      "border-weak-l": 21%,
      "border-l": 24%,
      "text-weak-l": 53%,
      "text-l": $text-l,
      "text-strong-l": 93%,
      "text-title-l": 100%,
      "hover-background-l-delta": 5%,
      "active-background-l-delta": 10%,
      "hover-border-l-delta": 10%,
      "active-border-l-delta": 20%,
      "hover-color-l-delta": 5%,
      "active-color-l-delta": 10%,
    )
  );
}

명도(lightness) 업데이트하기

다크 모드에서 Bulma는 메인 스킴 색상의 색조(hue)와 채도(saturation)를 유지해요. 대신 배경, 테두리, 텍스트 색상, 그리고 hover/active 상태의 명도는 반전시켜요.

Lightness Name Light Mode (default) Dark Mode (default)
--bulma-scheme-main-l 100% 11%
--bulma-scheme-main-bis-l 98% 13%
--bulma-scheme-main-ter-l 98% 15%
--bulma-background-l 96% 14%
--bulma-border-weak-l 93% 21%
--bulma-border-l 86% 24%
--bulma-text-weak-l 48% 53%
--bulma-text-l 29% 71%
--bulma-text-strong-l 21% 93%
--bulma-text-title-l 14% 100%
--bulma-hover-background-l-delta 5% 5%
--bulma-active-background-l-delta 10% 10%
--bulma-hover-border-l-delta 10% 10%
--bulma-active-border-l-delta 20% 20%
--bulma-hover-color-l-delta 5% 5%
--bulma-active-color-l-delta 10% 10%

generate-on-scheme-colors() 함수

스킴(scheme) 색은 다음에 사용되는 색이에요.

  • 배경(backgrounds)
  • 테두리(borders)
  • 텍스트 음영(text shades)
  • 강한 텍스트(strong text)
  • 약한 텍스트(weak text)
  • 제목 텍스트(title text)
  • 보통 텍스트(normal text)

7가지 기본 색상 각각에 대해, 기본 Bulma 테마는 on-scheme 음영을 생성해요. 이는 메인 스킴 색 위에서 괜찮아 보이는 각 색상의 음영을 의미해요.

라이트 모드에서는 이렇게 보여요.

색상 CSS 변수
link var(--bulma-link-on-scheme)
primary var(--bulma-primary-on-scheme)
info var(--bulma-info-on-scheme)
success var(--bulma-success-on-scheme)
warning var(--bulma-warning-on-scheme)
danger var(--bulma-danger-on-scheme)

다크 모드에서는 이 색상들의 명도를 반전시키기 때문에 페이지 배경이 흰색에서 검은색으로 바뀌어요. 따라서 7가지 기본 색상의 -on-scheme 색을 업데이트해야 해요.

만약 자신만의 테마를 만든다면, 각 색상마다 generate-on-scheme-colors() 함수를 사용해서 새로운 -on-scheme 색상을 자동으로 생성할 수 있어요. 이 함수는 3가지 매개변수를 받아요.

  • $name — 문자열. 예: "primary"
  • $color — 색상 값
  • $scheme-main — 테마의 메인 스킴 색상(페이지 배경으로 사용되는 색). 예: #fff

전체 코드는 이렇게 생겼어요.

@use "sass/utilities/css-variables" as cv;
@use "sass/utilities/derived-variables" as dv;

$scheme-main-l: 11%;
$scheme-main: hsl(iv.$scheme-h, iv.$scheme-s, $scheme-main-l);

@include cv.bulma-theme($name: "my-theme") {
  @each $name, $color in dv.$colors {
    @include cv.generate-on-scheme-colors($name, $color, $scheme-main);
  }
}

setup-theme() 함수

Bulma에서는 일부 CSS 변수가 다른 CSS 변수를 참조해요. 예를 들어 <code>--bulma-scheme-main</code>은 이렇게 정의돼요.

:root {
  --bulma-scheme-main: hsl(
    var(--bulma-scheme-h)
    var(--bulma-scheme-s)
    var(--bulma-scheme-main-l)
  );
}

CSS 변수의 특성상, --bulma-scheme-main-l 값을 업데이트하면 --bulma-scheme-main을 다시 정의해야 해요. 그것이 바로 setup-theme()이 하는 일이에요.

[data-theme=my-theme],
.theme-my-theme {
  --bulma-scheme-main-l: 7%;
  --bulma-scheme-main: hsl(
    var(--bulma-scheme-h)
    var(--bulma-scheme-s)
    var(--bulma-scheme-main-l)
  );
}

자신만의 테마를 만든다면, CSS 변수를 설정한 후에 이 함수를 호출하면 돼요.

@use "sass/themes/setup";

@include cv.bulma-theme($name: "my-theme") {
  // Set your own CSS variables,
  // either manually:
  --bulma-scheme-main-l: 7%;
  // or using Bulma's register-vars() function:
  @include register-vars((
    "bulma-scheme-main-l": 7%,
  ));

  // Then, setup the new theme.
  @include setup.setup-theme();
}

더 알아보기 (Learn more)