如何使用环境变量来指定CSS中的基色?

我使用NEXTJS

我的 colored颜色 都定义为globals.css中的变量:

@layer base {
   :root {
      ...
      --primary: #0096d0;
      --primary-bright: hsl(from var(--primary) h s calc(l*1.5));
      ...

我试

--PRIMARY:env(Next_PUBLIC_PRIMAL_COLOR,#0096d0);

但是env变量被忽略了

有什么 idea 吗?

推荐答案

虽然env()可以使用自定义属性,但它从UA-defined environment variables读取,而不是从客户端发布的NEXT_PUBLIC_个变量读取,而且肯定不是从服务器端环境变量读取.虽然future 我们might能够add custom environment variables via JS or CSS,但目前你还不能定义客户端Custom CSS Environment Variables.

因此,现在你需要考虑使用CSS预处理器、JSX中的内联样式或PostCSS插件.它们都有自己的缺点.

内联样式

最大的缺点是它不能像你那样在global.css中使用.但是,它的优点是你可以按照你想要的方式创建style对象.您还可以更新style对象并在应用程序运行后触发更新.(请注意,所有NEXT_PUBLIC_个变量将在运行时被冻结,无法更新.

倒数index.js:

//this can be created dynamically by looping over keys in .env.local
const style = {"--primary": process.env.NEXT_PUBLIC_PRIMARY_COLOR ?? '#0096d0'}
<div style={style}>
    <MyRoot></MyRoot>
</div>

CSS预处理器

以下是一个将特定环境变量导入scss变量的示例设置.

首先,按照Next文档Styling with SCSS安装SASS:

npm install --save-dev sass

next.config.js中,在sass变量前面加上:

const nextConfig = {
  sassOptions: {
    additionalData: Object.keys(process.env).reduce((accumulator, currentValue) => {
      if (currentValue.startsWith('NEXT_THEME_')) {
        return `${accumulator}$${currentValue}: ${process.env[currentValue]};`
      }
      else {
        return accumulator
      }
    }, ''),
    includePaths: [path.join(__dirname, 'styles')],
  }
}

倒数.env.local:

NEXT_THEME_PRIMARY_COLOR=red
NEXT_THEME_SECONDARY_COLOR='#fff'

然后,您可以通过以下方式使用globals.scss中的环境变量:

@layer base {
  :root {
    --primary: #{$NEXT_THEME_PRIMARY_COLOR};
  }
}

缺点是SCSS是"预处理"的,这意味着SCSS变量也不存在,供您在JS运行时更新.此外,环境变量必须始终呈现,否则您需要显式使用variable-exists()!default,这有点冗长.例如:

:root {
  --primary: #0096d0;
  @if variable-exists(NEXT_THEME_PRIMARY_COLOR) {
    --primary: #{$NEXT_THEME_PRIMARY_COLOR};
  }
}

PostCSS插件

因为你使用Nextjs,PostCSS和一些插件已经内置.然而,目前没有一个内置的符合您的需求.你需要find a plugin个或实现一个解决你的问题.

一个例子是postcss-functions插件,它允许你定义自己的env函数,从环境变量中读取.

倒数postcss.config.js:

const theme = Object.keys(process.env).reduce((accumulator, currentValue) => {
  if (currentValue.startsWith('NEXT_THEME_')) {
    accumulator[currentValue] = process.env[currentValue];
    return accumulator;
  }
  else {
    return accumulator
  }
}, {})

function getEnv(variable, fallback = null) {
  return theme[variable] ?? fallback;
}

module.exports = {
  "plugins": {
    "postcss-functions": {
      "functions": {
        getEnv
      }
    },
  }
}

然后您可以在global al.css中使用它,如下所示:

@layer base {
  :root {
    --primary: getEnv(NEXT_THEME_PRIMARY_COLOR, #0096d0);
  }
}

Css相关问答推荐

Tailwind CSS group-hover不适用于自定义前置码

将照片向下对齐至div并保持响应性

如何将CSS Paint API与Reaction一起使用

如何使用css::Part()定位Web组件shadowDOM中的第N个元素

如何使背景出现在具有自己背景 colored颜色 的子元素上

如何使shiny 的showNotification可滚动?

为什么align-content:start应用于单行项目?

Vuetify 抽屉标签溢出/z-index

在具有特定类的 td 之后,如何编写适用于该行上所有 td 元素的表行的 CSS Select 器?

如何在不使用 !important 的情况下提高优先级?

CSS 字符串变量的正确null值是多少?

zoom 时闪烁的背景滤镜模糊

使用border-radius时填充元素之间的空间

在 IE9-10 中压缩 SVG 的背景大小

下拉框中溢出文本的省略号

通过javascript删除或禁用浏览器的焦点边框

CSS - 使 div 水平对齐

CSS:悬停一个元素,多个元素的效果?

CSS3单向过渡?

为什么容器 div 坚持比 IMG 或 SVG 内容略大?