2016-10-13 101 views
20

我正在設計一個電子應用程序,所以我可以訪問CSS變量。我已經定義在vars.css可變色:如何將透明度應用於CSS顏色變量?

:root { 
    --color: #f0f0f0; 
} 

我想main.css使用這種顏色,但也有一些透明度應用:

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

我怎麼會去這樣做呢?我沒有使用任何預處理器,只有CSS。我更喜歡全CSS的答案,但我會接受JavaScript/jQuery。我不能使用opacity因爲我使用的背景圖像不應該是透明的。

+0

所以聽起來像你應該使用多個元素.... – epascarello

+0

我不喜歡,但它似乎我可能必須... :( – JoshyRobot

回答

35

你不能取一個現有的顏色值並應用一個alpha通道。也就是說,您不能使用現有的十六進制值,如#f0f0f0,給它一個alpha分量並將結果值與另一個屬性一起使用。

然而,自定義特性允許您在十六進制值轉換成RGB三元爲使用rgba(),存儲在自定義屬性(包括逗號!)該值,替代使用var()該值與所需的rgba()功能阿爾法值,它會只是工作:

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

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

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

這看起來幾乎是好得是真實的。 它是如何工作的?

關鍵之處是一個事實,即自定義屬性的值代該屬性的值被計算之前替換屬性值var()引用,時。這意味着就自定義屬性而言,在您的示例中--color的值根本不是顏色值,直到 a var(--color)表達式出現在需要顏色值(並且僅在該上下文中)的某處。來自section 2.1的css變量規範:

定製屬性的允許語法是非常寬容的。只要序列不包含< bad-string-token>,< bad-url-token>,無法匹配<)-token>,<] - <聲明 - 值>生產匹配任何序列的一個或多個標記。令牌>,或<} -token>或頂級<分號令牌或<帶有值「!」的分隔標記>標記。

例如,下面是一個有效的自定義屬性:

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

雖然這個值是作爲一個變量顯然是無用的,因爲它會在任何正常的財產無效,則可能通過JavaScript閱讀並採取行動。

而且section 3

如果屬性包含一個或多個VAR()函數,這些函數是語法上有效的,整個酒店的語法必須被認爲是在分析時有效。在var()函數被替換之後,它只在計算值時間進行語法檢查。

這意味着240, 240, 240值您在上面看到被直接代入rgba()功能計算聲明之前。所以這個:

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

不出現第一是有效的CSS因爲rgba()預計不少於四個以逗號分隔的數值,成爲本:

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

其中,當然,是完全有效的CSS。

把它一步,你可以在alpha分量存儲在它自己的自定義屬性:

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

,並用它替換,具有相同的結果:

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

這可以讓你有不同的阿爾法值,你可以即時交換。


嗯,這是,如果你正在運行在不支持自定義屬性瀏覽器的代碼片段。

+3

這很漂亮 – Roberrrt

+1

@Roberrrt:這是我早期應該意識到的事實,當我發佈[這些]時看到(http://stackoverflow.com/questions/37442603/how-to-use-commas-in- a-css-variable-fallback/37443195#37443195)[answers](http://stackoverflow.com/questions/38751778/is-it-possible-to-use-css-custom-properties-in-values-for- the-content-property/38751906#38751906)。 – BoltClock

+0

儘管如此,這真的很有用,SCSS/Less/Sass可以實現同樣的原理嗎? – Roberrrt

0

在CSS,你應該能夠要麼使用RGBA值:

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

或只是設置不透明度:

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

我無法硬編碼一個rgba值,我正在使用顏色變量我應該提到我不能使用不透明度,因爲我將有一個不應該透明的背景圖片 – JoshyRobot

0

您可以爲每種顏色設置特定變量/值 - 原來和在一個不透明度:

: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>

如果您不能使用這一點,你都OK與JavaScript的解決方案,您可以使用此一:

$(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>

+0

不透明度值會改變,因此爲每個不透明度創建一個變量會很麻煩 – JoshyRobot

+0

檢查更新js的解決方案 – Dekel

1

確實有可能與CSS。這只是有點骯髒,你必須使用漸變。我編寫了一個小片段爲例,需要注意的是對於黑暗的背景,你應使用黑色不透明,作爲光的白色的:

: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 { 
 
\t width: 100px; 
 
\t height: 100px; 
 
\t margin: 10px; 
 
} 
 
    
 
    
 
.element1 { 
 
\t background: 
 
     linear-gradient(var(--white-low-opacity), var(--white-low-opacity)) no-repeat, 
 
\t linear-gradient(var(--red), var(--red)) no-repeat; 
 
} 
 

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

 
.element4 { 
 
\t background: 
 
     linear-gradient(var(--black-high-opacity), var(--black-high-opacity)) no-repeat, 
 
\t 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>

+0

你不需要指定背景大小 - 漸變沒有固有的尺寸,並會自動伸展結果。 – BoltClock

+0

@BoltClock是的,我從字面上想到,當我發佈它時,它只是有點玩弄codepen;)。清理了,謝謝! – Roberrrt

+0

這很聰明,當我回答[類似問題]時,我沒有想過將純色漸變疊加到另一個上(http://stackoverflow.com/questions/29591465/use-css-variables-with-rgba-for - 漸變 - 透明度)去年。無論如何,寫這個問題可能會更普遍,我回答的是一個非常具體的用例。 – BoltClock

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

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

,你用0和1

+0

這是試圖回答這個問題嗎?因爲如果是這樣的話,代碼真的沒有意義。特別是'rgba(var( - color),opacity)'位。特別是因爲你的自定義屬性值是整個rgb()表示法。但也是因爲「不透明」關鍵字。 – BoltClock

+0

woops我的糟糕的rgb部分不應該在變種 –

2

我知道OP沒有使用預處理器之間的任何東西代替不透明度,但我會一直幫助如果下面的信息是答案的一部分,在這裏(我不能評論,否則我會評論@BoltClock答案。

如果你正在使用,例如scss,上面的答案將失敗,因爲scss試圖用scss特定的rgba()/ hsla()函數,它需要4個參數,但是,rgba()/ hsla()也是本地的css函數,所以你可以使用字符串interp olation繞過scss功能。

實施例(在SASS有效3.5.0+):

: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>

注意串內插將不用於非CSS SCSS功能工作,如lighten(),因爲所得代碼將不會是功能的CSS。儘管如此,它仍然是有效的,所以你在編譯時不會收到錯誤。