Membuat tata letak batu yang efektif hari ini – Beragampengetahuan
Tahun lalu, banyak ahli CSS memiliki dampak besar pada kemungkinan sintaksis fitur tata letak batu yang baru. Ada dua kamp utama dan kamp ketiga untuk menyeimbangkan keduanya:
- menggunakan
display: masonry - menggunakan
grid-template-rows: masonry - menggunakan
item-pack: collapse
Saya pikir mereka belum membuat resolusi. Tetapi Anda mungkin bertanya -tanya bahwa Firefox sudah mendukung tata letak batu menggunakan sintaks kedua. Chrome mengujinya dengan sintaksis pertama. Meskipun keren melihat dukungan asli yang berkembang untuk CSS Masonry, kami tidak akan dapat benar -benar menggunakannya dalam produksi jika browser lain tidak mendukung implementasi yang sama …
Jadi alih -alih menambahkan suara saya ke salah satu kamp, saya terus mencari tahu Bagaimana bekerja dengan browser lain hari ini. Saya senang melaporkan bahwa saya menemukan jalan – dan, hadiah! – Dukungan dapat disediakan Hanya 66 baris javascript.
Dalam artikel ini, saya akan menunjukkan cara kerjanya. Tapi pertama -tama, ini adalah demo yang bisa Anda mainkan, hanya untuk membuktikan bahwa saya bukan omong kosong. Perhatikan bahwa karena kita menunggu gambar memuat terlebih dahulu, akan ada beberapa penundaan. Jika Anda menempatkan batu di atas, pertimbangkan untuk melewatkan termasuk gambar!
Ngomong -ngomong, inilah demo:
Contents
Sihir macam apa ini?
Sekarang, ada Satu ton Bahkan jika hanya ada 66 baris JavaScript, saya memasukkan demo ini:
- Anda dapat mendefinisikan batu menggunakan sejumlah kolom.
- Setiap item dapat menjangkau beberapa kolom.
- Kami menunggu media memuat sebelum kami dapat menghitung ukuran setiap item.
- Kami mendengarkan
ResizeObserver.
Ini membuat implementasi saya sangat kuat, siap untuk digunakan produksi, dan juga lebih fleksibel daripada banyak pemalsuan batu flexbox di internet.
Sekarang, tip panas. Jika dikombinasikan dengan varian responsif dari nilai tailwind dan sewenang -wenang, itu dapat dimasukkan dengan lebih banyak fleksibilitas dalam mesh batu ini tanpa menulis lebih banyak CSS.
Oke, sebelum Anda hype lebih lanjut, mari kita kembali ke pertanyaan utama: bagaimana cara kerjanya?
Mari kita mulai dengan polyfill
Firefox telah mendukung tata letak batu melalui sintaks Batalyon Kedua. Ini adalah CSS yang Anda butuhkan untuk membuat tata letak CSS Masonry Mesh di Firefox.
.masonry {
display: grid;
grid-template-columns: repeat(
auto-fit,
minmax(min(var(--item-width, 200px), 100%), 1fr)
);
grid-template-rows: masonry;
grid-auto-flow: dense; /* Optional, but recommended */
}
Karena Firefox sudah memiliki dukungan batu setempat, tentu saja, kita tidak boleh mengacaukannya. Cara terbaik untuk memeriksa apakah Masonry didukung secara default adalah dengan memeriksa apakah grid-template-rows Bisa menahan masonry nilai.
function isMasonrySupported(container) {
return getComputedStyle(container).gridTemplateRows === 'masonry'
}
Jika Masonry didukung, kami akan melewatkan implementasi. Kalau tidak, kami akan melakukan sesuatu tentang itu.
const containers = document.querySelectorAll('.masonry')
containers.forEach(async container => {
if (isMasonrySupported(container)) return
})
Tata letak batu membuatnya sederhana
Sekarang, saya ingin mengambil kata pengantar segmen pasar ini, saya bukan orang yang menemukan teknologi ini.
Ketika saya menggali di jaringan, saya menemukan teknologi ini dan mencari cara yang mungkin untuk mengimplementasikan kisi -kisi batu hari ini. Jadi, pertama kali mengembangkan gagasan pengembang yang tidak dikenal, mungkin itu adalah pemahaman saya, mengonversi dan menggunakannya.
Teknologi ini terlihat seperti ini:
- Kami mengatur
grid-auto-rowstiba0px. - Lalu kami menyiapkan
row-gaptiba1px. - Lalu kami mendapatkan ketinggian proyek
getBoundingClientRect. - Kami kemudian mengukur dengan menambahkan “penugasan baris” dari item tersebut
heightinicolumn-gapNilai umum.
Ini nyata Jika Anda telah menggunakan CSS Mesh dengan cara standar, itu tidak sensitif. Tetapi begitu Anda mendapatkan ini, Anda juga bisa menguasai cara kerjanya!
Sekarang, karena ini sangat tidak intuitif, kita akan melalui hal -hal selangkah demi selangkah sehingga Anda dapat melihat bagaimana seluruh proses berkembang menjadi output akhir.
langkah demi langkah
Pertama, kami mengatur grid-auto-rows tiba 0px. Ini menjengkelkan, karena setiap proyek grid akan secara efektif memiliki “ketinggian nol”. Namun, pada saat yang sama, grid CSS mempertahankan urutan kolom dan baris!
containers.forEach(async container => {
// ...
container.style.gridAutoRows="0px"
})

Kedua, kami menyiapkan row-gap tiba 1px. Setelah Anda melakukan ini, Anda mulai melihat tumpukan awal baris, satu piksel di bawah setiap piksel.
containers.forEach(async container => {
// ...
container.style.gridAutoRows="0px"
container.style.setProperty('row-gap', '1px', 'important')
})

Ketiga, dengan asumsi tidak ada gambar atau elemen media lain dalam proyek grid, kita dapat dengan mudah mendapatkan ketinggian setiap proyek grid getBoundingClientRect.
Kita kemudian dapat mengembalikan “tinggi” item kisi di kisi CSS dengan menggantinya grow-row-end Dan height nilai. Ini karena setiap row-gap Sekarang 1px Tinggi.
Ketika kami melakukan ini, Anda melihat jaringan mulai terbentuk. Sekarang setiap proyek kembali ke posisinya masing -masing:
containers.forEach(async container => {
// ...
let items = container.children
layout({ items })
})
function layout({ items }) {
items.forEach(item => {
const ib = item.getBoundingClientRect()
item.style.gridRowEnd = `span ${Math.round(ib.height)}`
})
}

Sekarang, kita perlu memulihkan kesenjangan baris antar proyek. Untungnya, karena Masonry Mesh biasanya memiliki hal yang sama column-gap Dan row-gap Nilai, kita dapat memahami kesenjangan baris yang diperlukan dengan membaca column-gap nilai.
Setelah kami melakukan ini, kami menambahkannya ke grid-row-end Perluas jumlah baris (“tinggi”) yang ditempati item di kisi:
containers.forEach(async container => {
// ...
const items = container.children
const colGap = parseFloat(getComputedStyle(container).columnGap)
layout({ items, colGap })
})
function layout({ items, colGap }) {
items.forEach(item => {
const ib = item.getBoundingClientRect()
item.style.gridRowEnd = `span ${Math.round(ib.height + colGap)}`
})
}

Dan, begitu saja, kami membuat kisi batu! Semuanya di sini hanya untuk mempersiapkan produksi.
Tunggu agar media memuat
Coba tambahkan gambar ke proyek grid apa pun dan Anda akan melihat grid terputus. Itu karena ketinggian item akan “salah”.

Ini salah karena kami menerimanya height Nilai sebelum gambar dimuat dengan benar. DOM belum tahu ukuran gambar. Untuk memperbaikinya, kita harus menunggu media memuat sebelum dapat berjalan layout Fungsi.
Kita dapat melakukan ini dengan kode berikut (saya tidak akan menjelaskan ini karena ini bukan trik CSS 😅):
containers.forEach(async container => {
// ...
try {
await Promise.all([areImagesLoaded(container), areVideosLoaded(container)])
} catch(e) {}
// Run the layout function after images are loaded
layout({ items, colGap })
})
// Checks if images are loaded
async function areImagesLoaded(container) {
const images = Array.from(container.querySelectorAll('img'))
const promises = images.map(img => {
return new Promise((resolve, reject) => {
if (img.complete) return resolve()
img.onload = resolve
img.onerror = reject
})
})
return Promise.all(promises)
}
// Checks if videos are loaded
function areVideosLoaded(container) {
const videos = Array.from(container.querySelectorAll('video'))
const promises = videos.map(video => {
return new Promise((resolve, reject) => {
if (video.readyState === 4) return resolve()
video.onloadedmetadata = resolve
video.onerror = reject
})
})
return Promise.all(promises)
}
Lihatkami memiliki CSS Masnory Grid yang berfungsi dengan gambar dan video!

Membuatnya responsif dengan cepat
Ini adalah langkah yang mudah. Kita hanya perlu menggunakan API Ulang -ReSizeObserver untuk mendengarkan perubahan dalam ukuran wadah Masonry Mesh.
Saat perubahan terjadi, kami berlari layout Lagi fungsi:
containers.forEach(async container => {
// ...
const observer = new ResizeObserver(observerFn)
observer.observe(container)
function observerFn(entries) {
for (const entry of entries) {
layout({colGap, items})
}
}
})
Demonstrasi ini menggunakan API pengamat ukuran standar. Tapi Anda bisa menggunakan yang olahan resizeObserver Fitur yang kami bangun tempo hari.
containers.forEach(async container => {
// ...
const observer = resizeObserver(container, {
callback () {
layout({colGap, items})
}
})
})
Itu saja! Sekarang Anda memiliki jala batu yang kuat yang dapat Anda gunakan di setiap browser yang berfungsi yang mendukung CSS Mesh!
Menyenangkan, bukan? Implementasi ini sangat mudah digunakan!
Kisi batu dan laboratorium yang brilian
Jika Anda tidak suka menggunakan kode yang dibangun oleh orang lain, mungkin Anda mungkin ingin mempertimbangkan untuk mengambil kode yang saya buat untuk Anda di Labz yang indah.
Untuk melakukan ini, instal Asisten Perpustakaan dan tambahkan kode yang diperlukan:
# Installing the library
npm install @splendidlabz/styles
/* Import all layouts code */
@import '@splendidlabz/layouts';
// Use the masonry script
import { masonry } from '@splendidlabz/styles/scripts'
masonry()
Satu hal terakhir: Saya telah membangun banyak alat untuk membantu Memudahkan Anda dan saya untuk mengembangkan web. Saya telah menempatkan mereka semua di bawah merek Labz yang brilian, dan salah satu contohnya adalah kisi batu yang saya tunjukkan hari ini.
Jika Anda suka ini, Anda mungkin tertarik pada utilitas tata letak lainnya, yang membuat tata letak super build.
Sekarang, saya harap Anda menikmati posting ini hari ini. Jika Anda mau, lepaskan CSS Masonry Grid baru Anda dan semuanya berjalan dengan baik!
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
#Membuat #tata #letak #batu #yang #efektif #hari #ini