Bir CSS renk değişkenine opaklığı nasıl uygularım?


145

Elektronda bir uygulama tasarlıyorum, bu yüzden CSS değişkenlerine erişimim var. Ben bir renk değişkeni tanımladı vars.css:

:root {
  --color: #f0f0f0;
}

Bu rengi kullanmak istiyorum main.css, ancak bazı opaklık uygulanmış olarak:

#element {
  background: (somehow use var(--color) at some opacity);
}

Bunu nasıl yapabilirim? Herhangi bir önişlemci kullanmıyorum, sadece CSS kullanıyorum. Tamamen CSS cevabını tercih ederim, ancak JavaScript / jQuery'yi kabul edeceğim.

Kullanamam opacityçünkü şeffaf olmamalı bir arka plan görüntüsü kullanıyorum.


Yani birden fazla eleman kullanmanız gerektiği gibi geliyor ....
epascarello


4
AHHHHH !!!!! Bu çok sinir bozucu! Şimdi neredeyse 2020. Renk seçici #hex renk alır. alpha / rgba Sass / Stylus'ta çalışmaz - çünkü bu bir rgb değeri değildir. Her bir renk için CMS'ime 4 kaydırıcı koymalı mıyım?
sheriffderek

Yanıtlar:


242

Mevcut bir renk değerini alıp buna alfa kanalı uygulayamazsınız. Yani, #f0f0f0alfa bileşeni vermek ve elde edilen değeri başka bir özellik ile kullanmak gibi mevcut bir onaltılık değeri alamazsınız .

Bununla birlikte, özel özellikler onaltılık değerinizi kullanmak için bir RGB üçlüsüne dönüştürmenize rgba(), bu değeri özel mülkte (virgül dahil!) Depolamanıza, bu değeri kullanarak istediğiniz alfa değerine sahip var()bir rgba()işleve değiştirmenize olanak tanır. sadece iş:

:root {
  /* #f0f0f0 in decimal RGB */
  --color: 240, 240, 240;
}

body {
  color: #000;
  background-color: #000;
}

#element {
  background-color: rgba(var(--color), 0.8);
}
<p id="element">If you can see this, your browser supports custom properties.</p>

Bu gerçek olamayacak kadar iyi görünüyor. 1 Nasıl çalışır?

Büyü, özel özelliklerin değerlerinin, bir özellik değerindeki başvurular değiştirilirken , o özelliğin değeri hesaplanmadan önce olduğu gibi değiştirilmesidir . Uzakta özel özellikleri ile ilgili olarak olarak, değeri, bu bu araç sizin örnekte hiç bir renk değeri değil dek bir ifadenin bir renk değeri (ve yalnızca bu bağlamda) beklediği bir yerlerde görünür. Gönderen bölüm 2.1 css-değişkenler Spec arasında:var()--colorvar(--color)

Özel özellikler için izin verilen sözdizimi son derece izin vericidir. <declaration-value> üretimi, dizi <bad-string-token>, <bad-url-token>, eşleşmemiş <) - jeton>, <] içermediği sürece bir veya daha fazla jetondan oluşan herhangi bir diziyle eşleşir. token> veya <} - token> veya üst düzey <semicolon-token> belirteçleri veya "!" değerine sahip <delim-token> belirteçleri.

Örneğin, aşağıdakiler geçerli bir özel özelliktir:

--foo: if(x > 5) this.width = 10;

Bu değer, herhangi bir normal mülkte geçersiz olacağı için değişken olarak açıkça işe yaramaz olsa da, JavaScript tarafından okunabilir ve üzerinde işlem yapılabilir.

Ve bölüm 3 :

Bir özellik bir veya daha fazla var () işlevi içeriyorsa ve bu işlevler sözdizimsel olarak geçerliyse, tüm özelliğin dilbilgisinin ayrıştırma zamanında geçerli olduğu varsayılmalıdır. Var () işlevleri değiştirildikten sonra yalnızca hesaplanmış değer zamanında sözdizimi denetlenir.

Bu, 240, 240, 240yukarıda gördüğünüz değerin , bildirim hesaplanmadan önce doğrudan rgba()işleve ikame edildiği anlamına gelir . Yani bu:

#element {
  background-color: rgba(var(--color), 0.8);
}

rgba()virgülle ayrılmış en az dört sayısal değer beklemediği için başlangıçta geçerli CSS gibi görünmüyor :

#element {
  background-color: rgba(240, 240, 240, 0.8);
}

elbette, mükemmel bir şekilde geçerli olan CSS.

Bir adım ileri giderek, alfa bileşenini kendi özel özelliğinde saklayabilirsiniz:

:root {
  --color: 240, 240, 240;
  --alpha: 0.8;
}

ve aynı sonuçla değiştirin:

#element {
  background-color: rgba(var(--color), var(--alpha));
}

Bu, hareket halindeyken değiştirebileceğiniz farklı alfa değerlerine sahip olmanızı sağlar.


1 Eh, kod snippet'ini özel özellikleri desteklemeyen bir tarayıcıda çalıştırıyorsanız.


12
Bu güzel
roberrrt-s

1
@Roberrrt: It adlı bir şey ben yayınlanmıştır gibi görerek, aslında, erken fark var bu cevapları önceden.
BoltClock

2
Bu Var gidiyoruz, neden böyle bir şey kullanmayın: .element2 { background-color: rgba(var(--red), var(--low-opacity); }. Bu şekilde değişkenlerin kullanımını tam olarak kullanabilirsiniz :).
roberrrt-s

7
Ne yazık ki, değer "240, 240, 240"bir renk seçici ile düzenlenemez. GUI'niz için doğru renkleri bulmanız gerektiğinde büyük bir özledim.
Get Free

1
@ s3c Sözdizimi var(--hex-color)99iki jetona dönüştürülür #333333 99(jetonları ayırmak için boşluğa dikkat edin) ki bu kesinlikle istediğiniz şey değildir. Özel özellikler başlangıçta dizeleri değil, jetonları kopyalamak için tanımlanmıştır ve bu da sonuçtur. Bunu düzeltmek için artık çok geç.
Mikko Rantalainen

20

OP bir önişlemci kullanmadığını biliyorum, ama aşağıdaki bilgiler burada cevabın bir parçası olsaydı ben yardımcı olurdu (henüz yorum yapamam, aksi takdirde @BoltClock cevap yorum.

Örneğin, scss kullanıyorsanız yukarıdaki yanıt başarısız olacaktır, çünkü scss stilleri scss'e özgü bir rgba () / hsla () işleviyle derlemeye çalışır, bu da 4 parametre gerektirir. Ancak, rgba () / hsla () da yerel css işlevleridir, bu nedenle scss işlevini atlamak için dize enterpolasyonunu kullanabilirsiniz.

Örnek (sass 3.5.0+ için geçerlidir):

:root {
    --color_rgb: 250, 250, 250;
    --color_hsl: 250, 50%, 50%;
}

div {
    /* This is valid CSS, but will fail in a scss compilation */
    background-color: rgba(var(--color_rgb), 0.5);
    
    /* This is valid scss, and will generate the CSS above */
    background-color: #{'rgba(var(--color_rgb), 0.5)'};
}
<div></div>

Dize enterpolasyonunun lighten(), ortaya çıkan kod işlevsel CSS olmayacağı için CSS olmayan scss işlevleri için çalışmayacağını unutmayın . Yine de geçerli scss olurdu, bu yüzden derleme hiçbir hata alırsınız.


4
Sass .scss dosyalarınızda yerel CSS renk işlevlerini kullanmayı tercih ederseniz, Sass'ın işlenmesini geçersiz kılmak ve bunların geçmesini sağlamak için dosyanızın üstüne aşağıdaki işlev tanımlarını ekleyebilirsiniz: @function rgb($args...) { @return #{'rgb(#{$args})'}; } @function rgba($args...) { @return #{'rgba(#{$args})'}; } @function hsl($args...) { @return #{'hsl(#{$args})'}; } @function hsla($args...) { @return #{'hsla(#{$args})'}; }`` ``
lunelson

rgbargbuzunca bir süredir eşanlamlı .. Böylece "a" yı bırakabilirsiniz.
s3c

1
Scss dosyaları için başka bir geçici çözüm RGB, daha sonra sass tarafından göz ardı edilen büyük harf ( ) kullanmaktır . Ör: color: RGB(var(--color_rgb), 0.5);. Gönderen GitHub'dan
Jono İş

Güzel cevap! Renkleri onaltılı olarak tanımladıysanız, özel rgb özelliklerine dönüştürmek için bu kodu ekleyebilirsiniz::root { @each $color, $value in $colors { --#{$color}_rgb: #{red($value), green($value), blue($value)}; } }
Plumpssack

9

Ben de benzer bir durum oldu, ama değişkenler şey olabilir maalesef verilen çözümler, benim için işe yaramadı rgbiçin hsliçin hexhatta renk adları.
Ben uygulayarak, şimdi bu sorunu çözmüş background-colorve opacitybir pseudo için :afterveya :beforeeleman:

.container {
    position: relative;
}

.container:before {
    content: "";
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    background-color: var(--color);
    opacity: 0.3;
}

Arka planın uygulanması gereken öğeye bağlı olarak stillerin biraz değiştirilmesi gerekebilir.
Ayrıca tüm durumlar için işe yaramayabilir, ancak umarım diğer çözümlerin kullanılamadığı bazı durumlarda yardımcı olur.

Düzenleme: Sadece fark ettim ki, bu çözüm açıkça hedef öğenin önünde bir öğe oluşturur ve şeffaf bir arka plan rengi uygular gibi metin rengini etkiler.
Bu bazı durumlarda bir sorun olabilir.


Bu sadece rengin daha esnek bir şekilde tanımlanmasına (örneğin, bir ad veya rgbveya HSL) izin vermekle kalmaz, aynı zamanda doğal CSS renk fonksiyonları ile Sass'ın renk fonksiyonları arasındaki çatışmaları önler. Aşağıdaki SimplyPhy'nin cevabına bakın.
Jim Ratliff

1
Bence kullanmak daha iyidir, :beforeböylece oynamadan doğru istifleme sırasını alırsınız z-index.
Mikko Rantalainen

5

Bu gerçekten CSS ile mümkündür . Sadece biraz kirli ve degradeleri kullanmanız gerekecek. Küçük bir parçacığı örnek olarak kodladım, koyu arka planlar için açık-beyaz olanlar gibi siyah opaklığı kullanmanız gerektiğini unutmayın.

:root {
  --red: rgba(255, 0, 0, 1);
  --white-low-opacity: rgba(255, 255, 255, .3);
  --white-high-opacity: rgba(255, 255, 255, .7);
  --black-low-opacity: rgba(0, 0, 0, .3);
  --black-high-opacity: rgba(0, 0, 0, .7);
}

div {
	width: 100px;
	height: 100px;
	margin: 10px;
}
    
    
.element1 {
	background: 
        linear-gradient(var(--white-low-opacity), var(--white-low-opacity)) no-repeat,
	linear-gradient(var(--red), var(--red)) no-repeat;
}

.element2 {
	background: 
        linear-gradient(var(--white-high-opacity), var(--white-high-opacity)) no-repeat,
	linear-gradient(var(--red), var(--red)) no-repeat;
}
    
.element3 {
	background: 
        linear-gradient(var(--black-low-opacity), var(--black-low-opacity)) no-repeat,
	linear-gradient(var(--red), var(--red)) no-repeat;
}

.element4 {
	background: 
        linear-gradient(var(--black-high-opacity), var(--black-high-opacity)) no-repeat,
	linear-gradient(var(--red), var(--red)) no-repeat;
}
<div class="element1">hello world</div>
<div class="element2">hello world</div>
<div class="element3">hello world</div>
<div class="element4">hello world</div>


Arka plan boyutunu belirtmenize gerek yoktur - degradelerin gerçek boyutu yoktur ve sonuç olarak otomatik olarak gerilir.
BoltClock

@BoltClock Evet, kelimenin tam anlamıyla ben bunu yayınladığında, sadece kod kaleminde oynamak biraz olduğunu düşündüm;). Şimdi temizlendi, teşekkürler!
roberrrt-s

Bu akıllıca, geçen sene benzer bir soruyu cevapladığımda düz renk gradyanlarını birbirinin üzerine yerleştirmeyi düşünmemiştim . Bu soru muhtemelen yazma biçiminde daha geneldir, cevapladığım soru çok özel bir kullanım durumu içindi.
BoltClock

Arka planlar farklı olsa da gerçekten işe yaramaz, şimdi 'opaklık' uygularken beyaz bir arka plan (255,255,255) varsayalım. Muhtemelen OP'nin ana arka plan rengine varsayılan olarak ayarlanmış olabilir. Ama sonra tekrar, beyaz arka plan muhtemelen insanların bunu fark etmeyeceği ölçüde en açık renklerin ihtiyacına uyacaktır.
roberrrt-s

1
Sadece inanılmaz olan başka bir şey keşfettim. Şimdi bir cevap gönderdim.
BoltClock

1
:root{
--color: 255, 0, 0;
}

#element{
    background-color: rgba(var(--color), opacity);
}

opaklığı 0 ile 1 arasında bir şeyle değiştirdiğinizde


Bu, soruyu cevaplamaya yönelik bir girişim mi? Çünkü öyleyse, kod gerçekten mantıklı değil. Özellikle rgba(var(--color), opacity)biraz. Özellikle özel özellik değeriniz rgb () gösteriminin tamamı olduğundan. Ama aynı zamanda "opaklık" anahtar kelimesi nedeniyle.
BoltClock

benim kötü rgb parçaları var olmamalı woops
Pizza lord

1

SCSS / SASS

Avantajı: Her kanal için 8 Bit (0-255) kullanmak yerine Hex renk değerlerini kullanabilirsiniz.

İlk fikri şu şekilde yaptım: https://codyhouse.co/blog/post/how-to-combine-sass-color-functions-and-css-variables

Düzenleme: Ayrıca #{$color-name}-rgboluşturulan * -r, * -g, * -b CSS değişkenlerini kullanmak ve atlamak için alfa işlevini değiştirebilirsiniz .


Sonuç

body {
  --main-color: rgb(170, 68, 204);
  --main-color-rgb: 170,68,204;
  --main-color-r: 170;
  --main-color-g: 68;
  --main-color-b: 204;
}

.button-test {
  // Generated from the alpha function
  color: rgba(var(--main-color-r), var(--main-color-g), var(--main-color-b), 0.5);
  // OR (you wrote this yourself, see usage)
  color: rgba(var(--main-color-rgb), 0.5);
}

Kullanımı:

body {
    @include defineColorRGB(--main-color, #aa44cc);
}

.button-test {
  // With alpha function:
  color: alpha(var(--main-color), 0.5);
  // OR just using the generated variable directly
  color: rgba(var(--main-color-rgb), 0.5);
}

Mixin ve fonksiyonları

@mixin defineColorRGB($color-name, $value) {
    $red: red($value);
    $green: green($value);
    $blue: blue($value);
    #{$color-name}: unquote("rgb(#{$red}, #{$green}, #{$blue})");
    #{$color-name}-rgb: $red,$green,$blue;
    #{$color-name}-r: $red;
    #{$color-name}-g: $green;
    #{$color-name}-b: $blue;
}

// replace substring with another string
// credits: https://css-tricks.com/snippets/sass/str-replace-function/
@function str-replace($string, $search, $replace: '') {
    $index: str-index($string, $search);
    @if $index {
        @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
    }
    @return $string;
}

@function alpha($color, $opacity) {
    $color: str-replace($color, 'var(');
    $color: str-replace($color, ')');
    $color-r: var(#{$color+'-r'});
    $color-g: var(#{$color+'-g'});
    $color-b: var(#{$color+'-b'});
    @return rgba($color-r, $color-g, $color-b, $opacity);
}

Umarım bu biraz zaman kazanır.


1
Bu yaklaşımı seviyorum. Teşekkürler
tonygatta

0

Her renk için orijinal ve opaklığa sahip olan için belirli bir değişken / değer ayarlayabilirsiniz:

:root {
  --color: #F00;
  --color-opacity: rgba(255, 0, 0, 0.5);
}
#a1 {
  background: var(--color);
} 
#a2 {
  background: var(--color-opacity);
}
<div id="a1">asdf</div>
<div id="a2">asdf</div>

Bunu kullanamıyorsanız ve javascript çözümüne uygunsanız, bunu kullanabilirsiniz:

$(function() {
  $('button').click(function() {
    bgcolor = $('#a2').css('backgroundColor');
    rgb_value = bgcolor.match(/\d+,\s?\d+,\s?\d+/)[0]
    $('#a2').css('backgroundColor', 'rgba(' + rgb_value + ', 0.5)');
  });
});
:root {
  --color: #F00;
}
#a1 {
  background: var(--color);
} 
#a2 {
  background: var(--color);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="a1">asdf</div>
<div id="a2">asdf</div>
<button>Click to change opacity</button>


1
Opaklık değeri değişecektir, bu nedenle her opaklık için bir değişken oluşturmak sinir bozucu olacaktır.
JoshyRobot

-1

Genel css değişkeni ile rgba () kullanmak için şunu deneyin:

  1. İçinizdeki rengi belirtin: root, ancak diğer cevapların yaptığı gibi rgb () kullanmayın. sadece değeri yaz

:root{
  --color : 255,0,0;
  }

  1. Diğer cevaplar olarak var () kullanarak --color değişkenini kullan

#some-element {
  color : rgba(var(--color),0.5);
}


-3

CSS'de rgba değerlerini kullanabilmeniz gerekir:

#element {
  background: rgba(240, 240, 240, 0.5);
}

veya sadece opaklığı ayarlayın:

#element {
  background: #f0f0f0;
  opacity: 0.5;    
}

1
Bir rgba değerini kodlayamıyorum, renk değişkenleri kullanıyorum. Saydamlık kullanamayacağımı söylemeliydim çünkü şeffaf olmamalı bir arka plan resmim olacak.
JoshyRobot

BG'nin yalnızca şeffaflığa sahip olmasını istiyorsanız, ancak tam öğenin opaklığa sahip olmasını istiyorsanız, her şeye opaklık eklenmesi bu bir çözüm değildir.
Levidps

-4

Benim gibi altıgen renkleri seviyorsanız başka bir çözüm daha var. Onaltılık değer alfa değerinden sonra 6 basamaktır. 00% 100 şeffaflıktır 99% 75 civarındadır, daha sonra 'a1-af' sonra 'b1-bf' alfabesini kullanarak% 100 opak olan 'ff' ile biter.

:root {
--color: #F00;
}

#element {
background: var(--color)f6;
}

1
Ne yazık ki, bunun işe yaradığını düşünmüyorum. 8 basamaklı onaltılık kod desteği yayılmaya başlıyor, ancak kabul edilen cevapla kullanılan hile onlarla çalışıyor gibi görünmüyor. Örnek: jsbin.com/nacuharige/edit?css,output
JoshyRobot

Eğer işe yaramazsa harika bir çözüm olsa da bu işe yaramıyor.
Braden Rockwell Napier
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.