Kwiat paradoksu z indeksem CSS

98

Chciałbym stworzyć paradoksalny efekt poprzez właściwość z-index CSS .

W moim kodzie mam pięć okręgów, jak na poniższym obrazku, i wszystkie one są absolutnie ustawione bez zdefiniowania z-index. Dlatego domyślnie każde koło nakłada się na poprzednie.

W tej chwili okrąg 5 zachodzi na okrąg 1 (lewy obraz). Paradoks, który chciałbym osiągnąć, to mieć jednocześnie kółko 1 pod okręgiem 2 i nad okręgiem 5 (jak na prawym obrazku).


(źródło: schramek.cz )

Oto mój kod

Narzut:

<div class="item i1">1</div>
<div class="item i2">2</div>
<div class="item i3">3</div>
<div class="item i4">4</div> 
<div class="item i5">5</div>

CSS

.item {
    width: 50px;
    height: 50px;
    line-height: 50px;
    border: 1px solid red;
    background: silver;
    border-radius: 50%;
    text-align: center;
}

.i1 { position: absolute; top: 30px; left: 0px; }
.i2 { position: absolute; top: 0px; left: 35px; }
.i3 { position: absolute; top: 30px; left: 65px; }
.i4 { position: absolute; top: 70px; left: 50px; }
.i5 { position: absolute; top: 70px; left: 15px; }

Przykład na żywo jest również dostępny pod adresem http://jsfiddle.net/Kx2k5/ .

Wypróbowałem wiele technik układania zamówień, zestawiania kontekstu i tak dalej. Czytałem kilka artykułów na temat tych technik, ale bez sukcesu. Jak mogę to rozwiązać?

1ubos
źródło
10
Jeśli to tylko wyzwanie z kodowaniem, może to należy do codegolf?
TylerH
12
Myślę, że OP szuka pomocy. Chodzi mu o to, aby rozwiązać go wyzwaniem. Myślę, że jest to coś, z czego wielu się nauczy. Dla mnie ta technika jest przydatna.
LOTUSMS
@ 1ubos. Brak jQuery / JS w ogóle? Wydaje mi się, że będzie to wymagało logicznego wykorzystania IndexOf
LOTUSMS
5
nie jest to możliwe przy użyciu indeksu z. Z-index definiuje warstwy, jest to sekwencja liczb całkowitych: -x, 0, x, których nie możesz mieć: x1 <x2 <x1
gondo
4
Nie omijaj filtra jakości za pomocą fałszywego bloku kodu. Albo umieść kod w samym pytaniu, albo usuń link do skrzypiec, jeśli nie jest to konieczne. Ponadto radziłbym ci przeformułować to na rzeczywisty problem z badaniami, a nie WYZWANIE, jeśli chcesz, aby twoje pytanie zostało potraktowane poważnie.
BoltClock

Odpowiedzi:

91

Oto moja próba: http://jsfiddle.net/Kx2k5/1/
(z powodzeniem przetestowany na Fx27, Ch33, IE9, Sf5.1.10i Op19)


CSS

.item {
   /* include borders on width and height */  
   -webkit-box-sizing : border-box;
   -moz-box-sizing    : border-box;
   box-sizing         : border-box;
   ...
}

.i1:after {
   content: "";

   /* overlap a circle over circle #1 */
   position : absolute;
   z-index  : 1;
   top      : 0;
   left     : 0;
   height   : 100%;
   width    : 100%;

   /* inherit border, background and border-radius */
   background    : inherit;
   border-bottom : inherit;
   border-radius : inherit;

   /* only show the bottom area of the pseudoelement */
   clip          : rect(35px 50px 50px 0);
}

Zasadniczo :afternałożyłem pseudoelement na pierwszy okrąg (z odziedziczonymi niektórymi właściwościami), a następnie przyciąłem go do clip()właściwości, więc pokazuję tylko jego dolną część (gdzie koło #1zachodzi na okrąg #5).

Do właściwości CSS użyłem tutaj przykład ten powinien pracować nawet w IE8 ( box-sizing, clip(), inherit, i są tam pseudoelements obsługiwane)


Zrzut ekranu z efektem

wprowadź opis obrazu tutaj

Fabrizio Calderan
źródło
2
Wygląda na to, że przyszedłem na imprezę za późno! Dobra robota! : P
Ruddy
2
Nie tylko nauczyłem się dzisiaj CSS, ale także trochę
poprawiłem
29

Moja próba również użycia clip. Chodziło o to, aby mieć pół na pół na div. W ten sposób ustawienie z-indexzadziała.

Możesz więc ustawić górną część na, z-index: -1a dolną na z-index: 1.

Wynik:

wprowadź opis obrazu tutaj

.item {
  width: 50px;
  height: 50px;
  line-height: 50px;
  border: 1px solid red;
  background: silver;
  border-radius: 50%;
  text-align: center;
}
.under {
  z-index: -1;
}
.above {
  z-index: 1;
  overflow: hidden;
  clip: rect(30px 50px 60px 0);
}
.i1 {
  position: absolute;
  top: 30px;
  left: 0px;
}
.i2 {
  position: absolute;
  top: 0px;
  left: 35px;
}
.i3 {
  position: absolute;
  top: 30px;
  left: 65px;
}
.i4 {
  position: absolute;
  top: 70px;
  left: 50px;
}
.i5 {
  position: absolute;
  top: 70px;
  left: 15px;
}
<div class="item i1 under">1</div>
<div class="item i1 above">1</div>
<div class="item i2">2</div>
<div class="item i3">3</div>
<div class="item i4">4</div>
<div class="item i5">5</div>

DEMO TUTAJ

Uwaga: testowano w IE 10+, FF 26+, Chrome 33+ i Safari 5.1.7+.

Rumiany
źródło
wszelkie pomysły dotyczące tego pytania: stackoverflow.com/questions/22377416/how-to-warp-image#22377416
NoobEditor
18

Oto moja propozycja.

Używam również pseudoelementu umieszczonego na górze pierwszego koła, ale zamiast używać klipu, zachowuję jego przezroczyste tło i po prostu nadaję mu cień pola, który pasuje do koloru tła kół (srebrny), a także czerwony obramowanie, aby zakryć prawe dolne boki obramowania koła.

Próbny

CSS (różni się od punktu początkowego)

.i1 { 
  position: absolute; top: 30px; left: 0px;
  &:before {
    content: '';
    position: absolute;
    z-index: 100;
    top: 0;
    left: 0;
    width: 50px;
    height: 50px;
    border-radius:  50%;
    box-shadow: inset 5px -5px 0 6px silver;
    border-bottom: solid 1px red;
  }
}

Produkt finalny wprowadź opis obrazu tutaj

DMTintner
źródło
Niezła odpowiedź! Jedynym problemem, o którym myślę, jest to, że cienie pól nie są obsługiwane przez IE 8 i starsze. Pseudoelementy i tak nie są obsługiwane przez IE 7 i starsze :)
The Pragmatick
4

Niestety, poniższa odpowiedź jest tylko teoretyczną odpowiedzią, ponieważ z jakiegoś powodu nie mogę zabrać się -webkit-transform-style: preserve-3d;do pracy (muszę popełnić jakiś oczywisty błąd, ale nie mogę tego rozgryźć). Tak czy inaczej, po przeczytaniu twojego pytania - jak z każdym paradoksem - zastanawiałem się, dlaczego to tylko pozorna niemożliwość, a nie rzeczywista. Po kolejnych kilku sekundach uświadamiam sobie, że w rzeczywistości liście są nieco obrócone, dzięki czemu coś takiego istnieje. Więc chciałem wymyślić prostą demonstrację tej techniki, ale bez poprzedniej właściwości jest to niemożliwe (zostaje przyciągnięta do płaskiej warstwy macierzystej). Tak czy inaczej, oto kod podstawowy

<div class="container">
    <div>
        <div class="i1 leaf">
            <div class="item">1</div>
        </div>
        <div class="i2 leaf">
            <div class="item">2</div>
        </div>
        <div class="i3 leaf">
            <div class="item">3</div>
        </div>
        <div class="i4 leaf">
            <div class="item">4</div>
        </div>
        <div class="i5 leaf">
            <div class="item">5</div>
        </div>
    </div>
</div>

A css:

.i1 {
    -webkit-transform:rotateZ(288deg)
}
.i2 {
    -webkit-transform:rotateZ(0deg)
}
.i3 {
    -webkit-transform:rotateZ(72deg)
}
.i4 {
    -webkit-transform:rotateZ(144deg)
}
.i5 {
    -webkit-transform:rotateZ(216deg)
}
.leaf { 
    position:absolute;
    left:35px;
    top:35px;
}
.leaf > .item {
    -webkit-transform:rotateY(30deg) translateY(35px)
}

Pełny kod możesz znaleźć tutaj .

David Mulder
źródło
Działa dla mnie w Safari 7.0.2; może to Twoja przeglądarka? - EDYCJA - mehehe, preserve-3d rzeczywiście nie działa. W każdym razie rozsądne 3D :)
tomsmeding
2

JS Fiddle

HTML

<div class="item i1">1</div>
<div class="item i2">2</div>
<div class="item i3">3</div>
<div class="item i4">4</div>
<div id="five">5</div>
<div class="item2 i5"></div>
<div class="item3 i6"></div>

CSS

.item {
    width: 50px;
    height: 50px;
    line-height: 50px;
    border: 1px solid red;
    background: silver;
    border-radius: 50%;
    text-align: center;
}
.item2 {
      width: 25px;
    height: 50px;
    line-height: 50px;
    border: 1px solid red;
    border-right: none;
    border-radius: 50px 0 0 50px;
    background: silver 50%;
    background-size: 25px;
    text-align: center;   
        z-index: -3;
}
.item3 {
    width: 25px;
    height: 50px;
    line-height: 50px;
    border: 1px solid red;
    border-left: none;
    border-radius: 0 50px 50px 0;
    background: silver 50%;
    background-size: 25px;
    text-align: center;    
}
.i1 {
    position: absolute;
    top: 30px;
    left: 0px;
}
.i2 {
    position: absolute;
    top: 0px;
    left: 35px;
}
.i3 {
    position: absolute;
    top: 30px;
    left: 65px;
}
.i4 {
    position: absolute;
    top: 70px;
    left: 55px;
}
.i5 {
    position: absolute;
    top: 70px;
    left: 15px;
}
.i5 {
    position: absolute;
    top: 72px;
    left:19px;

}
.i6 {
    position: absolute;
    top: 72px;
    left: 44px;
}
#five {
     position: absolute;
    top: 88px;
    left: 40px;
    z-index: 100;
}
Derek Story
źródło
Można było nieco skrócić kod, usuwając zbędne elementy w item2i item3. A także przeniósł position: absolutesię .ixi #fivena item, item2iitem3
webprogrammer
0

JS Fiddle LIVE DEMO

Działa również na IE8.

HTML

<div class="half under"><div class="item i1">1</div></div>
<div class="half above"><div class="item i1">1</div></div>
<div class="item i2">2</div>
<div class="item i3">3</div>
<div class="item i4">4</div> 
<div class="item i5">5</div>

CSS

.item {
    width: 50px;
    height: 50px;
    line-height: 50px;
    border: 1px solid red;
    background: silver;
    border-radius: 50%;
    text-align: center;
}
.half {
    position: absolute;
    overflow: hidden;
    width: 52px;
    height: 26px;
    line-height: 52px;
    text-align: center;
}
.half.under {
    top: 30px; 
    left: 0px;
    z-index: -1;
    border-radius: 90px 90px 0 0;
}
.half.above {
    top: 55px;
    left: 0px;
    z-index: 1;
    border-radius: 0 0 90px 90px;
}
.half.above .i1 { margin-top:-50%; }
.i2 { position: absolute; top: 0px; left: 35px;}
.i3 { position: absolute; top: 30px; left: 65px;}
.i4 { position: absolute; top: 70px; left: 50px; }
.i5 { position: absolute; top: 70px; left: 15px; }
Martin Urban
źródło