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

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


    Сразу оговорюсь, что я не буду использовать 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.
    Поделиться публикацией
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 80
    • 0
      спасибо, здорово.

      хороший пример использования rgba с graceful degradation можно увидеть на 24ways.org/

      только, наверное, не «внуки», а «дети» или «потомки»?
      • +2
        Да, потомки хорошо. Исправил.
      • 0
        Взял на заметку.
        • –2
          FF 3.0.5 (Win)
          черный кирпич, никакой прозрачности
          • +1
            FF 3.0.5 (Win)
            Все прозрачно
          • –8
            полупрозрачным стало только после перезагрузки страницы
          • 0
            Отличный пример, большое спасибо!
            • +2
              Думаю, «ниже IE6» уже как таковым недостатком-то не является.
              • –8
                Хорошая статья, не хватает только ссылки на оригинал, откуда взят источник инфы для перевода. Сам хотел перевести но не успел.
                • +4
                  Какой источник? Это и есть оригинал.
                  • +3
                    Извини, если обидел. Просто видел пару очень похожих статей у буржуев.
                • 0
                  немного офтопа. может в каскадные таблицы перенести? как-то точнее получится.
                  • НЛО прилетело и опубликовало эту надпись здесь
                    • 0
                      В смысле? position:relative обязательное условие, но внутри элемента с positon:relative могут быть также любые другие элементы, например с position:absolute, и они тоже будут непрозрачными. И hasLayout если будет глючить можно дать.
                      • НЛО прилетело и опубликовало эту надпись здесь
                        • 0
                          Ну вот пример: http://markup.xtreemhost.com/opacity/opacity_example.html. Вроде все нормально.
                          • НЛО прилетело и опубликовало эту надпись здесь
                            • НЛО прилетело и опубликовало эту надпись здесь
                              • +1
                                Как-то Вы странно JS выключаете, потому как фильтры к JS не имеют никакого отношения. А много памяти жрет из-за фильтра, это неизбежно.
                        • НЛО прилетело и опубликовало эту надпись здесь
                        • –2
                          ИЕ5.5 арбайтен гут :) в 5.0 fail ;)
                          • +2
                            в 5.5 тоже fail так как контент тоже становится полупрозрачным
                        • НЛО прилетело и опубликовало эту надпись здесь
                          • 0
                            >Для этого можно использовать свойство opacity, но все знают, что оно применяется не только к самому элементу, но и к его детям
                            Не помню точно, но я внутрь полупрозрачного блока ставил еще один блок с непрозрачным опасити (то бишь = 1 или 100) и всё было тип-топ =)
                            • 0
                              Нет, так не получится.
                              • 0
                                тоочно. извиняюсь, помню боролся с такой проблемой и там всё-таки использовал пнг.
                            • 0
                              А можно полупрозрачный блок, сделать округлённым? А точнее, закруглить уголочки?
                              • 0
                                Можно. То что представлено тут это середина такого блока, как делать скругленные уголки много где написано.
                                • 0
                                • +1
                                  А зачем этот кусок?

                                  html {
                                  font-size:100.01%;
                                  }
                                  • 0
                                    Чтобы одинаковый размер был во всех браузерах, погуглите, это известная штука.
                                  • 0
                                    Чтобы с размером шрифта во всех браузерах было все нормально.
                                    • 0
                                      кстати, в opera 10 RGBA работает (-;
                                      • 0
                                        для IE тогда можно еще через mhtml сделать :)
                                        webo.in/articles/habrahabr/46-cross-browser-data-url/
                                        • НЛО прилетело и опубликовало эту надпись здесь
                                          • 0
                                            почему? mhtml понимается с IE5 или IE5.5
                                            • НЛО прилетело и опубликовало эту надпись здесь
                                              • 0
                                                alphaImageLoader?
                                                • НЛО прилетело и опубликовало эту надпись здесь
                                      • +1
                                        Вот все бы извращаться ;)
                                        Четырехпиксельный гиф у которого 2 пикселя прозрачны, а 2 черные работает везде без проблем.
                                        А если зерно мониторов таки будет уменьшаться, то будет работать все лучше и лучше
                                        • 0
                                          Дык смысл-то как раз в отсутствии дополнительной картинки.
                                          По сабжу — в избранное!
                                          • +2
                                            Сталевар-алкаш Вася с недоумением смотрит на dvd-плеер Сони и думает: «вот извращенцы, нет бы сделать, что бы видео-кассеты проигрывались».
                                        • +1
                                          За интересные идеи спасибо.
                                          Только не следует забывать, что можно простую png-картинку фоном ставить. Поддержка сразу везде, кроме IE6, а вот для него уже изврат с alfa и relative
                                          Это я просто напоминаю чтобы не зацикливались читающие эту тему)
                                          • 0
                                            Я это знаю, но хотелось как раз избавиться от лишнего запроса на такую маленькую картинку.
                                            • 0
                                              от лишнего запроса к картинке избавляемся, зато добавляем кучу кода и 3 костыля вместо одного…
                                              Мне кажется лучше использовать 1 общее, универсальное решение…
                                              По крайней мере до стадии оптимизации проекта

                                              хотя за способы большое спасибо, про (Data:URI) не знал
                                              • 0
                                                Где 3? Я насчитал только один (position: relative для потомков).
                                                • 0
                                                  ну как где?
                                                  1. background:url(data:image/png;base64,iVBORw0KG...);
                                                  2. background:rgba(0, 0, 0, 0.5);
                                                  3. filter:alpha(opacity=50);

                                                  • +1
                                                    Какие же это костыли? Dara:URI это стандарт. В том случае, когда все браузеры будут поддерживать RGBA (что тоже стандарт), можно будет убрать эту строчку. Пока же, те браузеры, которые уже поддерживают RGBA получают бекграунд через rgba. Progressive enhancement на лицо. 3 согласен, костыль, но если вы будете делать через полупрозрачную загружаемую картинку, то вам тоже придется использовать фильтр, только не Alpha а AlphaImageLoader. Поэтому в данном случае, по костылям получается один (AlphaImageLoader) против двух (Alpha + position:relative у потомков).
                                                    • 0
                                                      ладно уговорили :) не костыли
                                                      в любом случае при необходимости что-то изменить, придётся ковыряться в трёх местах, вместо одного, это может вызвать путанницу, особенно если решение для ие выносить в отдельный файл
                                                    • 0
                                                      Костыль, действительно, только один для IE6:
                                                      filter:alpha(opacity=50) и position:relative для потомков.
                                                      Остальное всё стандартно совешенно — используются приемущества прекрасной деградируемости CSS.
                                            • 0
                                              Делаю точно так же, только какртинки подгружаю :)
                                              Только, вот, с Opera 10 и таблицами засада — она не поддерживает нормально RGBA для ячеек таблицы (цвета COL за ячейками не видно).
                                              Я отправил эту ошибку уже.
                                              • 0
                                                Про трюк с IE6 и 7 не знал, спасибо!
                                              • +7
                                                Для IE есть такой трюк:

                                                filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#00000050,endColorstr=#00000050);

                                                HEX-цвет + прозрачность
                                              • 0
                                                Кстати, как вариант борьбы с IE6, можно оставить его без прозрачности, использовав PNG8, если это позволяет дизайн.
                                                • 0
                                                  для борьбы с IE6 лучше сложиться на двухстволку и сокращать количество юзеров, которые им пользуются :)
                                                • +1
                                                  Можно в .opacity положить контейнер (например div class='opacity-content') и назначить position:relative только ему вместо пугающего
                                                  .opacity * {position:relative;}
                                                  • –1
                                                    Еще одна хорошая статья про прозрачность была у Чернева chernev.ru/pravilnaya-prozrachnost.html, демо: chernev.ru/css-opacity/
                                                    • 0
                                                      До кучи The data: URI kitchen
                                                      • 0
                                                        Не работает, см. скриншот

                                                        img13.imageshack.us/img13/5417/ffailbl7.png
                                                        • 0
                                                          Пардон, не заметил ссылку «конечный результат».
                                                        • 0
                                                          Весьма интересно, кроме IE, в котором происходит непонятный кирдык сглаживанию шрифтов в блоке.
                                                          Чудеса в решете — установленный в системе IE7 не сглаживает текст, IE6 через IETester — сглаживает…
                                                          • НЛО прилетело и опубликовало эту надпись здесь
                                                            • 0
                                                              Интересно, какой фильтр включает его обратно…
                                                            • 0
                                                              Да, это проблема всех фильтров: http://blogs.msdn.com/ie/archive/2006/08/31/730887.aspx. Там в комментах советуют давать background-color, но он у нас уже установлен.
                                                            • –1
                                                              В примере автора статьи картинка является полноцветной, что увеличивает время загрузки. Возможно лучше работать с таблицей и вставить бегграундом в блоке оптимизированный и полупрозрачний рисунок png
                                                              • 0
                                                                У меня почему-то при абсолютном позиционировании прозрачного блока в IE6, IE7 дочерние элементы тоже становятся прозрачными, это никак нельзя исправить?
                                                                • 0
                                                                  Можно сделать, через фильтр Gradient, как предлагают тут: habrahabr.ru/blogs/webdev/50996/#comment_1345139 (только в комментарии неточность, значение прозрачности надо писать перед RGB: #50000000), но прозрачность будет не совсем такая, нужно экспериментировать. Либо, можно обернуть то, что внутри элемента с position:absolute в какой-нибудь другой элемент (с position:static) и перевесить фильтр Alpha на него. Вообще, не рекомендую давать фильтры элементам, значение свойства position которых отлично от static. Могут возникнуть проблемы связанные с обрезанием контента, который выходит за границы блока, или полным исчезновением элемента.
                                                                • 0
                                                                  У меня возникла проблема с этим методом, если внутри прозрачного блока располагать, скажем, список или таблицу, то в IE ничего не отображается.
                                                                  Причем с инлайновыми элементами и c div'ом все показывает.
                                                                  Кто-то еще сталкивался с подобным?
                                                                  • 0
                                                                    Вы не могли бы переложить картинки на хаброэффект.ру например?
                                                                    • 0
                                                                      Можно считать, что переложил ;)
                                                                    • 0
                                                                      markup.xtreemhost.com/opacity/ie.html — в FF 3.6 блок имет непрозрачный черный фон. в других примерах все хорошо.
                                                                      или это у меня с браузером что-то не так?
                                                                      • 0
                                                                        URL как бы намекает, что этот вариант только для просмотра в IE. Внизу есть ссылка на финальный кроссбраузерный вариант.
                                                                      • 0
                                                                        громадное спасибо! Сэкономили кучу нервов! и спасибо за data!

                                                                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.