Fleur de paradoxe CSS z-index

98

Je voudrais créer un effet paradoxal via la propriété z-index CSS .

Dans mon code, j'ai cinq cercles, comme dans l'image ci-dessous, et ils sont tous positionnés de manière absolue sans définition z-index. Par conséquent, par défaut, chaque cercle chevauche le précédent.

À l'heure actuelle, le cercle 5 chevauche le cercle 1 (image de gauche). Le paradoxe que j'aimerais réaliser est d'avoir, en même temps, le cercle 1 sous le cercle 2 et au-dessus du cercle 5 (comme sur l'image de droite).


(source: schramek.cz )

Voici mon code

Balisage:

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

Un exemple en direct est également disponible sur http://jsfiddle.net/Kx2k5/ .

J'ai essayé beaucoup de techniques avec l'empilement des commandes, l'empilement du contexte, etc. J'ai lu quelques articles sur ces techniques, mais sans succès. Comment puis-je resoudre ceci?

1ubos
la source
10
Si c'est juste un défi de codage, peut-être que cela appartient à codegolf?
TylerH
12
Je pense que l'OP cherche de l'aide. Il veut que ce soit un défi pour lui de le résoudre. Je pense que c'est quelque chose dont beaucoup apprendront une fois terminé. Pour ma part, je peux trouver cette technique utile.
LOTUSMS
@ 1ubos. Pas de jquery / JS que ce soit? Il me semble qu'il faudra une utilisation logique d'IndexOf
LOTUSMS
5
ce n'est pas possible en utilisant z-index. z-index définit des couches, c'est une séquence de nombres entiers: -x, 0, x vous ne pouvez pas avoir: x1 <x2 <x1
gondo
4
Veuillez ne pas contourner le filtre de qualité avec un faux bloc de code. Soit inclure le code dans la question elle-même, soit supprimer le lien violon s'il n'est pas essentiel. De plus, je vous conseillerais de reformuler cela en un problème réel de recherche plutôt qu'un DÉFI si vous voulez que votre question soit prise au sérieux.
BoltClock

Réponses:

91

Voici ma tentative: http://jsfiddle.net/Kx2k5/1/
(testé avec succès sur Fx27, Ch33, IE9, Sf5.1.10et 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);
}

Fondamentalement, j'ai superposé un :afterpseudo-élément sur le premier cercle (avec certaines propriétés héritées), puis je l'ai découpé avec une clip()propriété, donc je ne fais que sa section inférieure visible (où le cercle #1chevauche le cercle #5).

Pour les propriétés CSS que j'ai utilisé ici, cet exemple devrait fonctionner même sur IE8 ( box-sizing, clip(), inheritet pseudoelements y sont pris en charge)


Capture d'écran de l'effet résultant

entrez la description de l'image ici

Fabrizio Calderan
la source
2
On dirait que je suis arrivé à la fête trop tard! Bon travail! : P
Ruddy
2
Non seulement j'ai appris un peu de CSS aujourd'hui, mais j'ai aussi brossé un peu mon italien: D merci
Natan Streppel
29

Ma tentative utilise également clip. L'idée était d'en avoir la moitié et la moitié pour le div. De cette façon, le réglage z-indexfonctionnerait.

Ainsi, vous pouvez définir la partie supérieure sur z-index: -1et la partie inférieure sur z-index: 1.

Résultat:

entrez la description de l'image ici

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

DÉMO ICI

Remarque: testé sur IE 10+, FF 26+, Chrome 33+ et Safari 5.1.7+.

Rouge
la source
des idées avec cette question: stackoverflow.com/questions/22377416/how-to-warp-image#22377416
NoobEditor
18

Voici mon essai.

J'utilise également un pseudo élément positionné au-dessus du premier cercle, mais plutôt que d'utiliser le clip, je garde son arrière-plan transparent et je lui donne juste une ombre-boîte en médaillon qui correspond à la couleur de fond des cercles (argent) ainsi qu'un rouge bordure pour couvrir les côtés inférieurs droit de la bordure du cercle.

Démo

CSS (qui est différent du point de départ)

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

Produit final entrez la description de l'image ici

DMTintner
la source
Bonne réponse! Le seul problème que je peux penser est que les ombres de boîte ne sont pas prises en charge par IE 8 et les versions antérieures. Les pseudo-éléments ne sont de toute façon pas pris en charge par IE 7 et les versions inférieures :)
The Pragmatick
4

Malheureusement, ce qui suit n'est qu'une réponse théorique, car pour une raison quelconque, je ne peux pas me rendre -webkit-transform-style: preserve-3d;au travail (je dois faire une erreur évidente, mais je n'arrive pas à la comprendre). Quoi qu'il en soit, après avoir lu votre question, je me suis demandé - comme pour tout paradoxe - pourquoi ce n'est qu'une impossibilité apparente, plutôt qu'une réelle. Encore quelques secondes, je me rends compte que dans la vraie vie, les feuilles tournent un peu, permettant ainsi à une telle chose d'exister. Alors j'ai voulu concocter une simple démonstration de la technique, mais sans la propriété précédente c'est impossible (elle est attirée vers le calque parent plat). Quoi qu'il en soit, voici le code de base néanmoins

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

Et le 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)
}

Et vous pouvez trouver le code complet ici .

David Mulder
la source
Fonctionne pour moi dans Safari 7.0.2; c'est peut-être votre navigateur? - EDIT - mehehe, le Preserve-3d ne fonctionne en effet pas. De toute façon en 3D raisonnable :)
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;
}
Histoire de Derek
la source
Vous auriez pu raccourcir un peu votre code en supprimant les éléments redondants dans item2et item3. Et aussi déplacé le position: absolutein .ixet #fiveinto item, item2etitem3
webprogrammer
0

DÉMO EN DIRECT DE JS Fiddle

Fonctionne aussi sur 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 Urbain
la source