这是 James Stanley 的一个 有趣的想法:一个 CSS 文件(可能每天更新)包含“季节性”颜色的 CSS 自定义属性(例如,春季是绿色,秋季是橙色)。然后,您可以使用这些值来为您的网站设置主题,并知道这些颜色每天都会略有变化。
这是我在写这篇文章时想到的
:root {
--seasonal-bg: hsl(-68.70967741935485,9.419354838709678%,96%);
--seasonal-bgdark: hsl(-68.70967741935485,9.419354838709678%,90%);
--seasonal-fg: hsl(-68.70967741935485,9.419354838709678%,30%);
--seasonal-hl: hsl(-83.70967741935485,30.000000000000004%,50%);
--seasonal-hldark: hsl(-83.70967741935485,30.000000000000004%,35%);
}
我认为如果提供的 CSS 文件只是自定义属性,而不是带有主观意见的其他样式(比如设置主体背景),会更有趣。这样,您就可以以任何您选择的方式实现颜色,而不会产生任何副作用。
CSS 作为 API?
这让我想到,像这样的 CDN 托管的 CSS 文件可以包含其他有用的内容,比如今天的日期,用于伪内容,或者其他特殊的时间敏感内容。也许是月相?体育得分?!今日汤品?!
/* <div class="soup">The soup of the day is: </div> */
.soup::after {
content: var(--soupOfTheDay); /* lol kinda */
}
它几乎就像一个数据 API,非常易于使用。伪内容如今甚至也是可访问的内容——但您无法选择伪元素的文本,所以不要将其理解为使用 CSS 作为内容 API 的实际认可。
自定义属性的灵活性
Will Boyd 刚刚发布了一篇关于 自定义属性中可能出现的内容 的博文。它们非常灵活。几乎任何东西都是有效的自定义属性值,并且用法往往会按您预期的那样工作。
body {
/* totally fine */
--rgba: rgba(255, 0, 0, 0.1);
background: var(--rgba);
/* totally fine */
--rgba: 255, 0, 0, 0.1;
background: rgba(var(--rgba));
/* totally fine */
--rgb: 255 0 0;
--a: 0.1;
background: rgb(var(--rgb) / var(--a));
}
body::after {
/* totally fine */
--song: "I need quotes to be pseudo content \A and can't have line breaks without this weird hack \A but still fairly permissive (💧💧💧) ";
content: var(--song);
white-space: pre;
}
Bram Van Damme 在介绍 Will 的文章时,抓住了这种灵活性
这就是为什么您可以使用 CSS 自定义属性来
• 执行条件计算
Bram 指出了自定义属性可以实现的这种“基本”状态翻转功能
:root {
--is-big: 0;
}
.is-big {
--is-big: 1;
}
.block {
padding: calc(
25px * var(--is-big) +
10px * (1 - var(--is-big))
);
border-width: calc(
3px * var(--is-big) +
1px * (1 - var(--is-big))
);
}
添加几勺复杂性,您就可以得到 The Raven(使用自定义属性的媒体查询)。
我非常希望看到 CSS 中发生一些改变,使这变得更容易。使用 CSS 自定义属性来进行一般状态操作将非常棒。我们可以对 UI 处于任意状态时应用任意样式!想想媒体查询现在有多么有用,或者容器查询将有多么有用,但是由于它是任意状态,而不是这些东西所公开的状态,所以它会更加复杂。
Bram 也涵盖了这一点,他提到了 Lea Verou 所谓的 “高级自定义属性”
/* Theoretical! */
.square {
width: 2vw;
padding: 0.25vw;
aspect-ratio: 1/1;
@if (var(--size) = big) {
width: 16vw;
padding: 1vw;
}
}
.my-input {
@if(var(--pill) = on) {
border-radius: 999px;
}
}
关于命名
Will 将它们称为“CSS 变量”,这是非常常见且易于理解的。您会经常读到(我也写过)类似“CSS 变量(也称为 CSS 自定义属性)”或“CSS 自定义属性(也称为 CSS 变量)”的句子。Šime Vidas 最近 指出,有一种比较正确的称呼方式:--this-part
是自定义属性,var(--this-part)
是变量,这直接来自 规范 中的用法。
JavaScript 库状态… 自动化?
这让我回想起 这个 Vue 提案。我不确定它是否取得了进展,但想法是组件的状态将自动公开为 CSS 自定义属性。
<template>
<div class="text">Hello</div>
</template>
<script>
export default {
data() {
return {
color: 'red'
}
}
}
</script>
<style vars="{ color }">
.text {
color: var(--color);
}
</style>
由于此组件的状态包含color
,因此--color
将作为状态提供给此组件的 CSS。我认为这是一个好主意。
如果每次在 React 中使用useState
时,CSS 自定义属性都会被放到:root
上并自动更新,会怎么样?例如,如果您这样做
import React, { useState } from 'https://cdn.skypack.dev/react@^16.13.1';
import ReactDOM from 'https://cdn.skypack.dev/react-dom@^16.13.1';
const App = () => {
const [ activeColor, setActiveColor ] = useState("red");
return(
<div className="box">
<h1>Active Color: {activeColor}</h1>
<button onClick={() => {setActiveColor("red")}}>red</button>
<button onClick={() => {setActiveColor("blue")}}>blue</button>
</div>
);
}
ReactDOM.render(<App />,
document.getElementById("root"))
并且您知道您可以像这样操作
.box {
border-color: 2px solid var(--activeColor);
}
因为状态自动映射到自定义属性。有人应该创建一个useStateWithCustomProperties
钩子或类似的东西来实现这一点。#免费想法
像 React 和 Vue 这样的库用于构建 UI。我认为他们管理的状态自动公开给 CSS 是很有意义的。
浏览器可以为我们提供更多页面状态作为环境变量吗?
说到 CSS 应该了解的状态,我已经看到了不少演示,它们通过将鼠标当前位置或滚动位置映射到 CSS 来实现有趣的功能。我认为要求将这些数据以原生方式公开给 CSS 并不完全不合理。我们已经有了环境变量的概念,比如env(safe-area-inset-top)
,我可以想象它可以用来公开页面状态,比如env(page-scroll-percentage)
或env(mouseY)
。
这看起来确实很棒!我想补充一点,如果你使用 Sass,它会在处理一些东西时为了速度而向下取整小数。如果你需要特别长且精确的小数,比如用于 hsl,请参考 Sass 文档,了解如何设置 –precision 来处理这些情况。
这听起来像是 JS 中被污染的
window
对象,存在着不受任何范围限制的全局变量。难道这不会再次变成一团糟吗?您可以将这些变量的范围限定在组件的根元素。或者不。
rgb(var(--rgb) / var(--a))
嗨 Chris,一如既往的好文章!
我对这部分感到困惑,它是否应该让主体背景变透明?在我的测试中它没有生效,而且我以前从未见过这种情况。
看这里:https://css-tricks.org.cn/no-comma-color-functions-in-css/
是的,环境变量会非常有用。我希望它成为现实…
如果我是第一个做这件事的人,我会感到很惊讶,但我还是继续创建了您提到的自定义钩子。这个钩子可以让您将 React 状态注入到 CSS 变量中。:)
https://npmjs.net.cn/package/use-state-in-custom-properties
我认为非常棒!
我实际上曾经做过这件事——用
useState
控制 CSS 自定义属性我只是将自定义属性添加到 style 属性,并在我的 CSS 中捕获了该值。
对于简单的样式来说,这样做是可以的,但对于伪内容,出于可访问性原因,我不推荐这样做。并非所有屏幕阅读器都能访问这些内容,并且以这种方式添加的非装饰性内容被认为是 WCAG 指导方针 1.3.1 的失败 (https://www.w3.org/WAI/WCAG21/Techniques/failures/F87 )