具有半透明值 (alpha 色版) 的 css 3 颜色单位

  • 说明: rgbahslacss level 3 (css 3) 起,新一代表示色彩的单位 (color units),最大的进展就是增加了「a」这个可以定义颜色不透明度 (opacity) 的 alpha 值;颜色的指定,当然包括了背景色 (background) 、边线色 (border) 、前景色或文字色 (color) 、以及 text-shadow, box-shadow 的阴影色、 gradient 的颜色等,这让以往网页设计需要繁琐过程的半透明效果变得简单轻松多了。本篇也附带讨论旧式未支援的浏览器,可做到类似效果的几种设计概念。
  • 适合:有 htmlcss 语法基础概念者。
  • 难度:等级2
  • 更新:
  • 支援: firefox, safari, google chrome, opera 10, ie9 (至更新时) 。

有二种表示方式:

  • rgba(red 值, green 值, blue 值, alpha 值)
    red, green, blue
    可以是 0 ~ 255 的整数值,与一般 8 位元颜色的十进位值相同,惟这类表示法不接受十六进位值 (如 ff, 8c) ;也可以是 0% ~ 100% 的百分比值。所以例如, rgb(128,128,128) = rgb(50%,50%,50%) = #808080
    alpha 值 (alphavalue)
    0.0 ~ 1.0 允许小数一位的数值, 0 →完全透明, 1 →完全不透明, 0.7 → 70% 不透明。 w3c 没有明确地表示是否允许小数一位以上的数值,不过 firefox 小数二位的数值也可以呈现,真是令人赞赏。
    语法实例:

    rgba(255, 0, 0, 0.6) → 不透明度 60% 红色

    rgba(0%, 0%, 100%, 0.4) → 不透明度 40% 蓝色

  • hsla(hue 值, saturation 值, lightness 值, alpha 值)
    hue 值 (色相值)
    以整数「角度」值表示,但是不加「°」角度符号。 0 或 360 →红色, 60 →黄色, 120 →绿色, 240 →蓝色,就好像彩虹色绕成一个圆。如同数学角度,负值或超过 360 是允许的,不过这样用好像是有点自找麻烦。
    saturation 值 (饱和度值)
    0% ~ 100% 的百分比值, 0% →灰色调, 100% →最大饱和度。所以 0% 时,不论 hue 值是多少,都会以灰阶单色呈现。
    lightness 值 (亮度值)
    0% ~ 100% 的百分比值, 0% →最暗 (暗黑), 100% →最亮 (亮白), 50% →正常亮度。 50% 以上渐渐增加白色, 50% 以下渐渐增加黑色。
    alpha 值 (alphavalue)
    0.0 ~ 1.0 允许小数一位的数值。
    语法实例:

    hsla(0, 100%, 50%, 0.3) → 不透明度 30% 红色

    hsla(120, 100%, 20%, 0.4) → 不透明度 40% 暗绿色

    hsla(240, 0%, 50%, 0.6) → 不透明度 60% 中亮灰色

transparent 值 - 完全透明的关键字 (keyword) 值

alpha 值 = 1 时,完全不透明,实际上就等同没有半透明 alpha 值的定义一样,例如 rgba(255,0,0,1) = rgb(255,0,0) = #ff0000

alpha 值 = 0 时,完全透明,像似 css 2 的关键字 (keyword) 值 transparent ,当然不管是什么颜色,透明都是看不见的;不过, transparent 代表的是透明黑色,即 transparent = hsla(0,0%,0%,0) = rgba(0,0,0,0) 。所以,这也就意味前景色 (color) 特性 (property) 也接受 transparent 值了,如 color:transparent;color:rgba(0,0,0,0); ,而这在 css level 2 是不允许的。

思考 - 背景半透明效果轻松设计: css color module level 3

颜色单位 (color units) 在 css 设计里,主要运用在指定背景色 (background) 、边线色 (border) 、前景色或文字色 (color) ,而多了可以直接定义颜色不透明度 (opacity) 的模式,设计背景半透明效果可说是轻而易举。

半透明背景色 (background-color) 效果

直接看范例一 xhtml
<div id="st1" class="st">
 <div class="inner">
  <h1>也让时间等一等</h1>
  <p>积极很好。人,肯积极,多半心里有目标。…
   …以下略,实际内容见范例内…
  </p>
 </div>
</div>
共同基本的 css 定义
html, body, h1, h2, h3 {
 margin: 0px;
 padding: 0px;
}
h1 {
 font-size: 100%;
 font-weight: normal;
}
p{
 margin-top: 1em;
 margin-bottom: 1em;
}
h1,p{
 padding: 1em 1.25em;
}
.st {
 color: white; /*文字白色*/
 /*div.st加背景图片并定义与图片同尺寸*/
 background: url(图片档案位址) no-repeat center;
 height: 534px;
 width: 800px;
 overflow: auto; /*内容超过高度时产生卷轴*/
 margin: 1.2em auto 0;
 text-align: justify;
 border:1px solid rgb(60%,60%,60%);
 border-right:none;
}
css 定义半透明背景色 (background)
#st1 .inner {
 padding: 1em 4%;
}
/*标题 h1, 段落 p 加半透明背景色*/
#st1 h1 {
 background: rgba(30%,0%,0%,0.6);
}
#st1 p {
 background: rgba(0%,10%,20%,0.6);
}

实际呈现可参阅 [范例一] ←没看到应该有的效果?

多层半透明色重叠效果 - 背景加上边线色 (border-color)

共同的 css 定义与范例一相同。

范例二 xhtml
<div id="st2" class="st">
 <div class="inner">
  <h1>也让时间等一等</h1>
  <p>积极很好。人,肯积极,多半心里有目标。…
     …以下略,实际内容见范例内…
  </p>
 </div>
</div>
css 增加定义半透明边线色 (border)
#st2 .inner {
 padding-bottom: 0.25em;
}
/*半透明背景色与例一雷同*/
#st2 h1 {
 background: rgba(40%,0%,0%,0.6);
 border-top: 2em solid;
 border-right: 260px solid;
 border-bottom: 0.5em solid;
 border-color: rgba(100%,100%,100%,0.2); /*20%白色*/
} /*三边加上不同宽度的 border*/
#st2 p {
 background: rgba(0%,10%,20%,0.6);
 border-top: 12px solid rgba(100%,100%,100%,0.4);
 border-right: 12px solid rgba(55%,55%,65%,0.4);
 border-bottom: 12px solid rgba(30%,30%,40%,0.4);
 border-left: 12px solid rgba(80%,80%,90%,0.4);
} /*四边加上40%不同颜色的 border*/

实际呈现可参阅 [范例二] ←没看到应该有的效果?

需要了解的是, css 指定元素的背景色或背景图片 (background) 会显示在 border edge 区域以内,也就是说, border 色与 background 色是重叠的,当 border 颜色定义成半透明时,就会与其后方背景颜色产生混合。在范例二中, h1 加了 20% 半透明白色 border ,但实际呈现的是叠合了暗红的半透明背景色,因而,在最后面的背景图片被不同的半透明颜色覆盖,而产生不同的层次感,并且因为宽度不同的 border 而使设计更具活泼感;而 p 则在四边运用不同的颜色与背景色混合,让背景图片产生较立体的半透明视觉效果。

这样的双层半透明网页设计效果,只在一个元素 (element) 上定义样式 (styles) 就可轻易完成,没有 css level 3 时根本困难重重。

文字半透明 (color) 效果

颜色单位 (color units) 当然可以用在 css color 特性 (property) , color 通常用来指定文字的颜色,所以也就可以让文字变成半透明了。

共同的 css 定义与范例一相同。

范例三 xhtml
<div id="st3" class="st">
 <div class="inner">
  <h1>也让时间等一等</h1>
  <p>积极很好。人,肯积极,多半心里有目标。…
     …以下略,实际内容见范例内…
  </p>
 </div>
</div>
css 把标题首字变半透明色 (color)
#st3 h1::first-letter {
 /* h1 第一个字变粗大且半透明呈现*/
 font: 900 900% "标楷体",simhei,"细明体";
 vertical-align: -8%;
 color: rgba(85%,100%,100%,0.5); /*50%亮蓝*/
}
/*半透明背景及边线,与前例雷同*/
#st3 h1 {
 background: rgba(40%,0%,0%,0.4);
 border-bottom: 20px solid rgba(50%,20%,30%,0.4);
 border-left: 60px solid rgba(50%,20%,30%,0.4);
 padding: 1em 1.25em 0 0;
}
#st3 p {
 background: rgba(0%,10%,20%,0.6);
 border-top: 12px solid rgba(100%,100%,100%,0.4);
 border-right: 12px solid rgba(55%,55%,65%,0.4);
 border-bottom: 12px solid rgba(30%,30%,40%,0.4);
 border-left: 12px solid rgba(80%,80%,90%,0.4);
}

实际呈现可参阅 [范例三] ←没看到应该有的效果?

当然,半透明文字的颜色也会与背景色叠合成另一个半透明色,再让最后面的背景图片穿透上来。

css 3 hsla 让定义色彩及明暗度更直觉

色相饱和度亮度 (Hue, Saturation, Lightness - HSL) 指定颜色,也是 css 3 开始有的颜色单位,与色彩模型中的 HSB 有些类似,或许还有很多人不太习惯,不过许多情况它还挺方便用的。

共同的 css 定义与范例一相同。

范例四 xhtml
<div id="st4" class="st">
 <div class="inner">
  <h1>也让时间等一等</h1>
  <p>积极很好。人,肯积极,多半心里有目标。…
     …以下略,实际内容见范例内…
  </p>
 </div>
</div>
css 改变半透明色的饱和度及亮度
#st4 .inner {
 padding: 1em 4%;
}
#st4 h1 {
 background: hsla(120,60%,20%,0.6);
 border-top: 1.5em solid hsla(120,40%,12%,0.3);
 border-right: 80px solid hsla(120,40%,50%,0.3);
} /*背景及边线都是绿色调*/
#st4 p {
 background: hsla(0,70%,30%,0.7);
 border-right: 80px solid hsla(0,70%,80%,0.2);
} /*背景及边线都是红色调*/

实际呈现可参阅 [范例四] ←没看到应该有的效果?

很多时候需要以同一种色调 (Hue or Tone),呈现出不同明暗度的感觉,让视觉上更有层次及立体感,范例中使用 hsla 定义颜色会是个好方法。眼尖的人应该已经看出,h1 或是 p 中指定的色相值 (Hue) 都是一样的,也就是说用了同一种色调,而只是单纯地在背景色 (background) 或是 border 定义不同的亮度值 (Lightness),就可以产生更有深度的视觉效果;而如果希望降低或增加颜色的鲜艳度,如范例中只需要指定较低或较高的饱和度值 (Saturation) 就可以了, h1 就只是稍微改变了饱和度。使用 hsl 定义颜色,确实可以让我们省却不断地挑选 rgb 颜色的麻烦,因为只要决定一个颜色,剩下就由亮度饱和度来调整就可以了。

未支援 rgba, hsla 的浏览器也想半透明效果

未支援具有半透明 alpha色彩单位 (color units) 的浏览器,如果使用 rgba, hsla 指定色彩,只会略过该项定义,但不会因此而影响样式表 (style sheets) 里其它的定义。因此,我们可以另外替未支援的浏览器定义一组色彩,以范例一背景定义为例:

css 增加定义给未支援浏览器
#st1 h1 {
 background: rgb(30%,0%,0%); /*未支援浏览器指定不透明色*/
 background: rgba(30%,0%,0%,0.6);
}
#st1 p {
 background: rgb(0%,10%,20%); /*未支援浏览器指定不透明色*/
 background: rgba(0%,10%,20%,0.6);
}

未支援的浏览器只会执行第一项不透明颜色的定义,第二项会略过不产生任何影响;对于有支援半透明色彩的浏览器,虽然两项定义都有效,但当然是以最后一项为执行的依据;所以,注意两项顺序颠倒就不会有半透明效果啰。这种作法,至少未支援的浏览器不至于结果差距太多。

png 格式半透明图片作为背景

未支援的浏览器如果也想要有类似前述半透明效果的背景颜色,只要先制作一个很小的 png 格式的半透明图片,例如 10×10 px 不透明度 (opacity) 70% 的黑色图片 [图例下载→ ] ,然后定义成背景图片 (background-image)。以范例一的 p 为例:

css 改成定义背景为半透明 png 图片
#st1 p {
 background: url(bg_bk70.png); /*未支援浏览器指定半透明背景图片*/
 background: rgba(0,0,0,0.7); /*70%黑色*/
}

第一项除了 ie 6 没办法「正确」呈现外,其实较新型浏览器 (包括 ie 7) 都会有半透明黑色背景,唯一有点不方便的是,如果定义不同颜色的半透明背景,每次都必须制作不同的半透明 png 图片。实际上,只需要第一项就可以在各家浏览器达到半透明背景的效果了。加上第二项将会更好,因为也可以让有支援 alpha 值的浏览器直接运用更便利的 css 半透明颜色定义方式,对未来更有帮助,第二项的定义会将背景图片 (background-image) 变成预设值 none (无)。

css 3 的 opacity 不透明度特性,像这样 opacity:0.7; ,如果想要运用在此处,其实不是很恰当,因为 opacity 的定义会使整个元素 (element) 都变成半透明,包括内容里的文字,如此可能影响阅读,目前却有很多人使用这种方法,有点匪夷所思,有兴趣可以参阅久久前的某一个讨论,里面也有提到麻烦的 opacity 处理方式及以下将会提到的 ie filter 中的 alpha opacity

filter 中的 alpha(opacity) 不透明度指定给 ie 6

ie 6 就需要用到 ie 专用 (ie only) 的 css filter 语法中 alpha 的不透明度 opacity ,不过这个方法也是整个元素 (element) 都会半透明呈现,而且元素必须指定 hasLayout property ;也由于是特定给 ie 6 的设计,所以最好运用 css hacks 技巧:

css 接著前例,定义半透明给 ie 6
* html #st1 p {
 background: rgb(0,0,0); /*背景黑色,也让先前指定的背景图片回复没有*/
 zoom: 1; /*hasLayout*/
 filter: progid:DXImageTransform.Microsoft.Alpha(opacity=70); /*70%不透明度*/
}

这是 ie 专用 (ie only) 语法, 所以其实 ie 7 也可以用。麻烦的问题是里面文字内容也半透明了,虽然有一奇特方法, css 定义其内层元素 (element) 为 position: relative; 就可让里面内容回复成不透明。但是像范例中的 p ,内层没有可定义的元素 (element) 也就没辄了,其实部落格设计也会遇到没办法自己增加元素的问题。另外,像范例中有卷轴产生卷动内容,但是在 ie 如果内层定义成 position: relative; ,该元素 (element) 就像是「固定」在原位,不会随卷轴卷动了。所以,指定 ie 这个特性时,只能多注意一点啰。

ie 6 也使用半透明 png 图片作背景

另一种 ie 专用 (ie only) 的 css filter 语法中 AlphaImageLoader ,可以让 ie 6 「较正确」呈现半透明 png 图片,不过图片会「插在」背景 (background) 及内容 (content) 之间,所以如果原先有指定背景,会变成像似两个重叠的背景:

css 改成「插入」半透明 png 图片当背景
* html #st1 p {
 background: none; /*先前指定的背景图片改回没有*/
 zoom: 1; /*hasLayout*/
 filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="bg_bk70.png",sizingMethod="scale");
 /*插入图片并缩放至与元素同尺寸*/
}

图片会由所在元素的 border box 左上角开始插入。语法中 filter 内的 src="bg_bk70.png" (绿字) ,明显地,双引号内就是指出图片档的位址。而 sizingMethod="scale" 可以有三种选择:

  • sizingMethod="image" :不论所在元素的 Box 大小,图片一律以图片本身尺寸完整显示。如果 Box 尺寸大于图片, Box 超过图片的区域会被「裁掉」不显示;如果 Box 尺寸小于图片, Box 会保持尺寸,不会增大,而图片则会「突出」 Box 范围。这个定义是预设值,所以没有 sizingMethod 这段时,仍会套用此定义。
  • sizingMethod="scale" :图片会自动依据元素的 border box 尺寸缩放,所以图片呈现可能会宽高不等比例变形。
  • sizingMethod="crop" :图片会保持图片本身尺寸,但是图片超出 Box 范围的部分,不会显示,类似 css 定义背景图片的呈现方式。

看起来似乎达到想要的半透明背景效果,也不会让内容文字也变半透明。这样的作法只是为了让原本不能正确呈现的 ie 也能有我们想要的效果,严格说起来应算是 ie 的旁门左道,并非 w3c 标准规范。怪的是 ie 仍有不可预期的问题,使用时要先有心理准备就是了,像是内容如果包括需要滑鼠感应的元素 (如按钮、输入项之类) ,会变成无法执行,又得以 css 指定这类元素 position:relative; 才会作用。

参考资源
散布、展示请参阅 Creative Commons 授权条文,禁止重混,引述请增加原文连结。
相关文章