Как я могу определить цвета как переменные в CSS?

216

Я работаю над файлом CSS, который довольно длинный. Я знаю, что клиент мог запросить изменения в цветовой схеме и задавался вопросом: можно ли назначить цвета переменным, чтобы я мог просто изменить переменную, чтобы новый цвет применялся ко всем элементам, которые его используют?

Обратите внимание, что я не могу использовать PHP для динамического изменения файла CSS.

Патрик
источник
Возможное дублирование ... stackoverflow.com/questions/47487/…
Эдди
Это может помочь: stackoverflow.com/questions/15831657/…
DreamTeK

Ответы:

225

CSS изначально поддерживает это с помощью CSS-переменных .

Пример CSS-файла

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

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

Для рабочего примера, смотрите этот JSFiddle (пример показывает, что один из селекторов CSS в скрипте имеет цвет, жестко закодированный в синий, другой селектор CSS использует переменные CSS, как исходный, так и текущий синтаксис, чтобы установить синий цвет) ,

Управление переменной CSS на стороне JavaScript / клиента

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

Поддержка есть во всех современных браузерах

Firefox 31+ , Chrome 49+ , Safari 9.1+ , Microsoft Edge 15+ и Opera 36+ поставляются с встроенной поддержкой переменных CSS.

Артур Веборг
источник
3
На всякий случай, если кто-то прочтет это и попытается заставить его работать в Safari - кажется, что поддержка CSS была удалена из Webkit весной / летом 2013 года. Bugs.webkit.org/show_bug.cgi?id=114119 lists.webkit.org /pipermail/webkit-dev/2013-April/024476.html По-прежнему работает в Chrome после включения указанного выше флага.
Мари Фишер
Протестировано на chrome 36, не работает даже с включенным флагом. Тем не менее все еще работает с Firefox
yuvi
Только что проверил это с версией Chrome 49.0.2623.110 m, и она все еще не работает.
Рад
Какая у тебя ОС? Это сработало для меня: версия 49.0.2623.110 (64-разрядная версия) в Mac OS X
Артур Веборг,
Также работал на моем Android Chrome версии Android 5.1.0 Chrome 49.0.2623.105
Артур Веборг
66

Люди продолжают отговаривать мой ответ, но это ужасное решение по сравнению с радостью Sass или менее , особенно с учетом количества простых в использовании графических интерфейсов для обоих этих дней. Если у вас есть смысл, игнорируйте все, что я предлагаю ниже.

Вы можете поместить комментарий в 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
wheresrhys
источник
3
Добавление комментариев не будет работать в некоторых случаях, например, при использовании фильтров IE. Я не могу разместить здесь комментарии -> filter: progid: DXImageTransform.Microsoft.gradient (startColorstr = '# 3f5619', endColorstr = '# 77842f', GradientType = 0); / * IE6-9 * /
Картер Медлин
1
Понравился, потому что ты прав, это ужасное решение.
AndroidDev
Я лично предпочел стиль ответа на стороне клиента, а не решения на стороне сервера, поэтому я сделал что-то для этого. Это не удивительно, но это работает stackoverflow.com/a/44936706/4808079
Сеф Рид
1
Ваш ответ не принят. Вы всегда можете удалить его, если считаете, что это ужасно.
TylerH
38

Сам CSS не использует переменные. Однако вы можете использовать другой язык, например SASS, для определения стиля с помощью переменных и автоматического создания CSS-файлов, которые затем можно разместить в Интернете. Обратите внимание, что вам придется перезапускать генератор каждый раз, когда вы вносите изменения в свой CSS, но это не так сложно.

singingwolfboy
источник
12
Я думаю, что ответ СЕЙЧАС (2016) неверен, не так ли? Хотя я думаю, что все же может быть лучше использовать SASS или что-то подобное.
codenoob
Использование CSS-переменных может быть предпочтительнее, чем SASS, поскольку с помощью SASS цвета можно изменять только статически. С помощью CSS vars цвета могут быть изменены во время выполнения, то есть вы можете переключиться в «темный режим» с помощью кнопки, используя javascript.
Ник Крюс
24

Вы можете попробовать CSS3 переменные :

body {
  --fontColor: red;
  color: var(--fontColor);
}
Виталий Федоренко
источник
1
Примечание. Префикс пользовательского свойства изменялся в более ранней спецификации, но позже изменялся на -. Firefox 31 и выше соответствует новой спецификации. (ошибка 985838) developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables
августа,
20

Нет простого решения для CSS. Вы могли бы сделать это:

  • Найдите все экземпляры background-colorи colorв вашем CSS-файле и создайте имя класса для каждого уникального цвета.

    .top-header { color: #fff; }
    .content-text { color: #f00; }
    .bg-leftnav { background-color: #fff; }
    .bg-column { background-color: #f00; }
  • Затем перейдите на каждую страницу вашего сайта, где был задействован цвет, и добавьте соответствующие классы для цвета и фона.

  • Наконец, удалите все ссылки на цвета в вашем CSS, кроме недавно созданных классов цветов.

Кори Баллу
источник
1
Но что, если клиент решит, что он хочет сделать все красные элементы зелеными? Вам нужно будет изменить «красный» класс, чтобы обеспечить «цвет: зеленый», который запутывает и его трудно поддерживать.
Поющий волк
@singingwolfboy, я должен был быть более конкретным в названии классов. Проще всего указать, к какому элементу (элементам) они относятся, чтобы вы могли легко изменить их в будущем.
Кори Баллу
8
@ downvoters, это решение ТОЛЬКО для CSS . Существует множество альтернативных решений, включающих использование сценариев или интерфейс командной строки, для тех, кто не собирается этого делать .
Кори Баллу
17

Дааааааа .... теперь вы можете использовать функцию 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

Ruby Gem «Меньше» для CSS выглядит потрясающе.

http://lesscss.org/

Erin
источник
2
Я думаю, что прелесть LESS в том, что это не Ruby или какой-либо другой фреймворк. Его можно «скомпилировать» на стороне клиента или использовать с любым другим фреймворком, таким как django-css github.com/dziegler/django-css или чем-то
xster
9

Да, в ближайшем будущем (я пишу это в июне 2012 года) вы можете определить собственные переменные CSS, не используя less / sass и т. Д.! Движок Webkit только что реализовал первые правила для переменных css, поэтому передовые версии Chrome и Safari уже работают с ними. Смотрите официальный журнал разработки Webkit (Chrome / Safari) с демонстрационной версией браузера css.

Надеемся, что в ближайшие месяцы мы можем ожидать широкую поддержку браузером собственных переменных CSS.

SliQ
источник
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

Вы можете пропустить CSS через javascript и заменить все экземпляры COLOUR1 определенным цветом (в основном это регулярное выражение) и предоставить резервную таблицу стилей, если у конечного пользователя JS отключен.

Arcath
источник
3

Я не понимаю, почему вы не можете использовать PHP. Затем вы можете просто добавить и использовать переменные по своему усмотрению, сохранить файл как файл PHP и связать этот файл .php как таблицу стилей вместо файла .css.

Это не обязательно должен быть PHP, но вы понимаете, о чем я.

Когда мы хотим что-то программировать, почему бы не использовать язык программирования, пока CSS (возможно) не будет поддерживать такие вещи, как переменные?

Также ознакомьтесь с объектно-ориентированным CSS Николь Салливан .

stephenhay
источник
Мы не можем все использовать PHP, потому что работа требует, чтобы некоторые из нас этого не делали!
Horiatu
3

dicejs.com (формально cssobjs) является клиентской версией SASS. Вы можете установить переменные в своем CSS (хранящемся в CSS в формате json) и повторно использовать переменные цвета.

//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 demo

Джон Дэвид Пять
источник
Этот инструмент, кажется, больше не будет доступен в 2014 году
Даниэль
3

Рассмотрите возможность использования SCSS. Он полностью совместим с синтаксисом CSS, поэтому допустимый файл CSS также является допустимым файлом SCSS. Это облегчает миграцию, просто измените суффикс. Он имеет множество улучшений, наиболее полезными из которых являются переменные и вложенные селекторы.

Вам нужно запустить его через препроцессор, чтобы преобразовать его в CSS перед отправкой клиенту.

Я много лет был хардкорным CSS-разработчиком, но с тех пор, как я заставил себя делать проект в SCSS, я больше не буду использовать ничего другого.

superluminary
источник
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 )

Затем метод generate_CSS_files в site_settings.rb необходимо изменить следующим образом:

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 и т. Д.
Эрик Хармс
2

Боюсь, не PHP, но Zope и Plone используют нечто похожее на SASS под названием DTML для достижения этой цели. Это невероятно полезно в CMS.

У Upfront Systems есть хороший пример использования в Plone.

Джон Хэдли
источник
1

Если вы напишите файл css как шаблон xsl, вы можете прочитать значения цвета из простого файла xml. Затем создайте CSS с процессором 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>

Команда для рендеринга CSS: xsltproc -o styles.css styles.xsl colors.xml

styles.css:

body {
    background-color: #ccc;
}
Коул Тирни
источник
0

Это невозможно только с помощью CSS.

Вы можете сделать это с помощью JavaScript и LESS, используя less.js , который будет переводить переменные LESS в CSS в реальном времени, но он предназначен только для разработки и добавляет слишком много накладных расходов для реального использования.

Самое близкое, что вы можете сделать с CSS, это использовать селектор подстрок атрибута, например так:

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

и установить idS всех ваших элементов , которые вы хотите быть отрегулированы с именами , начиная с colvar-, например colvar-header. Затем при изменении цвета все стили идентификатора обновляются. Это так близко, как вы можете получить только с помощью CSS.

user2317093
источник
Я делаю это только с помощью CSS, это происходит с помощью переменных css Mozilla-пример
Артур Веборг
это здорово, если все ваши пользователи используют mozilla - удачи вам
user2317093
Работает с Chrome, Safari и Opera.
Артур Веборг
pmsl, что с привередливыми исправлениями грамматики средней школы в моем посте OP? Это было не так уж плохо.
user2317093