#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.