¿Cómo puedo definir colores como variables en CSS?

216

Estoy trabajando en un archivo CSS que es bastante largo. Sé que el cliente podría solicitar cambios en el esquema de color y me preguntaba: ¿es posible asignar colores a las variables, de modo que pueda cambiar una variable para que se aplique el nuevo color a todos los elementos que lo usan?

Tenga en cuenta que no puedo usar PHP para cambiar dinámicamente el archivo CSS.

Patricio
fuente
Posible duplicación ... stackoverflow.com/questions/47487/…
Eddie
Esto podría ayudar: stackoverflow.com/questions/15831657/…
DreamTeK

Respuestas:

225

CSS admite esto de forma nativa con las variables CSS .

Ejemplo de archivo CSS

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

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

Para un ejemplo de trabajo, vea este JSFiddle (el ejemplo muestra que uno de los selectores CSS en el violín tiene el color codificado en azul, el otro selector CSS utiliza variables CSS, tanto la sintaxis original como la actual, para establecer el color en azul) .

Manipular una variable CSS en JavaScript / lado del cliente

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

El soporte está en todos los navegadores modernos

Firefox 31+ , Chrome 49+ , Safari 9.1+ , Microsoft Edge 15+ y Opera 36+ se envían con soporte nativo para variables CSS.

Arthur Weborg
fuente
3
En caso de que alguien más lea esto e intente que funcione en Safari, la compatibilidad con CSS parece haberse eliminado de Webkit en la primavera / verano de 2013. bugs.webkit.org/show_bug.cgi?id=114119 lists.webkit.org /pipermail/webkit-dev/2013-April/024476.html Todavía funciona en Chrome después de habilitar el indicador mencionado anteriormente.
Marie Fischer
Probado en Chrome 36, no funciona incluso con la bandera habilitada. Sin embargo, todavía funciona con
Firefox
Simplemente lo comprobé con Chrome Versión 49.0.2623.110 my todavía no funciona.
radu
¿Cuál es tu sistema operativo? Funcionó para mí: Versión 49.0.2623.110 (64 bits) en Mac OS X
Arthur Weborg
También funcionó en la versión de Chrome de mi Android Android 5.1.0 Chrome 49.0.2623.105
Arthur Weborg el
66

La gente sigue votando mi respuesta, pero es una solución terrible en comparación con la alegría de sass o menos , particularmente dada la cantidad de gui fáciles de usar para ambos en estos días. Si tiene algún sentido, ignore todo lo que sugiero a continuación.

Puede poner un comentario en el CSS antes de cada color para que sirva como una especie de variable, que puede cambiar el valor de usar buscar / reemplazar, así que ...

En la parte superior del archivo CSS

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

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

*/

Más adelante en el archivo CSS

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

Luego, por ejemplo, para cambiar el esquema de color para el texto del cuadro en el que realiza una búsqueda / reemplazo

/*bt*/#123456
Wheresrhys
fuente
3
Agregar los comentarios no funcionará en algunos casos, como cuando se usan filtros IE. No puedo poner comentarios aquí -> filter: progid: DXImageTransform.Microsoft.gradient (startColorstr = '# 3f5619', endColorstr = '# 77842f', GradientType = 0); / * IE6-9 * /
Carter Medlin
1
Votado porque tiene razón, es una solución terrible.
AndroidDev
Personalmente, preferí su estilo de respuesta del lado del cliente sobre las soluciones del lado del servidor, así que hice algo para hacerlo. No es sorprendente, pero funciona stackoverflow.com/a/44936706/4808079
Seph Reed
1
Tu respuesta no es aceptada. Siempre puedes eliminarlo si crees que es terrible.
TylerH
38

CSS en sí mismo no usa variables. Sin embargo, puede usar otro idioma como SASS para definir su estilo usando variables y producir automáticamente archivos CSS, que luego puede poner en la web. Tenga en cuenta que tendría que volver a ejecutar el generador cada vez que realizara un cambio en su CSS, pero eso no es tan difícil.

cantando lobo
fuente
12
Creo que la respuesta es AHORA (2016) incorrecta, ¿no? Aunque creo que aún podría ser mejor usar SASS o algo así.
codenoob
El uso de CSS vars puede ser preferible a SASS porque con SASS los colores solo se pueden cambiar estáticamente. Con CSS vars, los colores se pueden cambiar en tiempo de ejecución, es decir, puede cambiar al "modo oscuro" con un botón usando javascript.
Nick Crews
20

No hay una solución fácil de CSS solamente. Podrías hacer esto:

  • Encuentre todas las instancias de background-colory coloren su archivo CSS y cree un nombre de clase para cada color único.

    .top-header { color: #fff; }
    .content-text { color: #f00; }
    .bg-leftnav { background-color: #fff; }
    .bg-column { background-color: #f00; }
  • Luego, revise todas las páginas de su sitio donde haya color involucrado y agregue las clases apropiadas para el color y el color de fondo.

  • Por último, elimine cualquier referencia de colores en su CSS que no sean sus clases de color recién creadas.

Corey Ballou
fuente
1
Pero, ¿qué pasa si el cliente decide que quiere que todos los elementos rojos sean verdes? Tendría que cambiar la clase "rojo" para proporcionar "color: verde", que se vuelve confuso y difícil de mantener.
singingwolfboy
@singingwolfboy, debería haber sido más específico al nombrar las clases. Es más fácil hacer referencia a los elementos a los que pertenecen para poder modificarlos fácilmente en el futuro.
Corey Ballou
8
@downvoters, esta es una solución SOLO para CSS . Hay muchas soluciones alternativas que implican secuencias de comandos o una CLI, esto es para personas que no tienen la intención de hacerlo .
Corey Ballou
17

Yeeeaaahhh .... ahora puedes usar la función var ( ) en CSS ... ...

La buena noticia es que puede cambiarlo mediante el acceso a JavaScript , que también cambiará a nivel mundial ...

Pero cómo declararlos ...

Es bastante simple:

Por ejemplo, desea asignar un #ff0000a a var(), simplemente asignarlo :root, también prestar atención a --:

:root {
    --red: #ff0000; 
}

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

Lo bueno es que el soporte del navegador no es malo, tampoco es necesario compilarlo para usarlo en el navegador como LESSo SASS...

soporte de navegador

Además, aquí hay un script JavaScript simple, que cambia el valor rojo a azul:

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

La Ruby Gem 'Less' para CSS se ve increíble.

http://lesscss.org/

Irlanda
fuente
2
Creo que la belleza de MENOS es que no es Ruby ni ningún marco específico. Puede 'compilarse' del lado del cliente o usarse con cualquier otro marco como django-css github.com/dziegler/django-css o algo así
xster
9

Sí, en un futuro próximo (escribo esto en junio de 2012) puede definir variables css nativas, ¡sin usar less / sass, etc.! El motor de Webkit acaba de implementar las primeras reglas variables de CSS, por lo que las versiones más avanzadas de Chrome y Safari ya deben funcionar con ellas. Consulte el registro de desarrollo del Webkit oficial (Chrome / Safari) con una demostración del navegador CSS en el sitio.

Con suerte, podemos esperar un amplio soporte del navegador de variables css nativas en los próximos meses.

Sliq
fuente
2
@Daniel Make that 2015
Still.Tony
4

No use variables css3 debido a la compatibilidad.

Haría lo siguiente si desea una solución CSS pura.

  1. Use clases de colores con nombres semenáticos .

    .bg-primary   { background: #880000; }
    
    .bg-secondary { background: #008800; }
    
    .bg-accent    { background: #F5F5F5; }
  2. Separar la estructura de la piel (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. Ponga esto dentro de un archivo css separado para cambiarlo según sea necesario.

Eric Harms
fuente
3

Puede pasar el CSS a través de javascript y reemplazar todas las instancias de COLOUR1 con un determinado color (básicamente regex) y proporcionar una hoja de estilo de respaldo en caso de que el usuario final haya desactivado JS

Arcath
fuente
3

No tengo claro por qué no puedes usar PHP. Luego, puede simplemente agregar y usar variables como desee, guardar el archivo como un archivo PHP y vincularlo a ese archivo .php como la hoja de estilo en lugar del archivo .css.

No tiene que ser PHP, pero entiendes lo que quiero decir.

Cuando queremos cosas de programación, ¿por qué no usar un lenguaje de programación hasta que CSS (tal vez) admita cosas como variables?

Además, echa un vistazo a CSS orientado a objetos de Nicole Sullivan .

stephenhay
fuente
¡No todos podemos usar PHP porque el trabajo requiere que algunos de nosotros no lo hagamos!
horiatu
3

dicejs.com (formalmente cssobjs) es una versión del lado del cliente de SASS. Puede establecer variables en su CSS (almacenado en CSS formateado json) y reutilizar sus variables de color.

//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();

Y aquí hay un enlace a una demostración completa descargable que es un poco más útil que su documentación: dicejs demo

John David Five
fuente
Parece que esta herramienta ya no está disponible en 2014
Daniel
3

Considere usar SCSS. Es totalmente compatible con la sintaxis CSS, por lo que un archivo CSS válido también es un archivo SCSS válido. Esto facilita la migración, solo cambie el sufijo. Tiene numerosas mejoras, siendo las más útiles las variables y los selectores anidados.

Debe ejecutarlo a través de un preprocesador para convertirlo a CSS antes de enviarlo al cliente.

He sido un desarrollador de CSS incondicional durante muchos años, pero desde que me obligué a hacer un proyecto en SCSS, ahora no usaré nada más.

superluminario
fuente
2

Si tiene Ruby en su sistema, puede hacer esto:

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

Esto se hizo para Rails, pero vea a continuación cómo modificarlo para ejecutarlo de forma independiente.

Puede usar este método independientemente de Rails, escribiendo un pequeño script de contenedor Ruby que funcione junto con site_settings.rb y tenga en cuenta sus rutas CSS, y que puede llamar cada vez que desee volver a generar su CSS (por ejemplo, durante el inicio del sitio)

Puede ejecutar Ruby en casi cualquier sistema operativo, por lo que debería ser bastante independiente de la plataforma.

por ejemplo, wrapper: generate_CSS.rb (ejecuta este script siempre que necesites generar tu 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 )

el método generate_CSS_files en site_settings.rb debe modificarse así:

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
Tilo
fuente
2

Puede agrupar selectores:

#selector1, #selector2, #selector3 { color: black; }
Botond Vajna
fuente
2

Claro que, de alguna manera, gracias al maravilloso mundo de múltiples clases, puede hacer esto:

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

pero a menudo termino combinándolos de esta manera:

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

Sé que la policía semántica estará sobre ti, pero funciona.

Gredoso
fuente
1
Yo agregaría: use nombres diferentes y más semánticos. Si los colores de la marca cambian, estará rehaciendo una gran cantidad de código html. Utilice nombres de clase como .primary, .secondary, .accent, etc.
Eric Harms
2

Me temo que no PHP, pero Zope y Plone usan algo similar a SASS llamado DTML para lograr esto. Es increíblemente útil en los CMS.

Upfront Systems tiene un buen ejemplo de su uso en Plone.

Jon Hadley
fuente
1

Si escribe el archivo css como una plantilla xsl, puede leer los valores de color de un simple archivo xml. Luego cree el CSS con un procesador xslt.

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>

Comando para renderizar css: xsltproc -o styles.css styles.xsl colors.xml

styles.css:

body {
    background-color: #ccc;
}
Cole Tierney
fuente
0

No es posible solo con CSS.

Puede hacerlo con JavaScript y MENOS usando less.js , que representará MENOS variables en CSS en vivo, pero es solo para desarrollo y agrega demasiada sobrecarga para el uso en la vida real.

Lo más cercano que puede venir con CSS es usar un selector de subcadena de atributos como este:

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

y establezca los ids de todos los elementos que desea que se ajusten a los nombres que comienzan colvar-, como colvar-header. Luego, cuando cambia el color, se actualizan todos los estilos de ID. Eso es lo más cercano que puedes obtener con CSS solo.

usuario2317093
fuente
Lo hago solo con CSS, es con variables CSS . Ejemplo de Mozilla
Arthur Weborg
eso es genial si todos tus usuarios usan mozilla - buena suerte con eso
user2317093
Funciona con cromo, safari y ópera también.
Arthur Weborg
pmsl, ¿qué pasa con las delicadas correcciones de gramática de la escuela secundaria en mi publicación del OP? No fue tan malo.
user2317093