<div class="cube"></div> <p>Без <code>opacity</code> контекст наложения строится относительно корневого элемента. Поэтому порядок отрисовки такой: фон корневого элемента (фактический <code>z-index</code> — минус бесконечность), затем <code>::before</code> (<code>z-index</code> отрицательный), затем сам <code>.cube</code> (<code>z-index</code> автоматический, по факту нулевой).</p> <p>С <code>opacity</code> (и <a href="https://developer.mozilla.org/ru/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context#Контекст_наложения">еще несколькими свойствами</a>) контекст наложения строится относительно <code>.cube</code>. Поэтому порядок отрисовки <code>.cube</code> и его потомков такой: фон <code>.cube</code> (фактический <code>z-index</code> — минус бесконечность), затем <code>::before</code> (любой <code>z-index</code>, даже отрицательный, будет выше минус бесконечности). Поэтому <code>::before</code> перекрывает фон <code>.cube</code> и скрывает его.</p> <p>Ну а сама <code>opacity</code> применяется к уже итоговому отрисованному <code>.cube</code>, как к единой картинке (текстуре). Поэтому мы видим не 2 полупрозрачных слоя, просвечивающих друг через друга, а один полупрозрачный слой.</p>