CSS 技巧 – rgba 函数的妙用
ClaireNeuba
8年前
<p>新出现的 CSS 颜色配置 <a href="/misc/goto?guid=4959623026077606755" rel="nofollow,noindex">函数</a> 是一项非常有意思的功能,它给予我们在浏览器中直接操纵颜色的能力。例如,当鼠标悬停在按钮上时,可以使用 color: color(black darkness(50%)) 改变颜色,而不需要使用 Sass 这类 CSS 预处理器。</p> <p>但是浏览器现在对这种颜色函数还不支持,我们只能 暂时 使用 PostCSS 将其编译成常规的颜色。当然,我们也可以使用 CSS 中的 rgba() 函数达到类似的效果,下面就让我们看看具体该如何操作。</p> <h3>工作原理</h3> <p style="text-align:center"><img src="https://simg.open-open.com/show/62c5b789ac93cf02808c900586fd6fae.jpg"></p> <p>在设计软件中,如果我们分别将具有一定透明度的白色盒子和黑色盒子放在一个较大的蓝色盒子上,它们将分别变成浅蓝色和深蓝色。</p> <p>这是因为当小盒子的透明度较高时,前景色和背景色将会混在一起。如果我们将背景色从蓝色变成绿色,你能想出结果将会怎样吗?</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/e56eace706439000ae1f4f52213009ba.jpg"></p> <p>如你所见,当背景色变成绿色时,小盒子的颜色分别变成了浅绿色和深绿色。同理,我们也可以通过改变前景色的透明度来生成更深或更浅的颜色。现在,就让我们根据这个基本前提,深入研究一些实际例子。</p> <h3>理论结合实际</h3> <p>在上面的例子中,为了保持简洁,我们只改变了不透明度属性(opacity)。其实,在实际设计中,更为普遍的是改变 rgba() 的alpha值。如:</p> <pre> <code class="language-css">.header{ background: rgba(0, 0, 0, 0.5); /* 不透明度为50%的黑色 */ } </code></pre> <p>在这里我们用的是背景色(background)而不是透明度(opacity),这是因为如果使用 opacity,那么所有子元素都会受到影响,这是应该避免的。(当 opacity 属性的值应用于某个元素上时,是把这个元素(包括它的内容)当成一个整体看待,即使这个值没有被子元素继承。因此,一个元素和它包含的子元素都会具有和元素背景相同的透明度,哪怕这个元素和它的子元素有不同的 opacity 属性值。 <a href="/misc/goto?guid=4959731677483337024" rel="nofollow,noindex">译者注</a> )。相反,如果使用 background 的 alpha 通道的话,就能保证只更改指定的元素。</p> <p>注意:在下面的 demo 中,为了让表述更简洁,将采用 Sass 中的 rgba() 函数。如:</p> <pre> <code class="language-css">.elem{ background: rgba(white, 0.5); } </code></pre> <p>这将被编译为:</p> <pre> <code class="language-css">.elem{ background: rgba(255, 255, 255, 0.5); } </code></pre> <p>为网站 header 定制主题</p> <p>第一个 rgba() 的使用场景是为网站的 header 定制主题。在 <a href="/misc/goto?guid=4958330243377773977" rel="nofollow,noindex">Trello</a> 中,使用 rgba() 为头部子元素 (logo, search input, buttons) 的背景色赋值:</p> <pre> <code class="language-css">.search{ background: rgba(255, 255, 255, 0.5); /* 透明度为50%的白色 */ } </code></pre> <p style="text-align:center"><img src="https://simg.open-open.com/show/3a7edc41285b50928490a63dc89d4353.jpg"></p> <p>有了这个,我们就可以通过只改变 header 背景的颜色来变换主题,因为具有透明度的子元素颜色也将随之变化。</p> <p>在我们的例子中,将会采用和 Trello 头部相似的方式,在开发者工具中进行实验。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/d54b04ba2ca8c4aa9218bf95192b8616.png"></p> <p>注意在下面两个 heade r中,子元素的背景色是不同的。通过改变父级元素的背景色,我们可以非常方便的定制 header 主题。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/bc6ad18155d381fb3e3138d7c65076f4.gif"></p> <p>请参阅Ahmad Shadeed ( <a href="/misc/goto?guid=4959731677599365925" rel="nofollow,noindex">@shadeed</a> ) 在 <a href="/misc/goto?guid=4958539547061522984" rel="nofollow,noindex">CodePen</a> 中创建的 <a href="/misc/goto?guid=4959731677718138481" rel="nofollow,noindex">Header</a> demo。</p> <p>文章标题</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/04d7939e06ac3bf5088b709c5843f1ff.png"></p> <p>在这个例子中,使用 rgba() 将有助于改变下列元素的颜色:</p> <ul> <li>顶部和底部边框</li> <li>中间包裹元素的背景</li> <li>类别链接的背景</li> </ul> <p style="text-align:center"><img src="https://simg.open-open.com/show/785d99f3e37f32402e51cdfe8ec380de.jpg"></p> <pre> <code class="language-css">.parent{ background: #5aaf4c; /* 父级背景 */ box-shadow: inset 0 8px 0 0 rgba(255, 255, 255, 0.5), inset 0 -8px 0 0 rgba(255, 255, 255, 0.5); /* 顶部和底部边框 */ } .contain{ background: rgba(0, 0, 0, 0.1); } .category{ background: rgba(255, 255, 255, 0.5); } </code></pre> <p>例如 <a href="/misc/goto?guid=4959731677801721825" rel="nofollow,noindex">Article Header</a> 。</p> <p>按钮</p> <p>当定制按钮的主题时,可以使用 rgba() 来改变 hover 和 focus 按钮时边框和阴影的样式。</p> <pre> <code class="language-css">.button{ background: #026aa7; box-shadow: inset 0 -4px 0 0 rgba(0, 0, 0, 0.2); } .button:hover{ box-shadow: inset 0 -4px 0 0 rgba(0, 0, 0, 0.6), 0 0 8px 0 rgba(0, 0, 0, 0.5); } .button:focus{ box-shadow: inset 0 3px 5px 0 rgba(0, 0, 0, 0.2); } </code></pre> <p>例如 <a href="/misc/goto?guid=4959731677887853101" rel="nofollow,noindex">Buttons</a> 。</p> <p>渐变</p> <p>另一个有用的场景就是给背景设置纯色,然后添加一个带有 rgba() 背景色的伪元素,用其生成渐变效果。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/8a0e4b933e3804058afed05d4f78ad48.jpg"></p> <pre> <code class="language-css">.elem{ background: green; } .elem:before{ content: ""; position: absolute; left: 0; top: 0; width: 100%; height: 100%; background: linear-gradient(to right, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.7)); } </code></pre> <p>这种方法也可以帮助我们在只改变背景色的前提下模拟渐变动画效果。</p> <pre> <code class="language-css">.elem{ /* other styles */ animation: bg 2s ease-out alternate infinite; } @keyframes bg to { background: green; } } </code></pre> <p>请见Ahmad Shadeed 在 CodePen 中创建的 Gradients 。</p> <p>子元素</p> <p>如果在 header 中有一个导航列表,我们可以给导航栏添加一个由 rgba() 定义的背景色。这可以使导航背景透明,从而与父级元素的背景混合。</p> <p>请见Ahmad Shadeed在 CodePen 中创建的 Sub Element 。</p> <p>这种方法也可以被用于实现 hover 效果:</p> <p>例如 Hover Effect 。</p> <p>调色盘中的深/浅效果</p> <p>我们可以使用这种方法来生成调色板中的不同色调,只需要在纯色盒子上覆盖一个具有特定 rgba() 颜色的伪元素即可。</p> <p>例如 Color Palette 。</p> <p>图像效果</p> <p>如果我们想让一张图片变的更深或者更浅,同样可以使用具有 rgba() 背景色的伪元素。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/d7062940d8a0828ec97d4b72c4d31c19.jpg"></p> <p>通过使用彩色背景,我们可以产生一个彩色效果。此外,我们还可以使用 mix-blend-mode 属性将背景和图片混合,从而得到不同的效果。</p> <p>在使用 mix-blend-mode 之前,请注意检查一下兼容性:</p> <pre> <code class="language-css">.elem:before{ background: rgba(0, 0, 0, 1); mix-blend-mode: color; } </code></pre> <p>如果 mix-blend-mode 不被支持,图片将会变成黑色的一块。所以,这种效果最好被作为一种增强方式,而不是作为一种依赖。使用这种方法时,可以使用 @support 或者 Modernizr。</p> <pre> <code class="language-css">@supports (mix-blend-mode: color) { /* your enhanced styles go there */ } </code></pre> <p>例如 Images 。</p> <h3>使用CSS变量定制主题</h3> <p>如果给父级元素使用 CSS 变量 (自定义属性),当变量变化时,所有的子元素都会发生变化。例如:</p> <pre> <code class="language-css">:root{ --brand-color: #026aa7; } /* Checking for the support of CSS Variables */ @supports (--color: red) { .elem { background: var(--brand-color); } } </code></pre> <pre> <code class="language-css">var colors = ["#026aa7", "#5aaf4c", "#00bcd4", "#af4c4c"]; var colorOptions = document.querySelectorAll(".option"); var colorLabels = document.querySelectorAll(".option + label"); for (var i = 0; i < colorOptions.length; i++) { /* Add an event listener to each radio button */ colorOptions[i].addEventListener('click', changeColor); /* Add a value to each radio button based on colors[] array */ colorOptions[i].value = colors[i]; colorLabels[i].style.background = colors[i]; } function changeColor(e) { /* calling the root element and set the value of a specific property. In our case: --brand-color */ document.documentElement.style.setProperty('--brand-color', e.target.value); } </code></pre> <p>通过将 CSS 变量和 rgba() 相结合,我们可以在不给每个元素赋予新颜色的前提下,动态改变布局和颜色。</p> <p>例如 Header – CSS 变量 。</p> <h3>需要考虑的地方</h3> <p>后备颜色</p> <p>虽然目前浏览器对 CSS 颜色的支持度达到了 97.39% ,但是对于不支持的浏览器,也需要给出后备手段。</p> <pre> <code class="language-css">.elem{ background: #fff; background: rgba(255, 255, 255, 0.5); /* 不支持rgba的浏览器将会忽略这个命令 */ } </code></pre> <p>颜色对比检查</p> <p>我们应确保元素之间的对比度符合可访问性标准,毕竟有时使用 rgba() 将得到难以识别的颜色。可以使用像 Lea Verou 的 对比度检查工具 来帮助确定颜色是否满足可访问性标准。</p> <p> </p> <p>来自:http://web.jobbole.com/89673/</p> <p> </p>