Flor de paradoxo do Z-index CSS

98

Eu gostaria de criar um efeito paradoxal por meio da propriedade z-index CSS .

No meu código tenho cinco círculos, como na imagem abaixo, e todos eles estão absolutamente posicionados sem nenhum definido z-index. Portanto, por padrão, cada círculo se sobrepõe ao anterior.

No momento, o círculo 5 se sobrepõe ao círculo 1 (imagem à esquerda). O paradoxo que gostaria de alcançar é ter, ao mesmo tempo, o círculo 1 abaixo do círculo 2 e no topo do círculo 5 (como na imagem à direita).


(fonte: schramek.cz )

Aqui está o meu código

Markup:

<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; }

Um exemplo ao vivo também está disponível em http://jsfiddle.net/Kx2k5/ .

Eu tentei várias técnicas com empilhamento de ordens, empilhamento de contexto e assim por diante. Li alguns artigos sobre essas técnicas, mas sem sucesso. Como posso resolver isso?

1ubos
fonte
10
Se for apenas um desafio de codificação, talvez isso pertença ao codegolf?
TylerH
12
Acho que o OP está procurando ajuda. Ele pretende que seja um desafio resolvê-lo. Eu acho que isso é algo que muitos aprenderão depois de feito. Eu, pelo menos, posso achar essa técnica útil.
LOTUSMS
@ 1ubos. Sem jquery / JS algum? Parece-me que será necessário algum uso lógico do IndexOf
LOTUSMS
5
isso não é possível usando o z-index. Z-index está definindo camadas, é uma sequência de números inteiros: -x, 0, x você não pode ter: x1 <x2 <x1
gondo
4
Por favor, não contorne o filtro de qualidade com um bloco de código falso. Inclua o código na própria pergunta ou remova o link do violino se não for essencial. Além disso, eu o aconselharia a reformular isso como um problema real de pesquisa, em vez de um DESAFIO, se quiser que sua pergunta seja levada a sério.
BoltClock

Respostas:

91

Aqui está a minha tentativa: http://jsfiddle.net/Kx2k5/1/
(testado com sucesso em Fx27, Ch33, IE9, Sf5.1.10e 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);
}

Basicamente, sobrepus um :afterpseudoelemento sobre o primeiro círculo (com algumas propriedades herdadas) e, em seguida, o recortei com a clip()propriedade, portanto, tornei apenas visível a seção inferior (onde o círculo se #1sobrepõe ao círculo #5).

Para as propriedades CSS que usei aqui, este exemplo deve ser trabalhar até mesmo em IE8 ( box-sizing, clip(), inherit, e pseudoelements são suportados lá)


Captura de tela do efeito resultante

insira a descrição da imagem aqui

Fabrizio Calderan
fonte
2
Parece que cheguei tarde na festa! Bom trabalho! : P
Ruddy
2
Não só aprendi CSS hoje, mas também melhorei um pouco meu italiano: D obrigado
Natan Streppel
29

Minha tentativa também usando clip. A ideia era ter meio a meio para o div. Dessa forma, a configuração z-indexfuncionaria.

Portanto, você pode definir a parte superior como z-index: -1e a parte inferior como z-index: 1.

Resultado:

insira a descrição da imagem aqui

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

Nota: Testado em IE 10+, FF 26 +, Chrome 33+ e Safari 5.1.7+.

Ruddy
fonte
alguma ideia com esta pergunta: stackoverflow.com/questions/22377416/how-to-warp-image#22377416
NoobEditor
18

Aqui está minha chance.

Eu também uso um pseudo elemento posicionado no topo do primeiro círculo, mas em vez de usar o clipe, mantenho o fundo transparente e apenas atribuo a ele uma sombra de caixa que corresponde à cor de fundo dos círculos (prata) e também vermelho borda para cobrir os lados inferiores direitos da borda do círculo.

Demo

CSS (que é diferente do ponto de partida)

.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;
  }
}

Produto final insira a descrição da imagem aqui

DMTintner
fonte
Boa resposta! O único problema que posso pensar é que as sombras das caixas não são suportadas pelo IE 8 e versões anteriores. Pseudo-elementos não são suportados pelo IE 7 e abaixo de qualquer maneira :)
The Pragmatick
4

Infelizmente, o que se segue é apenas uma resposta teórica, já que por algum motivo não consigo -webkit-transform-style: preserve-3d;trabalhar ( devo estar cometendo algum erro óbvio, mas não consigo descobrir). De qualquer forma, depois de ler sua pergunta, eu - como acontece com todo paradoxo - me perguntei por que é apenas uma impossibilidade aparente, ao invés de real. Depois de alguns segundos eu percebi que na vida real as folhas são giradas um pouco, permitindo que tal coisa exista. Então, eu queria inventar uma demonstração simples da técnica, mas sem a propriedade anterior isso é impossível (ela é desenhada para a camada pai plana). De qualquer forma, aqui está o código base, no entanto

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

E o 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)
}

E você pode encontrar o código completo aqui .

David Mulder
fonte
Funciona para mim no Safari 7.0.2; talvez seja o seu navegador? - EDIT - mehehe, o preserve-3d realmente não está funcionando. 3D razoável de qualquer maneira :)
tomsmeding em
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
fonte
Você poderia ter encurtado seu código um pouco removendo coisas redundantes em item2e item3. E também mudou o position: absolutein .ixe #fivepara item, item2eitem3
webprogrammer
0

JS Fiddle LIVE DEMO

Funciona no IE8 também.

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
fonte