Indeks z jest anulowany przez ustawienie przekształcenia (obrotu)

85

Używając właściwości transform, indeks z jest anulowany i pojawia się na początku. (Podczas komentowania out -webkit-transform, z-index działa poprawnie w poniższym kodzie)

.test {
  width: 150px;
  height: 40px;
  margin: 30px;
  line-height: 40px;
  position: relative;
  background: white;
  -webkit-transform: rotate(10deg);
}

.test:after {
  width: 100px;
  height: 35px;
  content: "";
  position: absolute;
  top: 0;
  right: 2px;
  -webkit-box-shadow: 0 5px 5px #999;
  /* Safari and Chrome */
  -webkit-transform: rotate(3deg);
  /* Safari and Chrome */
  transform: rotate(3deg);
  z-index: -1;
}
<html>

<head>
  <title>transform</title>
  <link rel="stylesheet" type="text/css" href="transformtest.css">
</head>

<body>
  <div class="test">z-index is canceled.</div>
</body>

</html>

Jak współdziałają transform i z-index?

kbth
źródło
To jest skrzypce, które zrobiłem. Czy chcesz ukryć tekst za pomocą indeksu z?
Surjith SM
Działa dobrze jsfiddle.net/raunakkathuria/8MQkP, jakie właściwie są wątpliwości?
Raunak Kathuria
Dziękuję za robienie skrzypiec. Chcę pokazać cień za prostokątem tekstu (jak post-it).
kbth

Odpowiedzi:

141

Przejdźmy przez to, co się dzieje. Na początek zwróć uwagę, że z-indexna pozycjonowanych elementach i transformsamodzielnie utwórz nowe „ konteksty układania ” na elementach. Oto co się dzieje:

Twój .testżywioł matransform ustawiony na coś innego niż none, co daje mu własny kontekst stosu.

Następnie dodajesz .test:afterpseudoelement, który jest dzieckiem .test. To dziecko ma z-index: -1, ustawienie poziomu stosu .test:after w kontekście stosu.test Ustawienie z-index: -1on .test:afternie powoduje umieszczenia go za nim, .testponieważz-index ma znaczenie tylko w danym kontekście układania.

Po usunięciu -webkit-transformz .testniego usuwa kontekst układania, powodując .testi .test:afterudostępniając kontekst układania (kontekst <html>) i .test:afterprzechodząc za nim .test. Zauważ, że po usunięciu reguły .test' -webkit-transformmożesz ponownie nadać jej własny kontekst stosu, ustawiając nową z-indexregułę (dowolną wartość) na .test(ponownie, ponieważ jest ustawiona)!

Jak więc rozwiążemy Twój problem?

Aby indeks Z działał zgodnie z oczekiwaniami, upewnij się, że .testi .test:afterudostępniaj ten sam kontekst stosu. Problem polega na tym, że chcesz .testobracać z transformacją, ale zrobienie tego oznacza utworzenie własnego kontekstu stosowego. Na szczęście umieszczenie .testw opakowaniu do owijania i obracanie, które nadal pozwoli jego dzieciom udostępniać kontekst układania, jednocześnie obracając oba.

  • Oto, od czego zacząłeś: http://jsfiddle.net/fH64Q/

  • A oto sposób na obejście kontekstów układania i utrzymanie rotacji (zwróć uwagę, że cień jest nieco odcinany z powodu .testbiałego tła):

.wrapper {
    -webkit-transform: rotate(10deg);
}
.test {
       width: 150px;
       height: 40px;
       margin: 30px;
       line-height: 40px;
       position: relative;
       background: white;
}
.test:after {
       width: 100px;
       height: 35px;
       content: "";
       position: absolute;
       top: 0;
       right: 2px;
       -webkit-box-shadow: 0 5px 5px #999; /* Safari and Chrome */
       -webkit-transform: rotate(3deg); /* Safari and Chrome */
       transform: rotate(3deg);
       z-index: -1;
}
<div class="wrapper">
    <div class="test">z-index is canceled.</div>
</div>

Są na to inne sposoby, nawet lepsze. Prawdopodobnie uczyniłbym tło "post-it" elementem zawierającym, a następnie umieściłbym tekst w środku, to prawdopodobnie byłaby najłatwiejsza metoda i zmniejszyłaby złożoność tego, co masz.

Zapoznaj się z tym artykułem, aby uzyskać więcej informacji na temat z-indexkolejności układania w stosy lub działającej specyfikacji W3C CSS3 dotyczącej kontekstu układania

Lochlan
źródło
4
To było świetne wyjaśnienie jednego z najbardziej złożonych aspektów układu CSS. Aby przeczytać w przyszłości, sprawdź specyfikację W3
AndyBean
12

Ustaw div, na którym chcesz pozostać na górze position:relative

AGrush
źródło
1
U mnie to zadziałało. Czy jest to związane z wyżej wymienionym kontekstem stosów? Jeśli ktoś pomoże wyjaśnić, będzie to bardzo cenne.
glihm
7

Miałem podobny problem, gdy rodzeństwo było transform: translate()i z-indexnie pracowało.

Najprostszym rozwiązaniem jest ustawienie position: relativena całe rodzeństwo, a potem z-indexznowu zadziała.

seeker_of_bacon
źródło
5

Szybka naprawa: Możesz po prostu obrócić drugi element o 0 stopni.

Chłopak
źródło
U mnie to zadziałało w przypadku, gdy nie mogłem obrócić pojemnika
Daniel Flippance
1
Miałem dziwny problem z niezauważaniem indeksu Z, a następnie zastosowanie stylu transform:rotate(0.0rad)go naprawiło. Nie mogłem go zastosować za pomocą reguły css, musiał on znajdować się bezpośrednio na elemencie. To NIE ma sensu, ale dziękuję za opublikowanie odpowiedzi, która skłoniła mnie do spróbowania.
Andrew Shepherd
1

Miałem podobny problem. To, co zrobiłem, to dodałem element div opakowujący wokół testu i przekazałem właściwość transform do elementu div wrapper.

.wrapper{
    transform: rotate(10deg);
}

tutaj jest skrzypce http://jsfiddle.net/KmnF2/16/

Ankur Sahu
źródło
-1

Ustaw div, na którym chcesz pozostać na górze, na pozycję: bezwzględną


źródło