Daftar avatar responsif menggunakan CSS modern (Bagian 2)

 – Beragampengetahuan
12 mins read

Daftar avatar responsif menggunakan CSS modern (Bagian 2) – Beragampengetahuan

Apakah Anda siap untuk bagian kedua? Jika Anda ingat, terakhir kali kami membuat daftar responsif gambar avatar yang tumpang tindih yang menampilkan potongan di antara gambar tersebut.

Dua baris gambar avatar melingkar. Gambar-gambar ini saling tumpang tindih. Baris pertama memiliki delapan gambar; baris kedua memiliki enam gambar.

Kami masih membuat daftar avatar responsif, namun kali ini akan menjadi daftar melingkar.

Menampilkan contoh dua gambar avatar berbentuk lingkaran yang disusun membentuk lingkaran. Contoh pertama memiliki delapan gambar. Contoh kedua memiliki enam gambar.

Desain ini kurang umum dibandingkan daftar horizontal, namun tetap merupakan latihan yang bagus untuk mengeksplorasi teknik CSS baru.

Mari kita mulai dengan demo. Anda dapat mengubah ukurannya dan melihat bagaimana gambar berperilaku, dan Anda dapat mengarahkannya untuk mendapatkan efek tampilan yang keren.

Demo di bawah ini saat ini terbatas pada Chrome dan Edge, tetapi juga dapat digunakan di browser lain sibling-index() Dan sibling-count() Fitur mendapatkan dukungan yang lebih luas. Anda dapat melacak dukungan Firefox di Tiket #1953973 dan penempatan WebKit di Edisi #471.

Kita akan mengandalkan struktur HTML dan dasar-dasar CSS yang sama seperti contoh yang disajikan di Bagian 1: Daftar gambar dalam sebuah wadah mask– pemotongan kertas. Namun kali ini pendiriannya akan berbeda.

Contents

Daftar avatar responsif menggunakan CSS modern

  1. daftar horisontal
  2. daftar siklus (Anda di sini!)

Tempatkan gambar di sekitar lingkaran

Ada beberapa teknik untuk menempatkan gambar di sekitar lingkaran. Saya akan mulai dengan salah satu favorit saya, yang kurang dikenal tetapi menggunakan kode sederhana yang mengandalkan CSS offset milik.

.container {
  display: grid;
}
.container img {
  grid-area: 1/1;
  offset: circle(180px) calc(100%*sibling-index()/sibling-count()) 0deg;
}

Kodenya tidak terlihat intuitif, tetapi logikanya cukup sederhana. ini offset property adalah sebuah singkatan, jadi mari kita tuliskan dengan cara biasa untuk melihat bagaimana rinciannya:

offset-path: circle(180px);
offset-distance: calc(100%*sibling-index()/sibling-count());
offset-rotate: 0deg;

Kami mendefinisikan jalur sebagai lingkaran dengan jari-jari 180px. Semua gambar akan “mengikuti” jalur ini, tetapi awalnya akan saling tumpang tindih. Kita perlu menyesuaikan jaraknya untuk mengubah posisinya di sepanjang jalur (yaitu lingkaran). itu di sana offset-distance ikut bermain, kami menggabungkannya dengan sibling-index() Dan sibling-count() berfungsi untuk membuat kode yang berfungsi untuk sejumlah elemen berapa pun, daripada menggunakan angka pasti.

Untuk enam elemen nilainya adalah sebagai berikut:

100% x 1/6 = 16.67%
100% x 2/6 = 33.33%
100% x 3/6 = 50%
100% x 4/6 = 66,67%
100% x 5/6 = 83.33%
100% x 6/6 = 100%

Ini akan menempatkan elemen secara merata di sekeliling lingkaran. Untuk melakukan ini, kami menambahkan sama dengan 0deg menggunakan offset-rotate Jaga agar elemen tetap lurus sehingga tidak berputar saat mengikuti jalur melingkar. Dari situ kita tinggal memperbarui jari-jari lingkaran dengan nilai yang kita inginkan.

Ini adalah metode pilihan saya, tetapi ada metode kedua yang digunakan transform Properti yang menggabungkan dua rotasi dan terjemahan:

.container {
  display: grid;
}
.container img {
  grid-area: 1/1;
  --_i: calc(1turn*sibling-index()/sibling-count());
  transform: rotate(calc(-1*var(--_i))) translate(180px) rotate(var(--_i));
}

Terjemahan berisi nilai jari-jari lingkaran, tergantung rotasinya sibling-* Fungsionalitasnya sama dengan milik kita offset-distance.

Meskipun saya lebih suka metode pertama, saya akan mengandalkan metode kedua karena memungkinkan saya menggunakan kembali sudut rotasi di lebih banyak tempat.

bagian respons

Mirip dengan daftar responsif horizontal di artikel sebelumnya, saya akan mengandalkan sel kueri kontainer untuk menentukan radius lingkaran dan membuat komponen responsif.

Diagram delapan gambar avatar melingkar yang disusun mengelilingi lingkaran. Garis putus-putus berwarna merah menunjukkan ukuran dan jari-jari lingkaran besar.
.container {
  --s: 120px; /* image size */

  aspect-ratio: 1;
  container-type: inline-size;
}
.container img {
  width: var(--s);
  --_r: calc(50cqw - var(--s)/2);
  --_i: calc(1turn*sibling-index()/sibling-count());
  transform: rotate(calc(-1*var(--_i))) translate(var(--_r)) rotate(var(--_i));
}

Ubah ukuran penampung dalam demo di bawah dan lihat bagaimana perilaku gambar:

Ini responsif, tetapi ketika wadahnya semakin besar, gambarnya menjadi terlalu menyebar, dan saya tidak suka. Jaga agar mereka sedekat mungkin. Dengan kata lain, kami menganggap lingkaran terkecil yang berisi semua gambar tanpa tumpang tindih.

Ingat apa yang kami lakukan di bagian pertama: kami menambahkan margin maksimal ke margin untuk alasan serupa. Kami akan melakukan hal yang sama di sini:

--_r: min(50cqw - var(--s)/2, R);

Saya tahu Anda tidak ingin mengambil kelas geometri yang membosankan, jadi saya akan melewatkannya dan memberi Anda nilainya R:

S/(2 x sin(.5turn/N))

Ditulis dalam CSS:

--_r: min(50cqw - var(--s)/2,var(--s)/(2*sin(.5turn/sibling-count())));

Sekarang ketika Anda memperbesar wadahnya, gambar-gambarnya akan tetap berdekatan satu sama lain, dan ini sempurna:

Mari kita perkenalkan variabel lain untuk merepresentasikan jarak antar gambar (--g) dan perbarui rumusnya sedikit untuk menjaga jarak kecil antar gambar.

.container {
  --s: 120px; /* image size */
  --g: 10px;  /* the gap */

  aspect-ratio: 1;
  container-type: inline-size;
}
.container img {
  width: var(--s);
  --_r: min(50cqw - var(--s)/2,(var(--s) + var(--g))/(2*sin(.5turn/sibling-count())));
  --_i: calc(1turn*sibling-index()/sibling-count());
  transform: rotate(calc(-1*var(--_i))) translate(var(--_r)) rotate(var(--_i));
}

efek pemangkasan

Untuk bagian ini, kita akan menggunakan masker yang sama yang kita gunakan pada artikel sebelumnya:

mask: radial-gradient(50% 50% at X Y, #0000 calc(100% + var(--g)), #000);

Untuk daftar horizontal, nilainya X Dan Y Sangat sederhana. kita tidak perlu mendefinisikannya Y karena nilai defaultnya berfungsi, dan X nilai adalah 150% + M atau -50% - MDan M Apakah margin yang mengontrol tumpang tindih. Lihatlah dari sudut lain, X Dan Y adalah koordinat titik tengah gambar berikutnya atau sebelumnya dalam daftar.

Hal ini masih terjadi saat ini, namun penghitungan nilainya lebih rumit:

Diagram delapan gambar avatar melingkar yang disusun mengelilingi lingkaran. Kedua ruas garis tersebut masing-masing ditandai sebagai ruas garis merah A dan ruas garis hijau B. Segmen pertama menunjuk ke gambar saat ini yang diwakili oleh i. Segmen kedua menunjuk ke gambar berikutnya yang diwakili oleh i ditambah 1.

Idenya adalah memulai dari tengah gambar saat ini (50% 50%) dan pindah ke tengah gambar berikutnya (X Dan Y). Saya pertama-tama akan mengikuti segmen A ke tengah lingkaran besar, lalu segmen B ke tengah gambar berikutnya.

Berikut rumusnya:

X = 50% - Ax + Bx
Y = 50% - Ay + By

Ax Dan Ay adalah proyeksi ruas garis A pada sumbu X dan sumbu Y. Kita bisa menggunakan fungsi trigonometri untuk mendapatkan nilainya.

Ax = r x sin(i);
Ay = r x cos(i);

ini r Mewakili jari-jari lingkaran yang ditentukan oleh variabel CSS --_rDan i Mewakili sudut rotasi yang ditentukan oleh variabel CSS --_i.

Logika yang sama seperti bagian B:

Bx = r x sin(j);
By = r x cos(j);

ini j Mirip dengan itapi untuk Berikutnya gambar dalam urutan, ini berarti kita meningkatkan indeks sebesar 1. Ini memberi kita perhitungan CSS berikut untuk setiap variabel:

--_i: calc(1turn*sibling-index()/sibling-count());
--_j: calc(1turn*(sibling-index() + 1)/sibling-count());

Dan kode terakhir dengan mask:

.container {
  --s: 120px; /* image size */
  --g: 14px;  /* the gap */

  aspect-ratio: 1;
  container-type: inline-size;
}
.container img {
  width: var(--s);
  --_r: min(50cqw - var(--s)/2,(var(--s) + var(--g))/(2*sin(.5turn/sibling-count())));
  --_i: calc(1turn*sibling-index()/sibling-count());
  --_j: calc(1turn*(sibling-index() + 1)/sibling-count());
  transform: rotate(calc(-1*var(--_i))) translate(var(--_r)) rotate(var(--_i));
  mask: radial-gradient(50% 50% at
    calc(50% + var(--_r)*(cos(var(--_j)) - cos(var(--_i))))
    calc(50% + var(--_r)*(sin(var(--_i)) - sin(var(--_j)))),
      #0000 calc(100% + var(--g)), #000);
}

Keren, bukan? Anda mungkin melihat dua implementasi kliping yang berbeda. Rumus yang saya gunakan sebelumnya memperhitungkan gambar berikutnya, tetapi jika kita pertimbangkan sebelumnya Gambarnya terbalik, dengan potongan menghadap ke arah lain. Jadi, alih-alih menambah indeks, kami menguranginya dan menetapkannya .reverse Kelas ini dapat digunakan ketika kita ingin potongannya bergerak ke arah yang berlawanan:

.container img {
  --_j: calc(1turn*(sibling-index() + 1)/sibling-count());
}
.container.reverse img {
  --_j: calc(1turn*(sibling-index() - 1)/sibling-count());
}

bagian animasi

Mirip dengan apa yang kita lakukan di artikel sebelumnya, tujuan animasi ini adalah menghilangkan tumpang tindih saat gambar diarahkan agar gambar terlihat sepenuhnya. Dalam daftar horizontal, kita cukup mengaturnya margin properti ke 0kami menyesuaikan margin gambar lain untuk mencegah luapan.

Kali ini logikanya berbeda. Kami akan memutar semua gambar kecuali gambar hover hingga gambar hover terlihat sepenuhnya. Tentu saja arah putarannya akan tergantung pada arah pemotongannya.

Delapan gambar avatar disusun dalam lingkaran. Panah menunjuk ke hal yang sama, menunjukkan apa yang terjadi ketika Anda mengarahkan kursor ke avatar di bagian atas lingkaran.

Untuk memutar gambar kita perlu memperbarui --_i Variabel digunakan sebagai argumen pada fungsi rotasi. Mari kita mulai dengan nilai rotasi arbitrer, misalnya 20deg.

.container img {
  --_i: calc(1turn*sibling-index()/sibling-count());
}
.container:has(:hover) img {
  --_i: calc(1turn*sibling-index()/sibling-count() + 20deg);
}
.container.reverse:has(:hover) img {
  --_i: calc(1turn*sibling-index()/sibling-count() - 20deg);
}

Semua gambar sekarang diputar ketika diarahkan 20deg. Cobalah di demo di bawah ini.

Ya, gambarnya memang berputar, tetapi topengnya tidak mengikuti perputarannya. Jangan lupa bahwa topeng memperhitungkan posisi yang ditentukan oleh gambar berikutnya atau sebelumnya --_j dan gambar berikutnya/sebelumnya berputar – jadi kita juga perlu memperbarui --_j Variabel saat hover terjadi.

.container img {
  --_i: calc(1turn*sibling-index()/sibling-count());
  --_j: calc(1turn*(sibling-index() + 1)/sibling-count());
}
.container.reverse img {
  --_j: calc(1turn*(sibling-index() - 1)/sibling-count());
}
.container:has(:hover) img {
  --_i: calc(1turn*sibling-index()/sibling-count() + 20deg);
  --_j: calc(1turn*(sibling-index() + 1)/sibling-count() + 20deg);
}
.container.reverse:has(:hover) img {
  --_i: calc(1turn*sibling-index()/sibling-count() - 20deg);
  --_j: calc(1turn*(sibling-index() - 1)/sibling-count() - 20deg);
}

Itu banyak kode yang berlebihan. Mari kita optimalkan sedikit dengan mendefinisikan variabel tambahan:

.container img {
  --_a: 20deg;

  --_i: calc(1turn*sibling-index()/sibling-count() + var(--_ii, 0deg));
  --_j: calc(1turn*(sibling-index() + 1)/sibling-count() + var(--_jj, 0deg));
}
.container.reverse img {
  --_i: calc(1turn*sibling-index()/sibling-count() - var(--_ii, 0deg));
  --_j: calc(1turn*(sibling-index() - 1)/sibling-count() - var(--_jj, 0deg));
}
.container:has(:hover) img {
  --_ii: var(--_a);
  --_jj: var(--_a);
}

sudut saat ini (--_a) didefinisikan di satu tempat, saya mempertimbangkan dua variabel perantara untuk menambahkan offset --_i Dan --_j variabel.

Sekarang rotasi semua gambar sudah sempurna. Mari kita nonaktifkan rotasi gambar hover:

.container img:hover {
  --_ii: 0deg;
  --_jj: 0deg;
}

Ups, topengnya lepas lagi! Apakah Anda melihat pertanyaan ini?

Kami ingin mencegah gambar yang melayang berputar sambil membiarkan gambar lainnya berputar. Karena itu, --_j Variabel untuk gambar hover perlu diperbarui karena terkait dengan gambar berikutnya atau sebelumnya. Jadi kita harus menghapusnya --_jj: 0deg dan simpan saja --_ii: 0deg.

.container img:hover {
  --_ii: 0deg;
}

Ini lebih baik. Kami memperbaiki efek kliping pada gambar hover, namun efek keseluruhan masih belum sempurna. Jangan lupa bahwa gambar yang dilayangkan adalah gambar berikutnya atau sebelumnya dari gambar lain, dan karena tidak berputar, gambar lainnya --_j Variabel harus tetap tidak berubah.

Untuk daftar pertama, variabel dari gambar sebelumnya tidak boleh diubah. Untuk daftar kedua, ini adalah variabel untuk gambar berikutnya:

/* select previous element of hovered */
.container:not(.reverse) img:has(+ :hover),
/* select next element of hovered */
.container.reverse img:hover + * {
  --_jj: 0deg;
}

Jika Anda bertanya-tanya bagaimana saya tahu melakukan ini, saya mencoba kedua metode dan memilih salah satu yang berhasil. Entah kode di atas, atau ini:

.container:not(.reverse) img:hover + *,
.container.reverse img:has(+ :hover) {
  --_jj: 0deg;
}

Kami semakin dekat! Semua gambar kecuali satu di setiap daftar berperilaku normal. Coba arahkan semuanya untuk menemukan pelakunya.

Bisakah Anda mencari tahu apa yang kami lewatkan? Pikirkan tentang hal ini.

Daftar kami berbentuk lingkaran, tetapi kode HTMLnya tidak, jadi meskipun gambar pertama dan terakhir secara visual ditempatkan bersebelahan, namun di dalam kodenya tidak. Kami tidak dapat menghubungkannya menggunakan pemilih saudara yang berdekatan (+). Kita juga memerlukan dua penyeleksi untuk menangani kasus tepi berikut:

.container.reverse:has(:last-child:hover) img:first-child,
.container:not(.reverse):has(:first-child:hover) img:last-child {
  --_jj: 0deg;
}

koin! Kami telah mengatasi semua masalah dan sekarang kami memiliki efek hover yang bagus, namun masih belum sempurna. Sekarang, kita harus akurat dan tidak menggunakan nilai sembarangan untuk rotasi. Kita harus menemukan nilai minimum yang menghilangkan tumpang tindih sambil menjaga gambar sedekat mungkin.

Menunjukkan jarak antara dua gambar pada tiga titik berbeda. Poin pertama dan ketiga masing-masing terlalu dekat dan terlalu jauh. Titik tengahnya sempurna dengan banyak ruang di antara gambar.

Kita bisa mendapatkan nilai ini melalui beberapa fungsi trigonometri. Saya akan melewatkan pelajaran geometri lagi (kita sudah cukup pusing!) dan memberi Anda nilainya:

--_a: calc(2*asin((var(--s) + var(--g))/(2*var(--_r))) - 1turn/sibling-count());

Sekarang kita dapat mengatakan semuanya sempurna!

sebagai kesimpulan

Ini agak sulit, bukan? Jika Anda sedikit bingung dengan semua rumus rumitnya, jangan khawatir. Mereka sangat spesifik untuk contoh ini, jadi tidak masalah jika Anda melupakannya. Tujuannya adalah untuk mengeksplorasi beberapa fitur modern dan beberapa trik CSS sejenisnya offset, mask, sibling-* fungsi, unit kueri kontainer, min()/max()dan banyak lagi!

Daftar avatar responsif menggunakan CSS modern

  1. daftar horisontal
  2. daftar siklus (Anda di sini!)

rencana pengembangan website



metode pengembangan website

jelaskan beberapa rencana untuk pengembangan website, proses pengembangan website, kekuatan dan kelemahan bisnis pengembangan website
, jasa pengembangan website, tahap pengembangan website, biaya pengembangan website

#Daftar #avatar #responsif #menggunakan #CSS #modern #Bagian

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *