Bunga paradoks indeks-z CSS

98

Saya ingin membuat efek paradoks melalui properti z-index CSS .

Dalam kode saya, saya memiliki lima lingkaran, seperti pada gambar di bawah, dan semuanya diposisikan secara mutlak tanpa ditentukan z-index. Oleh karena itu, secara default, setiap lingkaran tumpang tindih dengan yang sebelumnya.

Sekarang, lingkaran 5 tumpang tindih dengan lingkaran 1 (gambar kiri). Paradoks yang ingin saya capai adalah, pada saat yang sama, lingkaran 1 di bawah lingkaran 2 dan di atas lingkaran 5 (seperti pada gambar kanan).


(sumber: schramek.cz )

Ini kode saya

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

Contoh langsung juga tersedia di http://jsfiddle.net/Kx2k5/ .

Saya mencoba banyak teknik dengan perintah susun, konteks susun, dan sebagainya. Saya membaca beberapa artikel tentang teknik ini, tetapi tidak berhasil. Bagaimana saya bisa memecahkan masalah ini?

1ubos
sumber
10
Jika itu hanya tantangan pengkodean, mungkin ini milik codegolf?
TylerH
12
Saya pikir OP sedang mencari bantuan. Dia bermaksud untuk menjadi tantangan baginya untuk menyelesaikannya. Saya pikir ini adalah sesuatu yang akan dipelajari banyak orang setelah selesai. Saya sendiri dapat menemukan teknik ini berguna.
LOTUSMS
@ 1ub. Tidak ada jquery / JS sama sekali? Tampaknya bagi saya bahwa itu akan membutuhkan penggunaan logis dari IndexOf
LOTUSMS
5
ini tidak mungkin dengan menggunakan z-index. z-index mendefinisikan lapisan, ini adalah urutan bilangan bulat: -x, 0, x Anda tidak dapat memiliki: x1 <x2 <x1
gondo
4
Harap jangan mengelak filter kualitas dengan blok kode palsu. Sertakan kode dalam pertanyaan itu sendiri, atau hapus tautan biola jika tidak penting. Selain itu, saya akan menyarankan Anda untuk mengubah kalimat ini menjadi masalah nyata dengan penelitian daripada TANTANGAN jika Anda ingin pertanyaan Anda ditanggapi dengan serius.
BoltClock

Jawaban:

91

Berikut upaya saya: http://jsfiddle.net/Kx2k5/1/
(berhasil diuji pada Fx27, Ch33, IE9, Sf5.1.10dan 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);
}

Pada dasarnya saya telah tumpang tindih :afterpseudoelement di atas lingkaran pertama (dengan beberapa properti yang diwarisi), lalu saya telah memotongnya dengan clip()properti, jadi saya hanya membuat bagian bawahnya terlihat (di mana lingkaran #1tumpang tindih dengan lingkaran #5).

Untuk properti CSS yang saya gunakan di sini, contoh ini harus bekerja bahkan pada IE8 ( box-sizing, clip(), inherit, dan pseudoelements didukung di sana)


Tangkapan layar dari efek yang dihasilkan

masukkan deskripsi gambar di sini

Fabrizio Calderan
sumber
2
Sepertinya aku terlambat ke pesta! Kerja bagus! : P
Ruddy
2
Tidak hanya saya telah mempelajari beberapa CSS hari ini, tetapi juga sedikit
memoles bahasa
29

Upaya saya juga menggunakan clip. Idenya adalah memiliki setengah dan setengah untuk div. Setting seperti itu z-indexakan berhasil.

Jadi Anda bisa mengatur bagian atas ke z-index: -1dan bawah ke z-index: 1.

Hasil:

masukkan deskripsi gambar di sini

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

Catatan: Diuji di IE 10+, FF 26 +, Chrome 33+, dan Safari 5.1.7+.

Memerah
sumber
ada ide dengan pertanyaan ini: stackoverflow.com/questions/22377416/how-to-warp-image#22377416
NoobEditor
18

Inilah tujuan saya.

Saya juga menggunakan elemen semu yang diposisikan di atas lingkaran pertama, tetapi daripada menggunakan klip, saya menjaga latar belakangnya transparan dan hanya memberikannya sebuah kotak-bayangan sisipan yang cocok dengan warna latar belakang lingkaran (perak) serta merah perbatasan untuk menutupi sisi kanan bawah dari batas lingkaran.

Demo

CSS (yang berbeda dari titik awal)

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

Produk akhir masukkan deskripsi gambar di sini

DMTintner
sumber
Jawaban bagus! Satu-satunya masalah yang menurut saya adalah box-shadows tidak didukung oleh IE 8 dan di bawahnya. Pseudo-elemen tidak didukung oleh IE 7 dan di bawahnya :)
The Pragmatick
4

Sayangnya, berikut ini hanyalah jawaban teoritis, karena untuk beberapa alasan saya tidak bisa -webkit-transform-style: preserve-3d;bekerja (harus membuat kesalahan yang jelas, tetapi sepertinya tidak bisa memahaminya). Either way, setelah membaca pertanyaan Anda, saya - seperti halnya setiap paradoks - bertanya-tanya mengapa itu hanya kemustahilan yang tampak, daripada yang nyata. Beberapa detik lagi saya menyadari bahwa dalam kehidupan nyata daunnya diputar sedikit, sehingga memungkinkan hal seperti itu ada. Jadi saya ingin membuat demonstrasi sederhana dari teknik ini, tetapi tanpa properti sebelumnya itu tidak mungkin (itu akan ditarik ke lapisan induk datar). Bagaimanapun, berikut adalah kode dasarnya

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

Dan cssnya:

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

Dan Anda dapat menemukan kode lengkapnya di sini .

David Mulder
sumber
Bekerja untuk saya di Safari 7.0.2; mungkin itu browser Anda? - EDIT - mehehe, preservasi-3d memang tidak berfungsi. Bagaimanapun juga, 3D yang masuk akal :)
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;
}
Cerita Derek
sumber
Anda dapat mempersingkat kode Anda sedikit dengan menghapus hal-hal yang berlebihan di item2dan item3. Dan juga pindah position: absolutemasuk .ixdan #fivemasuk item, item2danitem3
webprogrammer
0

JS Fiddle DEMO LANGSUNG

Bekerja di IE8 juga.

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
sumber