aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/css/using_css_custom_properties
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:40:17 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:40:17 -0500
commit33058f2b292b3a581333bdfb21b8f671898c5060 (patch)
tree51c3e392513ec574331b2d3f85c394445ea803c6 /files/zh-cn/web/css/using_css_custom_properties
parent8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff)
downloadtranslated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz
translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2
translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip
initial commit
Diffstat (limited to 'files/zh-cn/web/css/using_css_custom_properties')
-rw-r--r--files/zh-cn/web/css/using_css_custom_properties/index.html275
1 files changed, 275 insertions, 0 deletions
diff --git a/files/zh-cn/web/css/using_css_custom_properties/index.html b/files/zh-cn/web/css/using_css_custom_properties/index.html
new file mode 100644
index 0000000000..daeae20d1a
--- /dev/null
+++ b/files/zh-cn/web/css/using_css_custom_properties/index.html
@@ -0,0 +1,275 @@
+---
+title: 使用CSS自定义属性(变量)
+slug: Web/CSS/Using_CSS_custom_properties
+tags:
+ - ':root'
+ - CSS
+ - Using CSS variables
+ - variable
+translation_of: Web/CSS/Using_CSS_custom_properties
+---
+<div><strong>自定义属性</strong>(有时候也被称作<strong>CSS变量</strong>或者<strong>级联变量</strong>)是由CSS作者定义的,它包含的值可以在整个文档中重复使用。由自定义属性标记设定值(比如: <strong><code>--main-color: black;</code></strong>),由<a href="/zh-CN/docs/Web/CSS/var">var() </a>函数来获取值(比如: <code>color: <strong>var(--main-color)</strong>;</code>)</div>
+
+<div></div>
+
+<div>复杂的网站都会有大量的CSS代码,通常也会有许多重复的值。举个例子,同样一个颜色值可能在成千上百个地方被使用到,如果这个值发生了变化,需要全局搜索并且一个一个替换(很麻烦哎~)。自定义属性在某个地方存储一个值,然后在其他许多地方引用它。另一个好处是语义化的标识。比如,<code>--main-text-color</code> 会比 <code>#00ff00</code> 更易理解,尤其是这个颜色值在其他上下文中也被使用到。</div>
+
+<div></div>
+
+<div>自定义属性受级联的约束,并从其父级继承其值。</div>
+
+<h2 id="基本用法">基本用法</h2>
+
+<p>声明一个自定义属性,属性名需要以两个减号(<code>--</code>)开始,属性值则可以是任何有效的CSS值。和其他属性一样,自定义属性也是写在规则集之内的,如下:</p>
+
+<pre class="brush:css; highlight:[2] language-css notranslate">element {
+ --main-bg-color: brown;
+}
+</pre>
+
+<p>注意,规则集所指定的选择器定义了自定义属性的可见作用域。通常的最佳实践是定义在根伪类 {{cssxref(":root")}} 下,这样就可以在HTML文档的任何地方访问到它了:</p>
+
+<pre class="brush: css notranslate">:root {
+ --main-bg-color: brown;
+}</pre>
+
+<p>然而这条规则不是绝对的,如果有理由去限制你的自定义属性,那么就应该限制。</p>
+
+<div class="blockIndicator note">
+<p><strong>注意:</strong>自定义属性名是大小写敏感的,<code>--my-color</code> 和 <code>--My-color</code> 会被认为是两个不同的自定义属性。</p>
+</div>
+
+<p>如前所述,使用一个局部变量时用 {{cssxref("var()")}} 函数包裹以表示一个合法的属性值:</p>
+
+<pre class="brush:css; highlight:[2] language-css notranslate">element {
+ background-color: var(--main-bg-color);
+}
+</pre>
+
+<h2 id="使用自定义属性的第一步">使用自定义属性的第一步</h2>
+
+<p>我们从这个简单的CSS代码开始,它将相同的颜色应用在了不同class的元素上:</p>
+
+<pre class="brush: css notranslate"><code>.one {
+ color: white;
+ background-color: brown;
+ margin: 10px;
+ width: 50px;
+ height: 50px;
+ display: inline-block;
+}
+
+.two {
+ color: white;
+ background-color: black;
+ margin: 10px;
+ width: 150px;
+ height: 70px;
+ display: inline-block;
+}
+.three {
+ color: white;
+ background-color: brown;
+ margin: 10px;
+ width: 75px;
+}
+.four {
+ color: white;
+ background-color: brown;
+ margin: 10px;
+ width: 100px;
+}
+
+.five {
+ background-color: brown;
+}</code>
+</pre>
+
+<p>应用在如下HTML上:</p>
+
+<pre class="brush: html notranslate"><code>&lt;div&gt;
+ &lt;div class="one"&gt;1:&lt;/div&gt;
+ &lt;div class="two"&gt;2: Text &lt;span class="five"&gt;5 - more text&lt;/span&gt;&lt;/div&gt;
+ &lt;input class="three"&gt;
+ &lt;textarea class="four"&gt;4: Lorem Ipsum&lt;/textarea&gt;
+&lt;/div&gt;</code>
+</pre>
+
+<p>其呈现是:</p>
+
+<p>{{EmbedLiveSample("First_steps_with_custom_properties",600,180)}}</p>
+
+<p>注意到在CSS代码中的重复:背景色 <code>brown</code> 被多处设置。对于一些CSS声明,是可以在级联关系更高的位置设置,通过CSS继承自然地解决这个重复的问题。但在一般项目中,是不可能通过这样的方式去解决。通过在 {{cssxref(":root")}} 伪类上设置自定义属性,然后在整个文档需要的地方使用,可以减少这样的重复性:</p>
+
+<pre class="brush: css notranslate"><code>:root {
+ --main-bg-color: brown;
+}
+
+.one {
+ color: white;
+ background-color: var(--main-bg-color);
+ margin: 10px;
+ width: 50px;
+ height: 50px;
+ display: inline-block;
+}
+
+.two {
+ color: white;
+ background-color: black;
+ margin: 10px;
+ width: 150px;
+ height: 70px;
+ display: inline-block;
+}
+.three {
+ color: white;
+ background-color: var(--main-bg-color);
+ margin: 10px;
+ width: 75px;
+}
+.four {
+ color: white;
+ background-color: var(--main-bg-color);
+ margin: 10px;
+ width: 100px;
+}
+
+.five {
+ background-color: var(--main-bg-color);
+}</code>
+</pre>
+
+<p>这里呈现的结果和前面的例子是一致的,但允许对所需属性值进行一个规范的声明。</p>
+
+<h2 id="自定义属性的继承性">自定义属性的继承性</h2>
+
+<p>自定义属性会继承。这意味着如果在一个给定的元素上,没有为这个自定义属性设置值,在其父元素上的值会被使用。看这一段HTML:</p>
+
+<pre class="notranslate"><code>&lt;div class="one"&gt;
+ &lt;div class="two"&gt;
+ &lt;div class="three"&gt;&lt;/div&gt;
+ &lt;div class="four"&gt;&lt;/div&gt;
+ &lt;/div&gt;
+&lt;/div&gt;</code>
+</pre>
+
+<p>配套的CSS:</p>
+
+<pre class="notranslate"><code>.two {
+ --test: 10px;
+}
+
+.three {
+ --test: 2em;
+}</code></pre>
+
+<p>在这个情况下, <code>var(--test)</code> 的结果分别是:</p>
+
+<ul>
+ <li>对于元素 <code>class="two"</code> :<code>10px</code></li>
+ <li>对于元素 <code>class="three"</code> :<code>2em</code></li>
+ <li>对于元素 <code>class="four"</code> :<code>10px</code> (继承自父属性)</li>
+ <li>对于元素 <code>class="one"</code> :<em>非法值</em>,会变成自定义属性的默认值</li>
+</ul>
+
+<p>注意,这些是自定义属性,并不是你在其他编程语言中遇到的实际的变量。这些值仅当需要的时候才会计算,而并不会按其他规则进行保存。比如,你不能为元素设置一个属性,然后让它从兄弟或旁支子孙规则上获取值。属性仅用于匹配当前选择器及其子孙,这和通常的CSS是一样的。</p>
+
+<h2 id="自定义属性备用值">自定义属性备用值</h2>
+
+<p>用 {{cssxref("var()")}} 函数可以定义多个<strong>备用值</strong>(fallback value),当给定值未定义时将会用备用值替换。这对于 <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements">Custom Elements</a> 和 <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM">Shadow DOM</a> 都很有用。</p>
+
+<div class="blockIndicator note">
+<p><strong><u>备用值</u>并不是用于实现浏览器兼容性的。</strong>如果浏览器不支持CSS自定义属性,备用值也没什么用。<strong>它仅对支持CSS自定义属性的浏览器提供了一个备份机制</strong>,该机制仅当给定值未定义或是无效值的时候生效。</p>
+</div>
+
+<p>函数的第一个参数是<a href="https://www.w3.org/TR/css-variables/#custom-property">自定义属性</a>的名称。如果提供了第二个参数,则表示备用值,当<a href="https://www.w3.org/TR/css-variables/#custom-property">自定义属性</a>值无效时生效。第二个参数可以嵌套,但是不能继续平铺展开下去了,例如:</p>
+
+<pre class="brush: css notranslate">.two {
+ color: var(--my-var, red); /* Red if --my-var is not defined */
+}
+
+.three {
+ background-color: var(--my-var, var(--my-background, pink)); /* pink if --my-var and --my-background are not defined */
+}
+
+.three {
+ background-color: var(--my-var, --my-background, pink); /* Invalid: "--my-background, pink" */
+}</pre>
+
+<p>第二个例子展示了如何处理一个以上的 fallback。该技术可能会导致性能问题,因为它花了更多的时间在处理这些变量上。</p>
+
+<div class="blockIndicator note">
+<p><strong>注意:</strong>像<a href="https://www.w3.org/TR/css-variables/#custom-property">自定义属性</a>这些 fallback 语法允许使用逗号。比如 <code>var(--foo, red, blue)</code> 定义了一个 <code>red, blue</code> 的备用值——从第一个逗号到最后的全部内容,都会被作为备用值的一部分。</p>
+</div>
+
+<h2 id="有效性和值">有效性和值</h2>
+
+<p>传统的CSS概念里,有效性和属性是绑定的,这对自定义属性来说并不适用。当自定义属性值被解析,浏览器不知道它们什么时候会被使用,所以必须认为这些值都是<em>有效的</em>。</p>
+
+<p>不幸的是,即便这些值是有效的,但当通过 <code>var()</code> 函数调用时,它在特定上下文环境下也可能不会奏效。属性和自定义变量会导致无效的CSS语句,这引入了一个新的概念:<em>计算时有效性</em>。</p>
+
+<h2 id="无效变量会导致什么?">无效变量会导致什么?</h2>
+
+<p>当浏览器遇到无效的 <code>var()</code> 时,会使用继承值或初始值代替。</p>
+
+<p>考虑如下代码:</p>
+
+<h3 id="HTML">HTML</h3>
+
+<pre class="brush: html notranslate">&lt;p&gt;This paragraph is initial black.&lt;/p&gt; </pre>
+
+<h3 id="CSS">CSS</h3>
+
+<pre class="brush: css notranslate">:root { --text-color: 16px; }
+p { color: blue; }
+p { color: var(--text-color); }
+</pre>
+
+<p>毫不意外,浏览器将 <code>--text-color</code> 的值替换给了 <code>var(--text-color)</code>,但是 <code>16px</code> 并不是 {{cssxref("color")}} 的合法属性值。代换之后,该属性不会产生任何作用。浏览器会执行如下两个步骤:</p>
+
+<ol>
+ <li>检查属性 color 是否为继承属性。是,但是 <code>&lt;p&gt;</code> 没有任何父元素定义了 color 属性。转到下一步。</li>
+ <li>将该值设置为它的<strong>默认初始值</strong>,比如 black。</li>
+</ol>
+
+<h3 id="Result">Result</h3>
+
+<p>{{EmbedLiveSample('What_happens_with_invalid_variables')}}</p>
+
+<p>段落颜色并不是蓝色,因为无效代换导致了它被替换成了默认初始值的黑色。如果你直接写n <code>color: 16px</code> 的话,则会导致语法错误,而前面的定义则会生效(段落显示为蓝色)。</p>
+
+<div class="note">
+<p><strong>注意:</strong>当CSS属性-值对中存在语法错误,该行则会被忽略。然而如果自定义属性的值无效,它并不会被忽略,从而会导致该值被覆盖为默认值。</p>
+</div>
+
+<h2 id="JavaScript_中的值">JavaScript 中的值</h2>
+
+<p>在 JavaScript 中获取或者修改 CSS  变量和操作普通 CSS 属性是一样的:</p>
+
+<pre class="notranslate">// 获取一个 Dom 节点上的 CSS 变量
+element.style.getPropertyValue("--my-var");
+
+// 获取任意 Dom 节点上的 CSS 变量
+getComputedStyle(element).getPropertyValue("--my-var");
+
+// 修改一个 Dom 节点上的 CSS 变量
+element.style.setProperty("--my-var", jsVar + 4);</pre>
+
+<h2 id="Browser_compatibility" name="Browser_compatibility">浏览器支持</h2>
+
+<p>{{Compat("css.properties.custom-property")}}</p>
+
+<div class="blockIndicator note">
+<p><strong>注意:</strong>自定义属性的前缀 <code>var-</code> 是早期标准规定的,后期改为了 <code>--</code>。Firefox 31 和以后的版本遵循新的标准。 ({{bug(985838)}})</p>
+</div>
+
+<article class="approved">
+<div class="boxed translate-rendered text-content">
+<h2 id="参见">参见</h2>
+
+<ul>
+ <li>{{cssxref("--*", "Custom properties")}}</li>
+</ul>
+</div>
+</article>