如何在CSS中将颜色定义为变量?


216

我正在处理一个很长的CSS文件。我知道客户可以要求更改配色方案,并且想知道:是否可以将颜色分配给变量,以便我可以更改变量以将新颜色应用于使用该颜色的所有元素?

请注意,我不能使用PHP动态更改CSS文件。




Answers:


224

CSS本身通过CSS Variables支持此功能。

示例CSS文件

:root {
    --main-color:#06c;
}

#foo {
    color: var(--main-color);
}

有关工作示例,请参阅此JSFiddle(该示例显示了提琴中的一个CSS选择器的颜色已硬编码为蓝色,另一个CSS选择器使用原始和当前语法的CSS变量将颜色设置为蓝色) 。

在JavaScript /客户端中处理CSS变量

document.body.style.setProperty('--main-color',"#6c0")

所有现代浏览器均支持

Firefox 31 +,Chrome 49 +,Safari 9.1 +,Microsoft Edge 15+和Opera 36+附带对CSS变量的本机支持。


3
以防万一其他人读到它并尝试使其在Safari中工作-2013年春/夏似乎已从Webkit中删除了对CSS的支持。bugs.webkit.org / show_bug.cgi? id= 114119 listing.webkit.org /pipermail/webkit-dev/2013-April/024476.html启用上述标记后,仍可在Chrome中使用。
— 玛丽·菲舍尔

在chrome 36上测试,即使启用了该标志也无法正常工作。虽然仍然可以与Firefox一起使用
— yuvi 2014年

刚刚用Chrome版本49.0.2623.110 m检查了一下,它仍然不起作用。
— radu 2016年

您的操作系统是什么?它为我工作:Mac OS X上的版本49.0.2623.110(64位)
— Arthur Weborg '16

也适用于我的Android的Chrome版本Android 5.1.0 Chrome 49.0.2623.105
— Arthur Weborg 2016年

66

人们不断upvoting我的答案,但相比的喜悦这是一个可怕的解决方案SASS或更少,特别是考虑到方便的使用数量GUI的两种这些天。如果您有任何想法,请忽略以下所有建议。

您可以在每种颜色之前的css中添加注释,以用作一种变量,您可以更改使用查找/替换的值,因此...

在css文件的顶部

/********************* Colour reference chart****************
*************************** comment ********* colour ******** 

box background colour       bbg              #567890
box border colour           bb               #abcdef
box text colour             bt               #123456

*/

稍后在CSS文件中

.contentBox {background: /*bbg*/#567890; border: 2px solid /*bb*/#abcdef; color:/*bt*/#123456}

然后,例如,更改您在其中查找/替换的框文本的配色方案

/*bt*/#123456

3
在某些情况下,例如使用IE过滤器时,添加注释将不起作用。我不能在这里添加评论->过滤器:progid:DXImageTransform.Microsoft.gradient(startColorstr ='#3f5619',endColorstr ='#77842f',GradientType = 0); / * IE6-9 * /
— 卡特

1
因为您是对的而被否决,这是一个糟糕的解决方案。
— AndroidDev '17

与服务器端解决方案相比,我个人更喜欢您的客户端答复风格,因此我做了一些事情。这并不令人惊讶,但它可以正常工作stackoverflow.com/a/44936706/4808079
— Seph Reed

1
您的答案不被接受。如果您认为它很糟糕,可以随时将其删除。
— TylerH '18

38

CSS本身不使用变量。但是,您可以使用SASS之类的另一种语言来使用变量定义样式,并自动生成CSS文件,然后将其放在Web上。请注意,每次更改CSS时都必须重新运行生成器,但这并不难。


12
我认为答案是现在(2016年)不正确,不是吗?尽管我认为使用SASS或类似方法可能更好。
— codenoob

使用CSS var优于SASS,因为使用SASS颜色只能静态更改。使用CSS var,可以在运行时更改颜色,即,您可以使用javascript通过按钮切换到“暗模式”。
— 尼克·克鲁斯


20

没有简单的CSS唯一解决方案。您可以这样做:

  • 在CSS文件中找到和的所有实例,background-color然后color为每种唯一的颜色创建一个类名。

    .top-header { color: #fff; }
    .content-text { color: #f00; }
    .bg-leftnav { background-color: #fff; }
    .bg-column { background-color: #f00; }
  • 接下来,遍历网站上涉及颜色的每个页面,并为颜色和背景色添加适当的类。

  • 最后,删除CSS中除新创建的颜色类以外的所有颜色引用。


1
但是,如果客户决定要使所有红色元素变为绿色怎么办?您必须更改“红色”类以提供“颜色:绿色”,这会造成混乱并且难以维护。
— 唱歌wolfboy

@singingwolfboy,我应该在类的命名上更加具体。引用它们所属的元素最容易,因此您将来可以轻松对其进行修改。
— 科里·巴拉

8
@downvoters,这是仅CSS解决方案。有很多替代方案涉及脚本或CLI,这是针对不打算这样做的人的。
— 科里·巴卢

17

Yeeeaaahhh ....你现在可以使用VAR( )函数在CSS .. ...

好消息是您可以使用JavaScript访问来更改它,它也会在全球范围内更改...

但是如何声明它们...

很简单:

例如,您想要将分配#ff0000给var(),只需将其分配给:root,还要注意--:

:root {
    --red: #ff0000; 
}

html, body {
    background-color: var(--red); 
}

好东西是对浏览器的支持还不错,也不需要像在浏览器中那样编译LESS或使用SASS...

浏览器支持

另外,这是一个简单的JavaScript脚本,它将红色值更改为蓝色:

const rootEl = document.querySelector(':root');
root.style.setProperty('--red', 'blue');


9

是的,在不久的将来(我在2012年6月撰写了这篇文章),您可以定义本机CSS变量,而无需使用less / sass等!Webkit引擎刚刚实现了第一个CSS变量规则,因此最先进的Chrome和Safari版本已经可以使用它们。请参阅带有官方 CSS浏览器演示的Official Webkit(Chrome / Safari)开发日志。

希望我们能在未来几个月内获得对本机CSS变量的广泛浏览器支持。


2
@丹尼尔(Daniel)做到2015年
— Still.Tony

4

由于支持,请勿使用css3变量。

如果您想要纯CSS解决方案,我将执行以下操作。

  1. 将颜色类别与语义名称一起使用。

    .bg-primary   { background: #880000; }
    
    .bg-secondary { background: #008800; }
    
    .bg-accent    { background: #F5F5F5; }
  2. 从皮肤分离结构(OOCSS)

    /* Instead of */
    
    h1 { 
        font-size: 2rem;
        line-height: 1.5rem;
        color: #8000;
    }
    
    /* use this */
    
    h1 { 
        font-size: 2rem;
        line-height: 1.5rem;
    }
    
    .bg-primary {
        background: #880000;
    }
    
    /* This will allow you to reuse colors in your design */
  3. 将它们放在单独的CSS文件中,以根据需要进行更改。


3

您可以通过javascript传递CSS,并用某种颜色(基本上是正则表达式)替换所有COLOUR1实例,并提供备份样式表,以防最终用户关闭JS


3

我不清楚您为什么不能使用PHP。然后,您可以根据需要简单地添加和使用变量,将文件另存为PHP文件,并以样式表(而不是.css文件)链接到该.php文件。

它不一定是PHP,但是您明白我的意思。

当我们想要编程时,为什么不使用编程语言,直到CSS(也许)支持变量之类的东西?

另外,请查看Nicole Sullivan的面向对象CSS。


我们不能全部使用PHP,因为这项工作要求我们中的某些人不要这样做!
— horiatu

3

dicejs.com(通常为cssobjs)是SASS的客户端版本。您可以在CSS中设置变量(以json格式的CSS存储),然后重新使用颜色变量。

//create the CSS JSON object with variables and styles
var myCSSObjs = {
  cssVariables : {
    primaryColor:'#FF0000',
    padSmall:'5px',
    padLarge:'$expr($padSmall * 2)'
  }
  'body' : {padding:'$padLarge'},
  'h1' : {margin:'0', padding:'0 0 $padSmall 0'},
  '.pretty' : {padding:'$padSmall', margin:'$padSmall', color:'$primaryColor'}
};

//give your css objects a name and inject them
$.cssObjs('myStyles',myCSSObjs).injectStyles();

这里是一个完整的可下载演示的链接,它比其文档更有帮助:dicejs演示


该工具似乎在2014
— Daniel

3

考虑使用SCSS。它与CSS语法完全兼容,因此有效的CSS文件也是有效的SCSS文件。这使迁移变得容易,只需更改后缀即可。它具有许多增强功能,最有用的是变量和嵌套选择器。

您需要通过预处理器将其运行,以将其转换为CSS,然后再将其交付给客户端。

我多年来一直是CSS的核心开发人员,但是自从强迫自己在SCSS中进行项目以来,我现在将不再使用其他任何东西。


2

如果您的系统上装有Ruby,则可以执行以下操作:

http://unixgods.org/~tilo/Ruby/Using_Variables_in_CSS_Files_with_Ruby_on_Rails.html

这是为Rails制作的,但是请参阅下文了解如何修改它以使其独立运行。

您可以独立于Rails使用此方法,方法是编写一个小的Ruby包装器脚本,该脚本与site_settings.rb结合使用,并考虑您的CSS路径,并且您可以在每次要重新生成CSS时调用(例如在网站启动期间)

您几乎可以在任何操作系统上运行Ruby,因此它应该与平台无关。

例如wrapper: generate_CSS.rb (在需要生成CSS时运行此脚本)

#/usr/bin/ruby  # preferably Ruby 1.9.2 or higher
require './site_settings.rb' # assuming your site_settings file is on the same level 

CSS_IN_PATH  = File.join( PATH-TO-YOUR-PROJECT, 'css-input-files')
CSS_OUT_PATH = File.join( PATH-TO-YOUR-PROJECT, 'static' , 'stylesheets' ) 

Site.generate_CSS_files( CSS_IN_PATH , CSS_OUT_PATH )

然后需要像下面这样修改site_settings.rb中的generate_CSS_files方法:

module Site
#   ... see above link for complete contents

  # Module Method which generates an OUTPUT CSS file *.css for each INPUT CSS file *.css.in we find in our CSS directory
  # replacing any mention of Color Constants , e.g. #SomeColor# , with the corresponding color code defined in Site::Color
  #
  # We will only generate CSS files if they are deleted or the input file is newer / modified
  #
  def self.generate_CSS_files(input_path = File.join( Rails.root.to_s , 'public' ,'stylesheets') , 
                              output_path = File.join( Rails.root.to_s , 'public' ,'stylesheets'))
    # assuming all your CSS files live under "./public/stylesheets"
    Dir.glob( File.join( input_path, '*.css.in') ).each do |filename_in|
      filename_out = File.join( output_path , File.basename( filename_in.sub(/.in$/, '') ))

      # if the output CSS file doesn't exist, or the the input CSS file is newer than the output CSS file:
      if (! File.exists?(filename_out)) || (File.stat( filename_in ).mtime > File.stat( filename_out ).mtime)
        # in this case, we'll need to create the output CSS file fresh:
        puts " processing #{filename_in}\n --> generating #{filename_out}"

        out_file = File.open( filename_out, 'w' )
        File.open( filename_in , 'r' ).each do |line|
          if line =~ /^\s*\/\*/ || line =~ /^\s+$/             # ignore empty lines, and lines starting with a comment
            out_file.print(line)
            next
          end
          while  line =~ /#(\w+)#/  do                         # substitute all the constants in each line
            line.sub!( /#\w+#/ , Site::Color.const_get( $1 ) ) # with the color the constant defines
          end
          out_file.print(line)
        end
        out_file.close
      end # if ..
    end
  end # def self.generate_CSS_files

end # module Site

2

您可以对选择器进行分组:

#selector1, #selector2, #selector3 { color: black; }

2

当然可以,由于有多个类的精彩世界,它可以做到:

.red {color:red}
.blackBack {background-color: black}

但我经常最终还是将它们组合成这样:

.highlight {color:red, background-color: black}

我知道语义警察将遍及您,但它确实有效。


1
我要补充一点:使用更多不同的语义名称。如果商标颜色发生变化,您将重做许多HTML代码。使用类名,例如.primary,.secondary,.accent等。–
— Eric Harms


1

如果将css文件作为xsl模板编写,则可以从简单的xml文件读取颜色值。然后使用xslt处理器创建CSS。

colors.xml:

<?xml version="1.0"?>
<colors>
    <background>#ccc</background>
</colors>

styles.xsl:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" version="1.0" encoding="iso-8859-1"/>
    <xsl:template match="/">body {
    background-color: <xsl:value-of select="/colors/background" />;
}
</xsl:template>
</xsl:stylesheet>

渲染CSS的命令: xsltproc -o styles.css styles.xsl colors.xml

styles.css:

body {
    background-color: #ccc;
}

0

单靠CSS是不可能的。

您可以使用less.js在JavaScript和LESS上完成此操作,这会将LESS变量实时呈现到CSS中,但这仅用于开发,并且会增加实际使用的开销。

CSS可以提供​​的最接近的选择是使用属性子字符串选择器,如下所示:

[id*="colvar-"] {
    color: #f0c69b;
}

并将id所有要调整的元素的s 设置为以开头的名称colvar-,例如colvar-header。然后,当您更改颜色时,所有ID样式都会更新。这与单独使用CSS所能达到的效果非常接近。


我只用CSS来做,而是用CSS变量Mozilla-example
— Arthur Weborg

如果您所有的用户都在使用mozilla,
— 那就太好了

也适用于Chrome,Safari和Opera。
— 亚瑟·韦伯

pmsl OP在我的帖子中对高中语法的更正是什么?没那么糟。
— user2317093 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.