Есть ли какой-либо способ применить непрозрачность к абсолютно расположенным дочерним элементам в ie8

#css #internet-explorer #parent-child #opacity #css-position

#css #internet-explorer #родитель-потомок #непрозрачность #css-position

Вопрос:

В большинстве браузеров, когда html-элемент непрозрачен лишь частично, его дочерние элементы «наследуют» эту непрозрачность. (Это не совсем наследование — точнее, все изображение собирается рекурсивно, включая родительский элемент и его дочерние элементы, а затем непрозрачность применяется ко всему объекту.)

В IE8 (и я бы предположил, что также для более ранних версий IE) это не всегда то, что происходит с непрозрачностью. Если дочерние элементы имеют position:static (по умолчанию, если позиция не указана), то это работает так, как я описал выше. Однако, похоже, что если для позиции задано что-либо другое (например, абсолютное или относительное), то дочерний элемент полностью непрозрачен.

Я хочу знать, как заставить непрозрачность правильно влиять как на родительский, так и на дочерний элементы, но при этом сохранить дочерний элемент с position: absolute;

Вот пример проблемы. Предполагается, что следующий код создаст полупрозрачный серый прямоугольник с полупрозрачной синей окружающей областью поверх вертикальной красной полосы. В Firefox, Chrome и т.д. Это то, что на самом деле видно. В IE8 синяя рамка правильно прозрачна, но серая часть непрозрачна.

 <!doctype html>
<html>
  <head>
    <style>
      div.parentElem
      {
        background-color:#0000ff;
        position: absolute;
        left:75px;
        top:75px;
        width:300px;
        height:225px;        
        opacity:0.5;
        filter:alpha(opacity=50);
      }
      div.childElem
      {
        background-color:#808080;
        position: absolute;
        left: 10px;
        right: 10px;
        top: 10px;
        bottom: 10px;
      }
      div.redBar
      {
        position: absolute;
        left:150px;
        top:50px;
        height:350px;
        width:25px;
        background-color: #ff0000;        
      }
    </style>
  </head>
  <body>
    <div class="redBar"></div>
    <div class="parentElem">
      <div class="childElem"></div>
    </div>
  </body>
</html>
  

Очевидно, что это всего лишь игрушечный пример — у меня мог бы быть один div с синей рамкой и серым фоном для достижения желаемого эффекта. В реальном сценарии я накладываю несколько разных разделов, каждый из которых имеет фоновое изображение в формате png для динамического построения изображения.

Моей первой попыткой обхода было применить непрозрачность как к родительскому, так и к дочернему элементам, либо установив для дочернего фильтра значение alpha (непрозрачность = 50); или просто установив filter:inherit; . Это не дает желаемого результата, потому что создает полупрозрачный синий прямоугольник с полупрозрачным серым прямоугольником поверх него. Пустое пространство в середине становится полупрозрачным сине-серым, тогда как оно должно быть полупрозрачно-серым. Аналогично, это не работает, чтобы сделать элементы родственными. Любое решение должно скомпоновать два изображения, прежде чем применять какую-либо прозрачность к чему-либо.

В моем исследовании я нашел несколько предложений о том, что применение zoom: 1; или float: none; к внутреннему элементу могло бы решить проблему, но ни то, ни другое не сработало для меня.

Моим возможным обходным решением было присвоить дочернему элементу position: static. Это своего рода уродливое решение, но что я бы сделал, чтобы применить его к приведенному выше примеру, так это изменил стиль дочернего элемента, чтобы он выглядел как:

   div.childElem
  {
    background-color:#808080;
    position:static;
    margin-left:10px; 
    margin-right:10px;
    height:205px;
    margin-top:10px;
  }
  

Это своего рода уродливое решение, потому что это означает, что я должен знать высоту объекта. Кроме того, в реальном случае, когда я составляю несколько разных png-файлов, и я хотел бы, чтобы они были логическими братьями и сестрами, я должен поместить их все во вложенные отношения родитель-потомок-внук- и т.д. Это также не позволяет мне добавлять какие-либо текстовые элементы, кроме как в самую верхнюю часть стека (самый внутренний div), не нарушая позиционирования. Однако это работает и выглядит одинаково во всех браузерах.

Есть ли какой-либо способ избежать такого ужасного обходного пути и корректно повлиять на непрозрачность дочерних элементов, не делая положение статичным? Спасибо!

Ответ №1:

 div.parentElem *{filter:inherit;}
  

смотрите:

http://seanmonstar.com/post/709013028/ie-opacity-ignores-positioned-children

Ответ №2:

Укажите ширину в дополнение к высоте для div.childElem. В вашем случае:

 width:280px;
  

Вероятно, это связано со старым добрым hasLayout.

Комментарии:

1. Хотя это и здорово, но, боюсь, это не сработало. Я добавил некоторый javascript, чтобы показать me .style.hasLayout для внутреннего элемента. Похоже, это не связано:

2. Я могу создать все четыре комбинации непрозрачности рабочая / неисправная и hasLayout true / false. (позиция: статическая с указанной высотой обеспечивает значение hasLayout true и непрозрачность рабочая; позиция: абсолютная (с шириной и высотой или без них) выдает значение hasLayout true и непрозрачность нарушена; позиция: статическая и без высоты / ширины обеспечивает значение hasLayout false и непрозрачность рабочая; позиция: относительная и без размера обеспечивает значение hasLayout false и непрозрачность нарушена.)

Ответ №3:

Поскольку только IE понимает filter правило, вы можете использовать его для дочерних элементов, когда знаете, что они расположены… Я не нашел «правильного» решения =/

Ответ №4:

Мне удалось найти один способ корректного применения непрозрачности к абсолютно расположенным дочерним элементам. Когда я не даю странице никакого doctype вообще, непрозрачность применяется правильно. На самом деле, поскольку это переводит браузер в режим quirks, обычно это нежизнеспособное решение.

Комментарии:

1. Лучший вывод, к которому я могу прийти на основе своих исследований, заключается в том, что вы просто не можете корректно наследовать непрозрачность в IE8 (и Ie<8) с абсолютно расположенными элементами.

Ответ №5:

Небольшая поправка к вашему вопросу. Это странное поведение происходит только в IE8. Оба IE7 и IE9 отображают ожидаемое поведение (где дочерние элементы сначала накладываются на родительский элемент, а затем фильтр применяется ко всей составной группе). IE8 также нарушается, когда родительский элемент имеет значение position: relative (и когда дочерние элементы являются либо абсолютными, либо относительными).

Ответ №6:

Краткий ответ: установите альфа-фильтр желаемой непрозрачности для дочернего элемента.

Вот подробное объяснение с примерами: http://jacklmoore.com/notes/ie-opacity-inheritance /

Ответ №7:

Я добился некоторого успеха с

 selector {
    -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
    filter: alpha(opacity=50);
    z-index: -1;
}
  

Я использую -1, поскольку это, похоже, не так сильно влияет на z-упорядочение, как положительный z-индекс, но из того, что я нашел, работает любой z-индекс, не являющийся автоматическим / наследуемым / 0.