Jak zdefiniować kolory jako zmienne w CSS?


216

Pracuję nad plikiem CSS, który jest dość długi. Wiem, że klient mógł poprosić o zmiany w schemacie kolorów i zastanawiałem się: czy można przypisać kolory do zmiennych, abym mógł po prostu zmienić zmienną i zastosować nowy kolor do wszystkich elementów, które z niej korzystają?

Pamiętaj, że nie mogę używać PHP do dynamicznej zmiany pliku CSS.




Odpowiedzi:


225

CSS obsługuje to natywnie za pomocą Zmiennych CSS .

Przykładowy plik CSS

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

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

Dla działającego przykładu zobacz ten JSFiddle (przykład pokazuje, że jeden z selektorów CSS w skrzypcach ma kolor zakodowany na niebiesko, drugi selektor CSS używa zmiennych CSS, zarówno oryginalnej, jak i bieżącej składni, aby ustawić kolor na niebieski) .

Manipulowanie zmienną CSS po stronie JavaScript / klienta

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

Wsparcie jest we wszystkich nowoczesnych przeglądarkach

Firefox 31+ , Chrome 49+ , Safari 9.1+ , Microsoft Edge 15+ i Opera 36+ są dostarczane z natywną obsługą zmiennych CSS.


3
Na wypadek, gdyby ktokolwiek to przeczytał i spróbował uruchomić w przeglądarce Safari - wydaje się, że obsługa CSS została usunięta z Webkit wiosną / latem 2013 roku. Bugs.webkit.org/show_bug.cgi?id=114119 lists.webkit.org /pipermail/webkit-dev/2013-April/024476.html Nadal działa w Chrome po włączeniu flagi wspomnianej powyżej.
Marie Fischer,

Testowane na chrome 36, nie działa nawet z włączoną flagą. Nadal jednak działa z firefox
yuvi

Właśnie sprawdziłem w Chrome w wersji 49.0.2623.110 mi nadal nie działa.
radu,

Jaki masz system operacyjny? To działało dla mnie: Wersja 49.0.2623.110 (64-bitowa) na Mac OS X
Arthur Weborg

Pracowałem także nad wersją Chrome dla Androida na Androida 5.1.0 Chrome 49.0.2623.105
Arthur Weborg,

66

Ludzie wciąż oceniają moją odpowiedź, ale jest to okropne rozwiązanie w porównaniu do radości z sassa lub mniejszej , szczególnie biorąc pod uwagę liczbę łatwych w użyciu gui w obu tych dniach. Jeśli masz jakiś sens, zignoruj ​​wszystko, co sugeruję poniżej.

Możesz umieścić komentarz w css przed każdym kolorem, aby służyć jako rodzaj zmiennej, którą możesz zmienić wartość za pomocą funkcji znajdź / zamień, więc ...

Na górze pliku css

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

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

*/

Później w pliku CSS

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

Następnie, na przykład, zmień schemat kolorów dla tekstu pola, w którym znajdujesz / zamieniasz

/*bt*/#123456

3
Dodanie komentarzy nie będzie działać w kilku przypadkach, na przykład podczas korzystania z filtrów IE. Nie mogę tutaj wstawiać komentarzy -> filter: progid: DXImageTransform.Microsoft.gradient (startColorstr = '# 3f5619', endColorstr = '# 77842f', GradientType = 0); / * IE6-9 * /
Carter Medlin

1
Odebrane, ponieważ masz rację, to okropne rozwiązanie.
AndroidDev

Osobiście wolałem styl odpowiedzi po stronie klienta niż rozwiązania po stronie serwera, więc zrobiłem coś, aby to zrobić. To nie jest niesamowite, ale działa stackoverflow.com/a/44936706/4808079
Seph Reed

1
Twoja odpowiedź nie została zaakceptowana. Zawsze możesz go usunąć, jeśli uważasz, że to okropne.
TylerH

38

Sam CSS nie używa zmiennych. Możesz jednak użyć innego języka, takiego jak SASS, aby zdefiniować styl za pomocą zmiennych i automatycznie utworzyć pliki CSS, które możesz następnie umieścić w Internecie. Pamiętaj, że będziesz musiał ponownie uruchomić generator za każdym razem, gdy wprowadzasz zmiany w CSS, ale to nie jest takie trudne.


12
Myślę, że odpowiedź jest TERAZ (2016) nieprawidłowa, prawda? Chociaż myślę, że nadal lepiej byłoby użyć SASS lub podobnego.
codenoob

Używanie zmiennych CSS może być lepsze niż SASS, ponieważ w SASS kolory można zmieniać tylko statycznie. W CSS vars kolory mogą być zmieniane w czasie wykonywania, tj. Możesz przejść do „trybu ciemnego” za pomocą przycisku za pomocą javascript.
Nick Crews


20

Nie ma łatwego rozwiązania opartego wyłącznie na CSS. Możesz to zrobić:

  • Znajdź wszystkie instancje background-colororaz colorw pliku CSS i stworzyć nazwę klasy dla każdego unikalnego koloru.

    .top-header { color: #fff; }
    .content-text { color: #f00; }
    .bg-leftnav { background-color: #fff; }
    .bg-column { background-color: #f00; }
  • Następnie przejrzyj każdą stronę witryny, w której był zaangażowany kolor, i dodaj odpowiednie klasy dla koloru i tła.

  • Na koniec usuń odniesienia do kolorów w swoim CSS inne niż nowo utworzone klasy kolorów.


1
Ale co, jeśli klient zdecyduje, że chce, aby wszystkie czerwone elementy były zielone? Musiałbyś zmienić klasę „czerwoną”, aby zapewnić „kolor: zielony”, co staje się mylące i trudne do utrzymania.
singingwolfboy

@singingwolfboy, powinienem był bardziej szczegółowo nazwać klasy. Najłatwiej jest wskazać, do jakich elementów odnoszą się, aby można je było łatwo modyfikować w przyszłości.
Corey Ballou,

8
@ downvoters, jest to rozwiązanie TYLKO CSS . Istnieje wiele alternatywnych rozwiązań obejmujących skrypty lub interfejs CLI, przeznaczony dla osób, które nie zamierzają tego robić .
Corey Ballou,

17

Yeeeaaahhh .... możesz teraz używać funkcji var ( ) w CSS .. ...

Dobrą wiadomością jest to, że możesz to zmienić za pomocą dostępu JavaScript , który również zmieni się globalnie ...

Ale jak je zadeklarować ...

To dość proste:

Na przykład, chcesz przypisać a #ff0000do var(), wystarczy po prostu przypisać :root, a także zwrócić uwagę na --:

:root {
    --red: #ff0000; 
}

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

Do dobrych rzeczy są takie wsparcie przeglądarka nie jest złe, też nie muszą być kompilowane do użytku w przeglądarce jak LESSi SASS...

obsługa przeglądarki

Oto prosty skrypt JavaScript, który zmienia czerwoną wartość na niebieską:

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

9

Rubinowy klejnot „Mniej” dla CSS wygląda niesamowicie.

http://lesscss.org/


2
Myślę, że piękno LESS polega na tym, że nie jest to ani Ruby, ani żaden konkretny framework. Można go „skompilować” po stronie klienta lub użyć z dowolnym innym frameworkiem, takim jak django-css github.com/dziegler/django-css lub coś w tym stylu
xster

9

Tak, w najbliższej przyszłości (piszę to w czerwcu 2012 roku) możesz zdefiniować natywne zmienne css, bez użycia less / sass itp! Silnik Webkit właśnie zaimplementował pierwsze zmienne reguły css, więc najnowocześniejsze wersje Chrome i Safari już z nimi współpracują. Zobacz dziennik rozwoju Official Webkit (Chrome / Safari) z demonstracyjną przeglądarką css w witrynie.

Mamy nadzieję, że w najbliższych miesiącach możemy spodziewać się szerokiej obsługi natywnych zmiennych css w przeglądarce.


2
@Daniel Make that 2015
Still.Tony

4

Nie używaj zmiennych css3 ze względu na obsługę.

Zrobiłbym następujące, jeśli chcesz czystego rozwiązania css.

  1. Używaj klas kolorów z nazwami semenatycznymi .

    .bg-primary   { background: #880000; }
    
    .bg-secondary { background: #008800; }
    
    .bg-accent    { background: #F5F5F5; }
  2. Oddziel strukturę od skóry (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. Umieść je w osobnym pliku css, aby zmienić w razie potrzeby.


3

Możesz przekazać CSS przez javascript i zastąpić wszystkie wystąpienia COLOUR1 określonym kolorem (w zasadzie regexować go) i dostarczyć arkusz stylów tworzenia kopii zapasowych, w przypadku gdy użytkownik końcowy wyłączył JS


3

Nie jestem pewien, dlaczego nie możesz używać PHP. Następnie możesz po prostu dodawać i używać zmiennych, jak chcesz, zapisać plik jako plik PHP i połączyć z tym plikiem .php jako arkusz stylów zamiast pliku .css.

To nie musi być PHP, ale rozumiesz.

Kiedy chcemy programować, dlaczego nie użyć języka programowania, dopóki CSS (być może) nie obsługuje takich rzeczy jak zmienne?

Zobacz także obiektowy CSS Nicole Sullivan .


Nie wszyscy możemy korzystać z PHP, ponieważ praca wymaga od nas, aby nie!
horiatu

3

dicejs.com (formalnie cssobjs) to wersja SASS po stronie klienta. Możesz ustawić zmienne w swoim CSS (przechowywanym w formacie CSS w formacie json) i ponownie użyć zmiennych kolorów.

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

A tutaj jest link do pełnej wersji demo do pobrania, która jest nieco bardziej pomocna niż ich dokumentacja: demo dicejs


To narzędzie wydaje się być niedostępne w 2014 r.
Daniel

3

Rozważ użycie SCSS. Jest w pełni kompatybilny ze składnią CSS, więc prawidłowy plik CSS jest również prawidłowym plikiem SCSS. Ułatwia to migrację, wystarczy zmienić przyrostek. Ma wiele ulepszeń, z których najbardziej przydatne są zmienne i zagnieżdżone selektory.

Musisz uruchomić go przez procesor wstępny, aby przekonwertować go na CSS przed wysłaniem go do klienta.

Od wielu lat jestem zagorzałym programistą CSS, ale odkąd zmusiłem się do projektu w SCSS, nie będę używać niczego innego.


2

Jeśli masz Ruby w swoim systemie, możesz to zrobić:

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

Zostało to stworzone dla Railsów, ale zobacz poniżej, jak je zmodyfikować, aby działało samodzielnie.

Możesz użyć tej metody niezależnie od Railsów, pisząc mały skrypt opakowujący Ruby, który działa w połączeniu z site_settings.rb i bierze pod uwagę twoje ścieżki CSS i który możesz wywoływać za każdym razem, gdy chcesz ponownie wygenerować swój CSS (np. podczas uruchamiania witryny)

Możesz uruchomić Ruby na prawie każdym systemie operacyjnym, więc powinno to być dość niezależne od platformy.

np. wrapper: generate_CSS.rb (uruchom ten skrypt, ilekroć potrzebujesz wygenerować swój 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 )

Następnie należy zmodyfikować metodę generate_CSS_files w site_settings.rb w następujący sposób :

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

Pewnie, że może, dzięki cudownemu światowi wielu klas, może to zrobić:

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

ale często i tak je łączę:

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

Wiem, że semantyczna policja będzie wokół ciebie, ale działa.


1
Dodałbym: użyj innych i bardziej semantycznych nazw. Jeśli kolory brandingu zmienią się, przerobisz dużo kodu HTML. Używaj nazw klas, takich jak .primary, .secondary, .accent itp.
Eric Harms

2

Obawiam się, że nie PHP, ale Zope i Plone używają czegoś podobnego do SASS o nazwie DTML . Jest to niezwykle przydatne w CMS.

Upfront Systems ma dobry przykład zastosowania w Plone.


1

Jeśli napiszesz plik css jako szablon xsl, możesz odczytać wartości kolorów z prostego pliku xml. Następnie utwórz css za pomocą procesora 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>

Polecenie do renderowania css: xsltproc -o styles.css styles.xsl colors.xml

styles.css:

body {
    background-color: #ccc;
}

0

Nie jest to możliwe tylko z CSS.

Możesz to zrobić za pomocą JavaScript i MNIEJ za pomocą less.js , co spowoduje, że zmienne LESS zostaną przetworzone w CSS na żywo, ale jest to tylko dla programistów i dodaje zbyt wiele narzutów do użycia w prawdziwym życiu.

Najbliższe CSS to użycie selektora podciągów atrybutów w następujący sposób:

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

i ustaw ids wszystkich elementów, które chcesz dopasować do nazw zaczynających się od colvar-, takich jak colvar-header. Następnie po zmianie koloru wszystkie style identyfikatora są aktualizowane. Jest to tak blisko, jak to tylko możliwe z samym CSS.


Robię to z samym CSS, ze zmiennymi css Przykład Mozilli
Arthur Weborg 11.09.2013

to świetnie, jeśli wszyscy użytkownicy używają mozilli - powodzenia
user2317093 11.09.2013

Działa również z Chrome, Safari i operą.
Arthur Weborg

pmsl, co jest z poprawionymi poprawkami gramatycznymi w szkole średniej w moim poście przez OP? Nie było tak źle.
user2317093,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.