cómo replicar el diseño de apilamiento div absoluto de pinterest.com [cerrado]

104

Estoy buscando replicar el diseño div de Pinterest.com, específicamente cómo se ajusta el número de columnas para adaptarse más / menos al cambio de tamaño del navegador y el apilamiento vertical no depende de las alturas de las columnas adyacentes. El código fuente muestra que cada div es posición absoluta. Un cofundador ha respondido una publicación de Quora indicando que se hace con jQuery y CSS personalizados. Me gustaría que los resultados estuvieran ordenados de izquierda a derecha. Cualquier dirección que pueda proporcionar para hacerlo yo mismo será muy apreciada.

chrickso
fuente
Codifiqué el mío con Jquery y CSS simples. Si desea que esto cambie al cambiar el tamaño, simplemente envuélvalo en una función y observe el cambio de tamaño en el elemento contenedor jsfiddle.net/92gxyugb/1
Andrew WC Brown

Respuestas:

79

También puede verificar en jQuery Plug-in Masonry , para este tipo de funcionalidad.

Beto.
fuente
3
Biblioteca realmente asombrosa. Ahora lo estoy usando sin problemas.
AhmetB - Google
183

Escribí el guión de Pinterest. Los ID no están relacionados con el diseño y se utilizan para otros JS relacionados con la interacción. Aquí está la base de cómo funciona:

Antemano:

  • Coloque absolutamente los contenedores de pines
  • Determinar el ancho de la columna
  • Determinar el margen entre columnas (el canalón)

Configurar una matriz:

  • Obtenga el ancho del contenedor principal; calcular el número de columnas que encajarán
  • Cree una matriz vacía, con una longitud igual al número de columnas. Utilice esta matriz para almacenar la altura de cada columna a medida que crea el diseño, por ejemplo, la altura de la columna 1 se almacena como matriz [0]

Pase por cada pin:

  • Coloque cada pin en la columna más corta en el momento en que se agrega
  • "left:" === el número de columna (matriz de índice) multiplicado por el ancho de la columna + margen
  • "top:" === El valor en la matriz (altura) para la columna más corta en ese momento
  • Finalmente, agregue la altura del pin a la altura de la columna (valor de matriz)

El resultado es ligero. En Chrome, diseñar una página completa de más de 50 pines toma menos de 10 ms.

Evan Sharp
fuente
4
¿Qué quieres decir con calcular la altura de la columna? ¿Cómo saber qué tan alto debe ser si no conoce el número y la altura de los elementos que contiene? ¿Alguna posibilidad de que pueda diseñar algún pseudo código para demostrar?
Michael Giovanni Pumo
22
aquí hay un tutorial sólido - benholland.me/javascript/…
hollandben
1
Comentarios de un usuario anónimo (que se encuentra en la cola de edición): Curiosamente hice exactamente el mismo script en jQuery, con la ligera diferencia de crear una tabla con 1 fila y N columnas, y simplemente agregarlas a la columna más corta de izquierda a derecha prioridad. Aunque también agregué una constante de "Diferencia de altura mínima" requerida para omitir una columna cuando se coloca de izquierda a derecha, esto le da al diseño una visualización cronológicamente intuitiva sin perder las alturas siendo lo más uniforme posible
Oers
1
@MichaelGiovanniPumo Creo que la altura debe conocerse antes del diseño (en el caso de Pinterest), no tienen un estado "inicial" que tenga divs superpuestos entre sí. Esto no se puede hacer si no se conoce la altura.
ptgamr
1
El enlace de @ hollandben está muerto, nuevo enlace: benholland.me/javascript/2012/02/20/…
Lukmo
57

Lanzamos un complemento de jQuery porque recibimos la misma pregunta varias veces para Wookmark . Crea exactamente este tipo de diseño. Véalo aquí: complemento Wookmark jQuery

GBKS
fuente
4
Esta solución parece cargar más rápido que la mampostería
Michael L Watson
cual encuentras mejor? la marca de madera o la mampostería?
Ramje
Prefiero esto a la mampostería, parece más rápido como dijo Michael.
nerdburn
2

Después de ver todas las opciones, terminé implementando un diseño similar a Pinterest de esta manera:

Todos los DIV son:

div.tile {
    display: inline-block;
    vertical-align: top;
}

Esto hace que se coloquen mejor en filas que cuando están flotando.

Luego, cuando se carga la página, itero todos los DIV en JavaScript para eliminar los espacios entre ellos. Funciona aceptablemente bien cuando:

  1. Los DIV no son muy diferentes en altura.
  2. No le importan algunas infracciones menores del orden (algunos elementos que estaban debajo se pueden levantar arriba).
  3. No le importa que el resultado final sea de diferente altura.

El beneficio de este enfoque: su HTML tiene sentido para los motores de búsqueda, puede funcionar con JavaScript desactivado / bloqueado por el firewall, la secuencia de elementos en HTML coincide con la secuencia lógica (los elementos más nuevos antes que los más antiguos)

esp
fuente
Oye, ¿podrías decirme cómo calculó la compensación que tuvo que restar? Y también, ¿cómo resolvió el problema de que el último elemento estaba en el lado derecho, porque hay un elemento que es un poco más grande y lo empuja allí?
Lukas Oppermann
@LukasOppermann 1) El desplazamiento del mosaico es la suma del desplazamiento del mosaico en la misma columna en la fila anterior y la diferencia entre la altura del mosaico más alto en la fila anterior y la altura del mosaico en la misma columna en la fila anterior. Eche un vistazo a dev.sheeporpig.com/news (primero debe hacer clic en el enlace dev.sheeporpig.com/sheep/3210 para obtener acceso al sitio de desarrollo, para que pueda ver scripts sin comprimir y comentados en archivos separados), archivo de script stock_news.js, función compressTiles.
especialmente
@LukasOppermann 2) Si usa CSS como en la respuesta (especialmente display: inline-block), no sucede. Solo sucede si flotas: dejaste tus divs. No uso flotador.
especialmente
0

Dividen entidades por columnas con identificadores (mala solución ... mejor use los nombres de clase) y luego calculan las posiciones por grupos de columnas

ant_Ti
fuente
2
+1 Por echar un vistazo a su código fuente.
Bojangles
Fue interesante para mí, pero creo que hay una mejor solución con menos cálculos de js
ant_Ti
display: inline-blockSupongo que podría usarlo , pero los elementos de diferente altura vertical no se colocarían juntos.
Bojangles
1
es mejor usar contenedores de columnas (divs con float:left;y último con overflow: hidden;) y almacenar elementos allí
ant_Ti
4
Buen punto. Si realmente quisiera seguir la ruta de JavaScript, ¿podría usar jQuery Masonry?
Bojangles
0

¿Podría usar flotadores y dimensionar sus anchos de div usando porcentajes junto con el ancho mínimo para forzar que los divs caigan automáticamente una vez que se alcanza el ancho mínimo? Es la forma en que lo hicimos funcionar en http://www.goldtree.co.za/work

Soy Goldtree
fuente