comment reproduire la disposition d'empilement div absolu de pinterest.com [fermé]

104

Je cherche à reproduire la disposition div de Pinterest.com, en particulier la façon dont le nombre de colonnes s'ajuste pour s'adapter plus / moins au redimensionnement du navigateur et l'empilement vertical ne dépend pas de la hauteur des colonnes adjacentes. Le code source montre que chaque div est une position absolue. Un co-fondateur a répondu à un message de Quora indiquant que cela était fait avec jQuery et CSS personnalisés. J'aimerais que les résultats soient triés de gauche à droite. Toute direction que vous pourriez fournir pour le faire moi-même serait grandement appréciée.

chrickso
la source
J'ai codé le mien avec de simples Jquery et CSS. Si vous voulez que cela change lors du redimensionnement, enveloppez-le simplement dans une fonction et regardez le redimensionnement sur l'élément conteneur jsfiddle.net/92gxyugb/1
Andrew WC Brown

Réponses:

79

Vous pouvez également vérifier sur la maçonnerie jQuery Plug-in , pour ce type de fonctionnalité.

Bob.
la source
3
Bibliothèque vraiment incroyable. Maintenant, je l'utilise sans aucun problème.
AhmetB - Google
183

J'ai écrit le script Pinterest. Les ID ne sont pas liés à la mise en page et sont utilisés pour d'autres JS liés à l'interaction. Voici comment cela fonctionne:

Préalablement:

  • Positionnez absolument les conteneurs de broches
  • Déterminer la largeur de la colonne
  • Déterminer la marge entre les colonnes (la gouttière)

Configurer une baie:

  • Obtenez la largeur du conteneur parent; calculer le nombre de colonnes qui conviendront
  • Créez un tableau vide, avec une longueur égale au nombre de colonnes. Utilisez ce tableau pour stocker la hauteur de chaque colonne au fur et à mesure que vous construisez la mise en page, par exemple, la hauteur de la colonne 1 est stockée sous forme de tableau [0]

Boucle à travers chaque broche:

  • Placez chaque épingle dans la colonne la plus courte au moment où elle est ajoutée
  • "left:" === la colonne # (tableau d'index) multipliée par la largeur de la colonne + la marge
  • "top:" === La valeur du tableau (hauteur) pour la colonne la plus courte à ce moment
  • Enfin, ajoutez la hauteur de la broche à la hauteur de la colonne (valeur du tableau)

Le résultat est léger. Dans Chrome, la présentation d'une page complète de plus de 50 broches prend moins de 10 ms.

Evan Sharp
la source
4
Comment voulez-vous dire calculer la hauteur de la colonne? Comment savez-vous quelle doit être sa hauteur si vous ne connaissez pas le nombre et la hauteur des éléments qu'il contient? Avez-vous une chance de mettre en page un pseudo-code pour le démontrer?
Michael Giovanni Pumo
22
voici un tutoriel solide - benholland.me/javascript/…
hollandben
1
Commentaires d'un utilisateur anonyme (trouvé dans la file d'attente d'édition): Curieusement, j'ai fait exactement le même script dans jQuery, avec la légère différence de créer une table avec 1 ligne et N colonnes, et de les ajouter simplement à la colonne la plus courte de gauche à droite priorité. Même si j'ai également ajouté une constante "Différence de hauteur minimale" nécessaire pour sauter une colonne lors du positionnement de gauche à droite, cela donne à la mise en page un affichage chronologiquement intuitif sans perdre les hauteurs aussi régulières que possible
oers
1
@MichaelGiovanniPumo Je pense que la hauteur doit être connue avant la mise en page (dans le cas de Pinterest), ils n'ont pas d'état "initial" qui ont des div se chevauchent. Cela ne peut pas être fait si la hauteur n'est pas connue.
ptgamr
1
Le lien de @ hollandben est mort, nouveau lien: benholland.me/javascript/2012/02/20
...
57

Nous avons publié un plugin jQuery car nous avons eu la même question plusieurs fois pour Wookmark . Il crée exactement ce type de mise en page. Regardez-le ici - Plugin Wookmark jQuery

GBKS
la source
4
Cette solution semble se charger plus rapidement que la maçonnerie
Michael L Watson
que trouvez-vous mieux? le wookmark ou la maçonnerie?
Ramje
Je préfère cela à la maçonnerie, semble plus rapide comme Michael l'a dit.
nerdburn
2

Après avoir examiné toutes les options, j'ai fini par implémenter la mise en page similaire à Pinterest de cette manière:

Tous les DIV sont:

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

Cela les rend mieux positionnés en rangées que lorsqu'ils sont flottants.

Ensuite, lorsque la page est chargée, j'itère toutes les DIV en JavaScript pour supprimer les espaces entre elles. Cela fonctionne bien quand:

  1. Les DIV ne sont pas très différents en hauteur.
  2. Cela ne vous dérange pas de quelques violations mineures de l'ordre (certains éléments qui étaient ci-dessous peuvent être tirés vers le haut).
  3. Cela ne vous dérange pas que la ligne du bas soit de hauteur différente.

L'avantage de cette approche - votre HTML a du sens pour les moteurs de recherche, peut fonctionner avec JavaScript désactivé / bloqué par le pare-feu, la séquence d'éléments en HTML correspond à la séquence logique (les éléments les plus récents avant les plus anciens)

esp
la source
Hé, peux-tu me dire comment tu as calculé le décalage que tu devais soustraire? Et aussi comment avez-vous résolu le problème du dernier élément étant du côté droit, car il y a un élément qui est un peu plus grand et le pousse là-bas.
Lukas Oppermann
@LukasOppermann 1) Le décalage de la tuile est la somme du décalage de la tuile dans la même colonne de la ligne précédente et la différence entre la hauteur de la tuile la plus haute de la ligne précédente et la hauteur de la tuile dans la même colonne dans la ligne précédente. Jetez un œil à dev.sheeporpig.com/news (vous devez d'abord cliquer sur le lien dev.sheeporpig.com/sheep/3210 pour accéder au site de développement - afin que vous puissiez voir les scripts non compressés et commentés dans des fichiers séparés), fichier de script stock_news.js, fonction compressTiles.
esp
@LukasOppermann 2) Si vous utilisez CSS comme réponse (en particulier display: inline-block), cela ne se produit pas. Cela n'arrive que si vous float: laissez vos divs. Je n'utilise pas de flotteur.
esp
0

Ils divisent les entités par colonnes avec des identifiants (mauvaise solution ... mieux vaut utiliser les noms de classe) puis calculent les positions par groupes de colonnes

ant_Ti
la source
2
+1 Pour avoir parcouru leur code source.
Bojangles
C'était intéressant pour moi mais je pense qu'il y a une meilleure solution avec moins de calculs js
ant_Ti
Vous pourriez utiliser display: inline-blockje suppose, mais les éléments de hauteur verticale différente ne s'asseoiraient pas ensemble.
Bojangles
1
mieux utiliser des conteneurs de colonnes (divs avec float:left;et le dernier avec overflow: hidden;) et y stocker des éléments
ant_Ti
4
Bon point. Si vous vouliez vraiment suivre la voie JavaScript, vous pourriez utiliser jQuery Masonry?
Bojangles
0

Vous pouvez utiliser des flotteurs et dimensionner vos largeurs de div en utilisant des pourcentages avec min-width pour forcer les div à tomber automatiquement une fois que la largeur minimale est atteinte? C'est ainsi que nous l'avons fait fonctionner sur http://www.goldtree.co.za/work

Je suis Goldtree
la source