CSS: зависание не работает из-за непрозрачности

У меня проблема с strangs CSS.

Ниже приведен очень простой пример кода, демонстрирующий проблему.

<html>
  <head>
     <style>
      .hover {
        float: right;
      }
      .hover:hover {
        background-color: blue;
      }
      .blocker {
        opacity: 0.5;
      }
    </style>
  </head>
  <body>
    <div class="hover">hover</div>
    <div class="blocker">blocker</div>
  </body>
</html>

У меня есть div A, плавающий над другим div B, который имеет непрозрачность 0,5. И я хочу добавить правило наведения CSS в плавающий div. Но по какой-то причине я не могу.

Я плаваю вправо или влево, не имеет значения.

Но когда я изменяю непрозрачность до 1, правило наведения работает внезапно.

Может ли кто-нибудь объяснить это поведение?

Я могу "исправить" проблему, обернув содержимое блокатора div в промежутке, но мне кажется, что мне не нужно.

Здесь jsFiddle, демонстрирующий проблему: http://jsfiddle.net/ed82z/1/

Ответы

Ответ 1

Проще говоря - это "выше", если непрозрачность имеет менее 1 значения.

Ключевым термином здесь является Контекст стеков.

Установив непрозрачность на значение меньше единицы, она будет различаться по-разному в соответствии со спецификацией, так как она получает новый контекст стекирования и располагается под элементом.

Здесь указано float и непрозрачность:

Корневой элемент формирует контекст укладки корня. Другие контексты стекирования генерируются любым позиционируемым элементом (включая относительно позиционированные элементы), имеющим вычисленное значение "z-index", отличное от "auto". Контексты стеков не обязательно связаны с блоками. В будущих уровнях CSS другие свойства могут вводить контексты стекирования, например "непрозрачность" [CSS3COLOR].

Из прозрачности:

Так как элемент с непрозрачностью менее 1 составлен из одного внеэкранного изображения, содержимое за его пределами не может быть наложено в z-порядке между кусками содержимого внутри него. По той же причине реализация должна создать новый контекст стекирования для любого элемента с непрозрачностью менее 1. Если элемент с непрозрачностью менее 1 не помещен, реализации должны рисовать создаваемый им слой в контексте родительского стека, в том же порядке укладки, который будет использоваться, если бы он был позиционированным элементом с "z-index: 0 и" непрозрачностью: 1. Если элемент с непрозрачностью меньше 1, то свойство "z-index" применяется, как описано в [ CSS21], за исключением того, что "auto обрабатывается как" 0 ", поскольку всегда создается новый контекст стекирования. Дополнительную информацию о контекстах стекирования см. В разделе 9.9 и в приложении E [CSS21]. Правила этого параграфа не применяются к элементам SVG, поскольку SVG имеет свою собственную модель рендеринга ([SVG11], глава 3).

Как это исправить:

Вы можете установить pointer-events на none, см. эту скрипту.

Ответ 2

Добавление overflow: hidden работало для меня:

.blocker {
    opacity: 0.5;
    overflow:hidden;
}

Или:

.blocker { 
        opacity: 0.5;
        position:relative; 
        z-index:-1;
}

(спасибо @Eyal Barta за этот вариант)

http://jsfiddle.net/ed82z/7/

Это связано с тем, что .blocker накладывает ваш другой div, который легко отображается с помощью firebug или других инструментов разработчика.

Когда вы добавляете непрозрачность, вы добавляете "контекст стекирования".

This occurs because these DIVs have special properties which cause them to form a stacking context.

В этом случае: elements with an opacity value less than 1. Что дает ваш div z-index, и это приводит к тому, что div будет отображаться в другом порядке.

Контекст стеков

Ответ 3

В .blocker класс перекрывает класс .hover из-за float:right;

.blocker {
    opacity: 0.5; 
    width:100px
}

вы можете исправить этот набор float:left в классе блокировщика или установить width:100px на фиксированную ширину для div, которая не будет перекрываться.