web-dev-qa-db-fra.com

Fleur paradoxe CSS z-index

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

Dans mon code, j'ai cinq cercles, comme dans l'image ci-dessous, et ils sont tous absolument positionnés sans _ 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 atteindre est d'avoir, en même temps, le cercle 1 sous le cercle 2 et en haut du cercle 5 (comme dans l'image de droite).


(source: schramek.cz )

Voici mon code

Annotation:

<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 les ordres d'empilement, le contexte d'empilement et ainsi de suite. J'ai lu quelques articles sur ces techniques, mais sans succès. Comment puis-je resoudre ceci?

98
1ubos

Voici ma tentative: http://jsfiddle.net/Kx2k5/1/
(testé avec succès sur Fx27, Ch33, IE9, Sf5.1.10 et 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 chevauché un pseudo-élément :after Sur le premier cercle (avec certaines propriétés héritées), puis je l'ai découpé avec la propriété clip(), donc je ne fais que rendre visible sa section inférieure (où le cercle #1 chevauche le cercle #5).

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


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

enter image description here

91
Fabrizio Calderan

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

Vous pouvez donc définir la partie supérieure sur z-index: -1 et le bas à z-index: 1.

Résultat:

enter image description here

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

29
Ruddy

Voici mon coup.

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

Démo

CSS (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 enter image description here

18
DMTintner

Malheureusement, ce qui suit n'est qu'une réponse théorique, car pour une raison quelconque, je ne peux pas obtenir -webkit-transform-style: preserve-3d; au travail (doit faire une erreur évidente, mais ne semble pas pouvoir le comprendre). Quoi qu'il en soit, après avoir lu votre question, je me suis demandé - comme pour tout paradoxe - pourquoi il ne s'agit que d'une impossibilité apparente, plutôt que 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 sur 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 .

4
David Mulder

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;
}
2
Derek Story

JS Fiddle LIVE DEMO

Fonctionne également 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; }
0
Martin Urban