CSS / 前端技術 / 筆記 · 2020-12-11

CSS :root 根目錄選取

:root

利用根目錄選取器,自定義CSS屬性,並套用於元素。
自定義屬性 Custom properties (sometimes referred to as CSS variables or cascading variables)

☞ 基本語法使用

使用以雙連字符(–)開頭的自定義屬性名稱,可以使用CSS屬性來自定義屬性。
PS.自定義名稱可依大小寫區分,例:–my-color與–My-color兩者可單獨定義。

透過 :root 定義共同屬性

:root {
–自定義名稱: 屬性值; /* 自定義屬性變數 */
}
element {
屬性: var(–自定義名稱); /* 套用屬性變數 */
}

/* css範例-基本使用*/

/*自定義全域變數屬性 */
:root {
 --maincolor: black; 
 --secondarycolor: red;
 background: #ff0000;  /* 自定義屬性,套用<html>背景 */
}
/* 套用屬性變數 */
body {
 background: var(--maincolor);
 color: white;
}
body p {
 background: var(--secondarycolor);
}
a {   
 color: var(--maincolor);  
 text-decoration-color: var(--secondarycolor); 
}
/* css範例-重複元素套用範例*/

/*自定義全域變數屬性 */
:root {
  --main-bg-color: brown; 
}

/* 套用屬性變數 */
.one {
  background-color: var(--main-bg-color);
}
.two {
  background-color: black; 
}
.three {
  background-color: var(--main-bg-color);
}

透過CSS標籤定義元素屬性

element (父元素) {
–自定義名稱: 屬性值; /* 自定義屬性變數 */
}
element (子元素){
屬性: var(–自定義名稱); /* 套用屬性變數 */
}

/* css範例-元素使用*/

root {
 --darkborder: 5px solid black;
}
body {
 --darkborder: 1px solid darkred;
}
img{
 border: var(--darkborder); /* img border will be 1px solid darkred */
}
/* css範例-套用元素,子元素也會繼承*/

:root {
 --myborder: 2px solid black;
}
ul {
 margin: 0;
 border-left: var(--myborder);
}
ul ul {
 margin-left: 30px;
}
/* html範例-屬性值使用於html*/

<!--HTML-->
<html style="--size: 600px">

body {
  max-width: var(--size)
}
/* css範例-在自定義屬性中,使用自定義屬性*/

--base-red-color: #f00;
--background-gradient: linear-gradient(to top, var(--base-red-color), #222);
/* css範例-使用在@media screen(不同裝置尺寸) */
:root {
	--padding: 15px 
}

@media screen and (min-width: 750px) {
	--padding: 30px
}

☞ 基本使用範例

繼承運用

不同元素自定義同個屬性名稱,設定不同屬性值,根據有無定義值而呈現不同效果

/* css範例-繼承運用*/

/* 自定義屬性變數 */
:root { --bg-color: #eeeeee;} 
h3    { --bg-color: #d826c1;}
#text-1 { --bg-color: #94a437;}
.text-2 { --bg-color: #d9444a;}

/* 將--bg-color套用至所有元素 */
* {
  background: var(--bg-color); 
}
<!--html範例-繼承運用-->

<section><!-- section無自定義,繼承 root 的設定-->
  <p>無自定義,繼承 root 的設定</p>
  <h3>繼承 h3 的設定</h3>
  <div id="text-1">繼承 #text-1 的設定</div>
  <div class="text-2">繼承 .text-2 的設定</div>
</section>

fallback 運用

element : var(–自定義屬性名稱, fallback屬性值,例:blue);

/* css範例-fallback 運用*/

#main {
  --bg-color: red;
}

#main .header {
  background: var(--header-color, blue);
  /* 沒有 --header-color,顯示 fallback color: 藍色 */
}

#main .text {
  background: var(--bg-color, black);
  /* 有 --bg-color,顯示紅色 */
}
/* css範例-fallback 繼承範例*/

template-default {
  --bg-color: #d9444a;
}

p {
  background: var(--bg-color, #369);
}
<!--html範例-fallback 繼承範例-->

<template-default>
繼承 template-default 的 --bg-color 
</template-default>

<p>不在 tempalte-default內,無 --bg-color ,顯示 fallback #369</p>

☞ 使用 JavaScript 定義屬性的值

讀取:getPropertyValue()
寫入:setProperty()

var styles = getComputedStyle(document.documentElement);
var value = String(styles.getPropertyValue('--bg-primary-color')).trim();

/* 讀取背景顏色 */
document.getElementById("color-name").innerHTML=value;

/* 修改背景顏色 */
document.documentElement.style.setProperty('--bg-primary-color', '#369');
// get variable from inline style
element.style.getPropertyValue("--my-var");

// get variable from wherever
getComputedStyle(element).getPropertyValue("--my-var");

// set variable on inline style
element.style.setProperty("--my-var", jsVar + 4);

改變背景範例

/*css範例-改變背景*/
body {
  background-color: var(--bg, #b3e5fc);
  color: var(--bg-text, #37474f);
  font-family: sans-serif;
  line-height: 1.3;
}

.toolbar {
  text-align: center;
}
<!--html範例-改變背景-->
<div class="toolbar">
    <button value="dark">dark</button>
    <button value="calm">calm</button>
    <button value="light">light</button>
</div>

<h2>Stackoverflow Question</h2>
I would like to use an external javascript file in another javascript file. For example, I could store all my global variables
in a globals.js file and then call then from the website logic logic.js. Then in the index.html, i would insert the tag.
How do I use the globals.js inside the logic.js?

<h2>Stackoverflow Answer</h2>
Javascript doesn't have any implicit "include this other file" mechanisms, like css's @include. You just have to list your
globals file before the logic file in the tags:

<pre>
<code>
script type="text/javascript" src="globals.js"
</code>
</pre>
If guaranteeing that the globals are available before anything in the logic file fires up, you can do a slow polling loop
to see if some particular variable is available before calling an init() or whatever function.
//js範例-改變背景
const root = document.documentElement;
const themeBtns = document.querySelectorAll(".toolbar > button");

themeBtns.forEach(btn => {
  btn.addEventListener("click", handleThemeUpdate);
});

function handleThemeUpdate(e) {
  switch (e.target.value) {
    case "dark":
      root.style.setProperty("--bg", "black");
      root.style.setProperty("--bg-text", "white");
      break;
    case "calm":
      root.style.setProperty("--bg", "#B3E5FC");
      root.style.setProperty("--bg-text", "#37474F");
      break;
    case "light":
      root.style.setProperty("--bg", "white");
      root.style.setProperty("--bg-text", "black");
      break;
  }
}