[JavaScript30] 3. CSS Variables | CSS ๋ณ€์ˆ˜, setProperty()
language/javascript

[JavaScript30] 3. CSS Variables | CSS ๋ณ€์ˆ˜, setProperty()

๐Ÿ“ƒ ์š”๊ตฌ์‚ฌํ•ญ

  1. spacing, blur, base color์— ๋Œ€ํ•œ input์„ ๋งˆ์šฐ์Šค๋กœ ์กฐ์ ˆํ•˜๋ฉด, ํ•ด๋‹นํ•˜๋Š” ๊ฐ’์œผ๋กœ CSS ์š”์†Œ๊ฐ€ ์—…๋ฐ์ดํŠธ ๋œ๋‹ค.
  2. css variable์„ ์‚ฌ์šฉํ•œ๋‹ค.
  3. ์œ„์˜ ์ด๋ฒคํŠธ๋Š” ๋งˆ์šฐ์Šค๊ฐ€ ์›€์ง์ž„์— ๋”ฐ๋ผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐ˜์˜๋˜์–ด์•ผ ํ•œ๋‹ค.

 

โœจ ๊ฒฐ๊ณผํ™”๋ฉด

 

๐Ÿ’ป ์†Œ์Šค์ฝ”๋“œ

๐Ÿ™„ ๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ

HTML, CSS

<!DOCTYPE html>
<html lang="en">
  <head>
  ...
    <script src="variables.js" defer></script>
  </head>
  <body>
    <h2>Update CSS Variables with <span class="hl">JS</span></h2>
    ...
    <style>
      :root {
        /* color, space, blur์˜ ๊ธฐ๋ณธ๊ฐ’ */
        --color-base: #ffc600;
        --space-base: 10px;
        --blur-base: 10px;
      }

      img {
        transform: translate(var(--space-base));
        filter: blur(var(--blur-base));
      }

      .hl {
        color: var(--color-base);
      }
    </style>
  </body>
</html>

css variable์˜ ์‚ฌ์šฉ์„ ์œ„ํ•ด :root์— ๊ฐ๊ฐ base variable์„ ์„ ์–ธํ•ด ์ฃผ์—ˆ๊ณ , ํ•„์š”ํ•œ ์š”์†Œ์— ํ•ด๋‹น css variable์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ’์„ ๋Œ€์ž…ํ•ด ์ฃผ์—ˆ๋‹ค.

 

JS

"use strict";

// root์— ์„ ์–ธ๋œ css variable์„ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•ด ์„ ์–ธ
let root = document.querySelector(":root");
// ๊ฐ input์— addEventListener๋กœ ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ์„ ์–ธ
const color = document.getElementById("base");
const blur = document.getElementById("blur");
const spacing = document.getElementById("spacing");

// 1. blur ์ด๋ฒคํŠธ
blur.addEventListener("mousemove", (e) => {
  root.style.setProperty("--blur-base", `${e.target.value}px`);
});

// 2. spacing ์ด๋ฒคํŠธ
spacing.addEventListener("mousemove", (e) => {
  root.style.setProperty(
    "--space-base",
    `${e.target.value}px, ${e.target.value}px`
  );
});

// 3. color ์ด๋ฒคํŠธ
color.addEventListener("mousemove", (e) => {
  root.style.setProperty("--color-base", `${e.target.value}`);
});

ํ•„์š”ํ•œ input ์š”์†Œ๋“ค์„ getElementById๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ€์ ธ์˜จ ํ›„, ๊ฐ๊ฐ addEventListener๋ฅผ ํ†ตํ•ด mousemove ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  input์˜ ๊ฐ’์ด ๋ณ€ํ•จ์— ๋”ฐ๋ผ, setProperty๋ฅผ ํ†ตํ•ด ํ•ด๋‹น css variable์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ–ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ–ˆ์„ ๋•Œ์˜ ๋ฌธ์ œ์ ์€, addEventListener๊ฐ€ ์ค‘๋ณต ์‚ฌ์šฉ๋˜์–ด ์ฝ”๋“œ๊ฐ€ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๊ธธ์–ด์ง„๋‹ค. ๊ฐ•์˜๋ฅผ ํ†ตํ•ด ๊ฐœ์„ ํ•œ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

๐Ÿค— ๊ฐœ์„ ๋œ ๊ฐ•์˜ ์ฝ”๋“œ

HTML, CSS

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Scoped CSS Variables and JS</title>
    <script src="variables_after.js" defer></script>
  </head>
  <body>
    <h2>Update CSS Variables with <span class="hl">JS</span></h2>

    <div class="controls">
      <label for="spacing">Spacing:</label>
      <input
        id="spacing"
        type="range"
        name="spacing"
        min="10"
        max="200"
        value="10"
        data-sizing="px"
      />

      <label for="blur">Blur:</label>
      <input
        id="blur"
        type="range"
        name="blur"
        min="0"
        max="25"
        value="10"
        data-sizing="px"
      />

      <label for="base">Base Color</label>
      <input id="base" type="color" name="base" value="#ffc600" />
    </div>

    <img src="https://source.unsplash.com/7bwQXzbF6KE/800x500" />

    <style>
      :root {
        /* color, space, blur์˜ ๊ธฐ๋ณธ๊ฐ’ */
        --base: #ffc600;
        --spacing: 10px;
        --blur: 10px;
      }
      /*
        misc styles, nothing to do with CSS variables
      */

      body {
        text-align: center;
        background: #193549;
        color: white;
        font-family: "helvetica neue", sans-serif;
        font-weight: 100;
        font-size: 50px;
      }

      .controls {
        margin-bottom: 50px;
      }

      input {
        width: 100px;
      }

      img {
        padding: var(--spacing);
        background: var(--base);
        transform: translate(var(--spacing));
        filter: blur(var(--blur));
      }

      .hl {
        color: var(--base);
      }
    </style>

    <script></script>
  </body>
</html>

๊ฐ input์—๋Š” name์ด ์„ ์–ธ๋˜์–ด ์žˆ๋Š”๋ฐ, JS์—์„œ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•ด css variable์˜ ์ด๋ฆ„์„ ๊ฐ input์˜ name์œผ๋กœ ์„ ์–ธํ•ด ์ฃผ์—ˆ๋‹ค. ๋˜, ์ด๋ฏธ์ง€์— ๋ฐฐ๊ฒฝ์ƒ‰์„ ์ฃผ๊ธฐ ์œ„ํ•ด padding์„ ์ฃผ๊ณ , ๊ฐ’์€ :root์— ์„ ์–ธํ•œ variable๋กœ ์ฃผ์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ padding๊ฐ’ ๋˜ํ•œ JS์—์„œ ์ œ์–ด๋œ๋‹ค.

 

JS

"use strict";

// controls div์˜ ๋ชจ๋“  input ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์™€์„œ ์–ด๋–ค ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด css๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค.
const inputs = document.querySelectorAll(".controls input");

function handleUpdate() {
  const suffix = this.dataset.sizing || "";
  // px, or nothing์€ type=color input์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
  // || ''์„ ๋ช…์‹œํ•˜์ง€ ์•Š์œผ๋ฉด undefined ์ฒ˜๋ฆฌ๋œ๋‹ค.
  document.documentElement.style.setProperty(`--${this.name}`, this.value + suffix);
}

inputs.forEach((input) => input.addEventListener("change", handleUpdate));
inputs.forEach((input) => input.addEventListener("mousemove", handleUpdate));

JS์ฝ”๋“œ๋Š” ํ›จ์”ฌ ์ค„์–ด๋“ค์—ˆ๋‹ค. ๊ฐ ์š”์†Œ๋ฅผ ์ผ์ผํžˆ ๊ฐ€์ ธ์™€์„œ ์„ ์–ธํ•œ ๋‚˜์˜ ๋ฐฉ์‹๊ณผ๋Š” ๋‹ฌ๋ฆฌ, input ์š”์†Œ๋ฅผ ํ•œ๊บผ๋ฒˆ์— ๊ฐ€์ ธ์™€์„œ ํ•ด๋‹น ์š”์†Œ๋“ค์— ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ•˜๋ฉด ๊ฐ’์„ ์ ์šฉํ•ด์ฃผ๋Š” ์‹์œผ๋กœ ์ž‘์„ฑํ•˜์˜€๋‹ค.

suffix ๋ณ€์ˆ˜๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š”, HTML์—์„œ ์ •์˜๋œ data-sizing์„ ๊ฐ€์ ธ์˜ค๋Š”๋ฐ, input type="color"์—๋Š” data-*๊ฐ€ ์—†์œผ๋ฏ€๋กœ dataset์„ ๊ฐ€์ ธ์˜ค๋Š” ๋ถ€๋ถ„ ๋’ค์— or nothing(|| '')์„ ์ž‘์„ฑํ•ด ์ฃผ์–ด undefined๊ฐ€ ๋œจ๋Š” ํ˜„์ƒ์„ ๋ฐฉ์ง€ํ•˜์˜€๋‹ค.

 

๐Ÿ“– TIL

css variable

CSS ๋ณ€์ˆ˜๋Š” ๋ฌธ์„œ ์ „๋ฐ˜์ ์œผ๋กœ ์žฌ์‚ฌ์šฉํ•  ์ž„์˜์˜ ๊ฐ’์„ ๋‹ด์„ ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. ์–ด๋””์„œ๋‚˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ ค๋ฉด :root์— ์ •์˜ํ•˜๋ฉด ๋œ๋‹ค. ํŠน์ • element ๋‚ด์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋„๋ก ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. CSS ๋ณ€์ˆ˜๋Š” CSS ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•  ๋•Œ์—๋Š” ๋ณ€์ˆ˜ ์•ž์— --๋ฅผ ๋ถ™์—ฌ์ฃผ๋ฉฐ, ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜๋ ค๋ฉด var() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      :root {
        --color-one: #ff8080;
        --color-two: #80dfff;
      }
      .one {
        color: var(--color-one);
      }
      .two {
        color: var(--color-two);
      }
    </style>
  </head>
  <body>
    <h1 class="one">Hello!</h1>
    <h1 class="two">Bye!</h1>
  </body>
</html>

CSS ๋ณ€์ˆ˜๋ฅผ :root์—๋งŒ ์„ ์–ธํ–ˆ์„ ๋•Œ

์ด ๋•Œ, CSS ๋ณ€์ˆ˜๋ฅผ :root ํ•˜์œ„์˜ ํŠน์ • ์š”์†Œ์— ์„ ์–ธํ•˜๊ฒŒ ๋˜๋ฉด, ํ•ด๋‹น ์š”์†Œ์— ์„ ์–ธ๋œ ์ž‘์€ ๋ฒ”์œ„์˜ CSS ๋ณ€์ˆ˜๊ฐ€ ๋จผ์ € ์ ์šฉ๋œ๋‹ค.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      :root {
        --color-one: #ff8080;
        --color-two: #80dfff;
      }
      .one {
        --color-one: #ffdf80;
        color: var(--color-one);
      }
      .two {
        color: var(--color-two);
      }
    </style>
  </head>
  <body>
    <h1 class="one">Hello!</h1>
    <h1 class="two">Bye!</h1>
  </body>
</html>

CSS ๋ณ€์ˆ˜๋ฅผ :root ํ•˜์œ„์˜ ์š”์†Œ์— ํ•œ๋ฒˆ ๋” ์„ ์–ธํ–ˆ์„ ๋•Œ

CSS ๋ณ€์ˆ˜๋Š” ์ƒ์† ๋Œ€์ƒ์ด๋ฏ€๋กœ, ํŠน์ • ์š”์†Œ์— ์‚ฌ์šฉ์ž ์ง€์ • ๊ฐ’์„ ์„ค์ •ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋Š” ๊ทธ ๋ถ€๋ชจ์˜ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ž˜์„œ CSS ๋ณ€์ˆ˜๋ฅผ ๊ณ„๋‹จ์‹ ๋ณ€์ˆ˜๋ผ๊ณ ๋„ ํ•œ๋‹ค.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      :root {
        --color-one: #ff8080;
        --color-two: #80dfff;
      }
      .one {
        --color-one: #ffdf80;
        color: var(--color-one);
      }
      .two {
        color: var(--color-two);
      }
    </style>
  </head>
  <body>
    <div class="one">
      <h1>one</h1>
      <div class="two">
        <h1>two</h1>
        <div class="three"><h1>three</h1></div>
        <div class="four"><h1>four</h1></div>
      </div>
    </div>
  </body>
</html>

three, four๊ฐ€ ๊ฐ๊ฐ์˜ ๋ถ€๋ชจ์˜ CSS ๋ณ€์ˆ˜๋ฅผ ์ƒ์†๋ฐ›๋Š” ๋ชจ์Šต

 

setProperty()

์„ ์–ธ๋œ CSS ๋ณ€์ˆ˜๋Š” JS์˜ getPropertyValue(), setProperty() ๋“ฑ์œผ๋กœ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค. 

var value = element.style.getPropertyValue(property);

getPropertyValue()๋Š” ์ธ์ˆ˜๋กœ ์ง€์ •๋œ CSS ์†์„ฑ์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

style.setProperty(propertyName, value, priority);

setProperty()๋Š” ์ธ์ˆ˜๋กœ ์ง€์ •๋œ CSS ์†์„ฑ์˜ ๊ฐ’์„ ์„ค์ •ํ•œ๋‹ค. priority(์„ ํƒ)๋Š” !important์˜ ์‚ฌ์šฉ ์—ฌ๋ถ€์ด๋‹ค.

์œ„ ๋‘๊ฐœ์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ --color-two์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ณ  ๋ณ€๊ฒฝํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      :root {
        --color-one: #ff8080;
        --color-two: #80dfff;
      }
      .one {
        --color-one: #ffdf80;
        color: var(--color-one);
      }
      .two {
        color: var(--color-two);
      }
      body {
        width: 100%;
        display: flex;
        justify-content: center;
      }
    </style>
  </head>
  <body>
    <div class="one">
      <h1>one</h1>
      <div class="two">
        <h1>two</h1>
        <div class="three"><h1>three</h1></div>
        <div class="four"><h1>four</h1></div>
      </div>
    </div>
  </body>
  <script>
    document.documentElement.style.setProperty("--color-two", `#80ff80`);
    console.log(document.documentElement.style.getPropertyValue("--color-two"));
  </script>
</html>

--color-two๊ฐ€ #80dfff์—์„œ #80ff80๋กœ ์„ค์ •(๋ณ€ํ™˜)๋˜์—ˆ๋‹ค.

 

 

 

๐Ÿ‘€ ์ฐธ๊ณ 

youtube Wes Bos

https://www.youtube.com/watch?v=AHLNzv13c2I&list=PLu8EoSxDXHP6CGK4YVJhL_VWetA865GOH&index=3 

 

https://developer.mozilla.org/ko/docs/Web/CSS/Using_CSS_custom_properties

 

https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration/setProperty