> For the complete documentation index, see [llms.txt](https://lochiwei.gitbook.io/web/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lochiwei.gitbook.io/web/css/var.md).

# variables

a.k.a css custom properties

🔸 [Valid Names](/web/css/var.md#valid-names) ┊ [Cheatsheet](/web/css/var.md#cheatcheet) ┊ [Key Points](/web/css/var.md#key-points)

```css
:root {
    /* ⭐️ define css vars */
    --panel-bg: #fff;
    --panel-color: #000;
}

.panel {
    /* ⭐️ use css vars */
    color: var(--panel-color);
    background-color: var(--panel-bg);
}
```

{% tabs %}
{% tab title="📗 文章" %}

* [ ] CSSTricks ⟩&#x20;
  * [The Big Gotcha With Custom Properties](https://css-tricks.com/the-big-gotcha-with-custom-properties/) ⭐️ - 改變 CSS 變數如何影響其他屬性❗️
  * [Updating a CSS Variable with JavaScript](https://css-tricks.com/updating-a-css-variable-with-javascript/) - update with "**mousemove**" events
* [ ] [--css variables](https://dev.to/turpp/css-variables-1o8a)
* [ ] JS.info ⟩ [Computed styles: getComputedStyle](https://javascript.info/styles-and-classes#computed-styles-getcomputedstyle)
  {% endtab %}

{% tab title="📘 手冊" %}

* MDN ⟩ CSS functions ⟩ [var()](https://developer.mozilla.org/en-US/docs/Web/CSS/var\(\))
  {% endtab %}

{% tab title="👥 相關" %}

* Shadow DOM ⟩ [Use CSS Variables](/web/component/shadow-dom/styles/css-vars.md)
* Element ⟩ [.styleProp()](/web/browser/dom/type/element/+ext/.styleprop.md)
* <mark style="color:yellow;">**styles**</mark> in [shadow DOM](/web/component/shadow-dom.md) can use [variables](/web/css/var.md) defined in [<mark style="color:yellow;">**light DOM**</mark>](/web/component/light-dom.md).
  {% endtab %}
  {% endtabs %}

## Valid Names

{% tabs %}
{% tab title="valid vs invalid names" %}
{% hint style="info" %}
**⭐️ valid** CSS variable **names** ( begin with **two dashes** "**`--`**" ❗️):

```css
/* ✅ valid names */
--spacing: var(--line_height);
--spacing_1: calc(var(--spacing) * var(--scale));
--spacing_2: calc(var(--spacing_1) * var(--scale));
--spacing_-1: calc(var(--spacing) / var(--scale));

/* ❌ not valid names */
--spacing_+1:    
```

{% endhint %}
{% endtab %}

{% tab title="💾 程式" %}

* CodeSandbox ⟩ [--css-var+1 valid name?](https://codesandbox.io/s/--css-var-1-valid-name-5v3oe?file=/src/styles.css)
  {% endtab %}
  {% endtabs %}

## Cheatcheet

{% tabs %}
{% tab title="CSS" %}

```css
:root { 
    /* ⭐️ CSS variable */
    --main-font: Helvetica, Arial, sans-serif; 
}

p {
    /* ⭐️ use var() to reference the variable */
    font-family: var(--main-font); 
}
```

{% endtab %}

{% tab title="JS" %}

```javascript
// ⭐️ set
elem.style.setProperty('--panel-bg', '#cdf');

// ⭐️ get
var styles = getComputedStyle(elem);
var bg = styles.getPropertyValue('--panel-bg');

console.log(bg.trim());

```

{% endtab %}

{% tab title="🧨 陷阱" %}

```css
html {
  --color-1: red;
  --color-2: blue;
}

div {

  height: 50px;
  border: 1px solid black;
  margin-bottom: 10px;
  
  /*  
    ⭐️ 注意：
       如果此行放在上面 html { ... } 中，下面 .variation 的設定就會無效❗️ 
  
       理論上，更新 `--color-1` 應該也會帶動更新 `--bg` 才對，但這只是
       「一廂情願」的想法，CSS 實際上並不會因為更新 `--color-1` 而主動
       更新 <div> 中的 var(--bg)，除非我們將 `--bg` 的定義直接放在使用 
       var(--bg) 的 <div> 身上❗️
  */
  --bg: linear-gradient(to right, var(--color-1), var(--color-2));
  
  background: var(--bg);
}

.variation {
  --color-1: green;
}
```

{% embed url="<https://codepen.io/lochiwei/pen/abwMdev>" %}
{% endtab %}

{% tab title="📘 手冊" %}

* **Window** ⟩ .[getComputedStyle](https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle)() - returns an **object** (***live*** [`CSSStyleDeclaration`](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration) object) containing the values of all **CSS properties** of an element.
* **CSSStyleDeclaration** ⟩&#x20;
  * .[getPropertyValue](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration/getPropertyValue)() : [`DOMString`](https://developer.mozilla.org/en-US/docs/Web/API/DOMString) `| ''`
  * .[setProperty](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration/setProperty)()

```javascript
window.getComputedStyle(elem);
window.getComputedStyle(elem, pseudoElem);

// style get/set property
var value = style.getPropertyValue(prop);
style.setProperty(prop, value, priority);
```

{% endtab %}

{% tab title="📗 參考" %}

* [ ] JS.info ⟩ [Computed styles: getComputedStyle](https://javascript.info/styles-and-classes#computed-styles-getcomputedstyle)
  {% endtab %}

{% tab title="👥 相關" %}

* Element ⟩ [.styleProp()](/web/browser/dom/type/element/+ext/.styleprop.md)
  {% endtab %}
  {% endtabs %}

## key points

* The **custom properties** behave as a sort of **scoped variable** because the values are **inherited** by descendant elements.

## redefine css vars

{% tabs %}
{% tab title="Result" %}
{% embed url="<https://codepen.io/lochiwei/pen/LYyMjRq>" %}
{% endtab %}

{% tab title="CSS" %}

```css
:root {
    /* ⭐️ define css vars */
    --panel-bg: #fff;
    --panel-color: #000;
}

.panel {
    padding: 0.5em 1em;
    border: 1px solid #999;
    border-radius: 0.5em;

    /* ⭐️ use css vars */
    color: var(--panel-color);
    background-color: var(--panel-bg);
}

.panel > h2 {
    margin-block-start: 0;
    font-size: 0.8em;
    font-weight: 900;
    text-transform: uppercase;
}

.dark {
    margin-block-start: 1em;

    /* ⭐️ redefine css vars */
    --panel-bg: #333;
    --panel-color: #fff;
}
```

{% endtab %}

{% tab title="JS" %}

```javascript
var root = document.documentElement;    // <html> element
var styles = getComputedStyle(root);

// get property value
var bg = styles.getPropertyValue('--panel-bg'); 
console.log(bg.trim());                 // #fff

// set property value
root.style.setProperty('--panel-bg', '#cdf');

// ------------ helpers --------------
// $ ⭐️
function $(selector, parent = document){
  return parent.querySelector(selector);
}

// $all ⭐️
function $all(selector, parent = document){
  return parent.querySelectorAll(selector);
}
```

{% endtab %}

{% tab title="HTML" %}

```markup
<!-- A regular panel on the page -->
<div class="panel">
  <h2>Light Version</h2>
  <div class="body">
    We have built partnerships with small farms around the world to hand-select beans at the peak of season. We then careful roast in small batches to maximize their potential.
  </div>
</div>

<aside class="dark">
  <!-- The second panel inside a dark container -->
  <div class="panel">
    <h2>Dark Version</h2>
    <div class="body">
      We have built partnerships with small farms around the world to hand-select beans at the peak of season. We then careful roast in small batches to maximize their potential.
    </div>
  </div>
</aside>
```

{% endtab %}
{% endtabs %}
