Кроссбраузерная одноцветная полупрозрачность

:

В этой статье я рассмотрю метод создания блоков с одноцветным полупрозрачным фоном.
Например, таких:


Сразу оговорюсь, что я не буду использовать opacity и абсолютное позиционирование, чтобы разместить контент поверх полупрозрачного блока.

Итак, нам нужно сделать блок с однотонным полупрозрачным фоном. Для этого можно использовать свойство opacity, но все знают, что оно применяется не только к самому элементу, но и к его детям. Можно, конечно, схитрить и применить opacity к элементу-подложке, а сам контент разместить в другом блоке, и, затем, переместить этот блок на элемент-подложку с помощью абсолютного позиционирования. Но у этого метода есть существенные недостатки, во-первых, необходимо точно знать размеры блока, а, во-вторых, добавляются лишние несемантические элементы.

Всех этих недостатков можно избежать, если вместо opacity использовать однопиксельную картинку нужного цвета с заданной прозрачностью. Но, в таком случае, будет происходить лишний http-запрос, что нежелательно.

В CSS3 появилась возможность задавать цвет фона элементу при помощи RGBA это, по сути, тот же RGB но с возможностью указать значение прозрачности.

.opacity {
background: rgba(0, 0, 0, 0.5);
}


пример (RGBA)

Но, к сожалению, задание цвета фона через RGBA поддерживается только в новых версиях Safari (Chrome тоже) и Firefox. Для старых версий Safari, Firefox а также для Opera и IE8 (Ура!), чтобы избавиться от лишнего http-запроса, можно использовать Data:URI:

.opacity {
background:url(data:image/png;base64,iVBORw0KGg...);
}


пример (Data:URI)

Где, iVBORw0KG... это наша однопиксельная полупрозрачная картинка, закодированная base64. Такое представление файла получить достаточно просто. Можно, например, использовать Data: URI image encoder.

Объединив вместе эти два способа получим:

.opacity {
background:url(data:image/png;base64,iVBORw0KGg...);
background:rgba(0, 0, 0, 0.5);
}


пример (RGBA + Data:URI)

Этот пример уже работает для FF 1.5+, Opera 7.2+, Safari 2+, Chrome, Konqueror, IE 8.
Но что делать с IE 7 и IE 6? Здесь нам поможет фильтр Alpha и один маленький трюк. Дело в том, что если к элементу применить фильтр Alpha и потом дать всем потомкам этого элемента position: relative;, то они чудесным образом становятся полностью непрозрачными:

.opacity {
zoom:1; /* hasLayout чтобы фильтр применился */
background:#000;
filter:alpha(opacity=50);
}

.opacity * {
position:relative;
}


пример (IE 6 и 7)

Итак, совмещая все вместе получим:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
<head>
<title>Opacity Block</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<style type="text/css">
* {
margin:0;
padding:0;
}
html {
font-size:100.01%;
}
body {
font:.8em Arial, Helvetica, sans-serif;
color:#fff;
background:url(bg_pattern.jpg);
}
a {
color:#fff;
}
h1 {
font-weight:normal;
margin:0 0 .5em;
}
p {
margin:0 0 .5em;
}
.opacity {
margin:40px;
padding:20px;
background:url(data:image/png;base64,iVBORw0KG...);
background:rgba(0, 0, 0, 0.5);
}
</style>
<!--[if lte IE 7]>
  <style type="text/css">
   .opacity {
    zoom:1;
    background:#000;
    filter:alpha(opacity=50);
   }
   
   .opacity * {
    position:relative;
   }
  </style>
 <![endif]-->
</head>
<body>
<div class="opacity">
<h1>Привет!</h1>
<p>Это полупрозрачный блок.</p>
</div>
</body>
</html>

* This source code was highlighted with Source Code Highlighter.


конечный результат

Пример протестирован и корректно работает в IE 6+, FF 1.5+, Opera 7.2+, Safari 2+, Chrome, Konqueror 4.1. Из недостатков, не работает в IE < 6.