Flor de la paradoja del índice z de CSS

98

Me gustaría crear un efecto paradójico a través de la propiedad z-index CSS .

En mi código tengo cinco círculos, como en la imagen de abajo, y todos están posicionados absolutamente sin definir z-index. Por lo tanto, por defecto, cada círculo se superpone al anterior.

En este momento, el círculo 5 se superpone al círculo 1 (imagen de la izquierda). La paradoja que me gustaría lograr es tener, al mismo tiempo, el círculo 1 debajo del círculo 2 y encima del círculo 5 (como en la imagen de la derecha).


(fuente: schramek.cz )

Aqui esta mi codigo

Margen:

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

También hay un ejemplo en vivo disponible en http://jsfiddle.net/Kx2k5/ .

Probé muchas técnicas con órdenes de apilamiento, contexto de apilamiento, etc. Leí algunos artículos sobre estas técnicas, pero no tuve éxito. ¿Como puedo resolver esto?

1ubos
fuente
10
Si es solo un desafío de codificación, ¿tal vez esto pertenezca a codegolf?
TylerH
12
Creo que el OP está buscando ayuda. Quiere decir que será un desafío para él resolverlo. Creo que esto es algo de lo que muchos aprenderán una vez hecho. Yo, por mi parte, puedo encontrar útil esta técnica.
LOTUSMS
@ 1ubos. ¿Sin jquery / JS en absoluto? Me parece que necesitará un uso lógico de IndexOf
LOTUSMS
5
esto no es posible usando z-index. z-index está definiendo capas, es una secuencia de números enteros: -x, 0, x no puede tener: x1 <x2 <x1
gondo
4
No eluda el filtro de calidad con un bloque de código falso. Incluya el código en la pregunta o elimine el enlace de violín si no es esencial. Además, le aconsejaría que reformule esto en un problema real con la investigación en lugar de un DESAFÍO si desea que su pregunta sea tomada en serio.
BoltClock

Respuestas:

91

Aquí está mi intento: http://jsfiddle.net/Kx2k5/1/
(probado con éxito en Fx27, Ch33, IE9, Sf5.1.10y 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);
}

Básicamente, superpuse un :afterpseudoelemento sobre el primer círculo (con algunas propiedades heredadas), luego lo recorté con clip()propiedad, por lo que solo hago visible su sección inferior (donde el círculo se #1superpone al círculo #5).

Para las propiedades CSS que he usado aquí, este ejemplo debería estar trabajando incluso en IE8 ( box-sizing, clip(), inherit, y son compatibles pseudoelements allí)


Captura de pantalla del efecto resultante

ingrese la descripción de la imagen aquí

Fabrizio Calderan
fuente
2
¡Parece que llegué demasiado tarde a la fiesta! ¡Buen trabajo! : P
Ruddy
2
No solo aprendí algo de CSS hoy, sino que también
repasé
29

Mi intento también usando clip. La idea era tener mitad y mitad para el div. De esa manera, la configuración z-indexfuncionaría.

De modo que puede establecer la parte superior en z-index: -1y la inferior en z-index: 1.

Salir:

ingrese la descripción de la imagen aquí

.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 AQUÍ

Nota: Probado en IE 10+, FF 26 +, Chrome 33+ y Safari 5.1.7+.

Rubicundo
fuente
cualquier idea con esta pregunta: stackoverflow.com/questions/22377416/how-to-warp-image#22377416
NoobEditor
18

Aquí está mi camino.

También utilizo un pseudo elemento colocado en la parte superior del primer círculo, pero en lugar de usar un clip, mantengo su fondo transparente y solo le doy una sombra de cuadro insertada que coincide con el color de fondo de los círculos (plateado) así como con un rojo borde para cubrir los lados inferiores derechos del borde del círculo.

Manifestación

CSS (que es diferente del punto 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;
  }
}

Producto final ingrese la descripción de la imagen aquí

DMTintner
fuente
¡Buena respuesta! El único problema que puedo pensar es que las sombras de caja no son compatibles con IE 8 y versiones anteriores. Los pseudoelementos no son compatibles con IE 7 y versiones anteriores de todos modos :)
The Pragmatick
4

Lamentablemente, la siguiente es solo una respuesta teórica, ya que por alguna razón no puedo ponerme -webkit-transform-style: preserve-3d;a trabajar (tengo que estar cometiendo un error obvio, pero parece que no puedo resolverlo). De cualquier manera, después de leer su pregunta, al igual que con todas las paradojas, me pregunté por qué es solo una imposibilidad aparente, en lugar de una real. En unos segundos me doy cuenta de que en la vida real las hojas se giran un poco, permitiendo así que exista tal cosa. Entonces quería inventar una demostración simple de la técnica, pero sin la propiedad anterior eso es imposible (se dibuja en la capa principal plana). De cualquier manera, aquí está el código base.

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

Y el 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)
}

Y puedes encontrar el código completo aquí .

David Mulder
fuente
Me funciona en Safari 7.0.2; tal vez sea tu navegador? - EDITAR - jejeje, el preserve-3d de hecho no funciona. 3D razonable de todos modos, sin embargo :)
tomsmeding
2

JS violín

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
fuente
Podría haber acortado un poco su código eliminando elementos redundantes en item2y item3. Y también moví el position: absolutein .ixy #fiveen item, item2yitem3
webprogrammer
0

Demostración en vivo de JS Fiddle

También funciona en 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; }
Martín Urbano
fuente