28172 sujets

CSS et mise en forme, CSS3

Bonjour !

Je poste un message sur ce forum après des heures de recherche afin de faire fonctionner un système de grille aux gouttières fluides.

Je vous explique :

J'essaye de disposer des affiches de films sous forme de grille. Une affiche fait 165px/234px et je doit donc avoir des colonnes fixes. Ce sont les gouttières qui doivent être fluides. Si la largeur des gouttières est insuffisante ou trop importante, le nombre d'affiches par ligne doit pouvoir s'adapter.

Dans tous les cas, la première affiche d'une ligne doit être collée à gauche, la dernière de la ligne collée à droite de ma page (mon conteneur n'a pas de largeur prédéfinie).

Alors il y a deux écoles : la première étant de faire un tableau HTML, de lui mettre un width à 100%, puis de fixer la largeur des colonnes, en laissant les gouttières prendre l'espace restant. Le problème que j'ai avec ça, c'est que si mes gouttières sont trop petites ou trop grandes, cela devient compliqué de changer le nombre d'affiches par ligne.

Deuxième solution : une DIV par affiche, avec des marges pour les gouttières. Mais je ne parviens pas à obtenir l'effet produit par un tableau HTML ... J'ai essayé de simuler un tableau avec les propriétés CSS "display:table", "display:table-cell", mais je récupère les inconvénients du tableau HTML, et la difficulté pour changer le nombre d'affiches par lignes selon la largeur disponible.

Après des heures de tests de grilles CSS, de recherche sur des forums, j'en viens à me demander si c'est vraiment possible en CSS, et si je dois pas envisager une solution JavaScript.

J'attends donc vos avis sur la question.

Voici un test des deux solutions dont j'ai parlé : http://codepen.io/anon/pen/IHerE

Merci d'avance, et bonnes fêtes de fin d'année Smiley smile

Grégory
Je suis parvenu à la même conclusion: un script qui calcule la largeur de chaque élément, prend en compte la taille de la fenêtre et fait le calcul de positionnement. Cela me permet d'avoir un menu centré qui tient sur une seule ligne sur un écran en format paysage et sur deux lignes en format portait.

Je serais également intéressé à une solution purement CSS.
Non, mais il semblerait que ce soit ce que je cherche !

J'ai fait quelques tests et cela fonctionne très bien. Les affiches s'alignent comme je le souhaite avec l'alignement "space-between".

Seulement si j'ai beaucoup d'affiches et un écran pas assez large, tout est compressé. Alors j'ai vu qu'il y avait la propriété "flex-wrap" pour retourner à la ligne, mais dès que je l'applique, mon alignement flexible s'annule ...

J'ai mis en ligne mon code de test : http://codepen.io/anon/pen/hxqef

Une idée ?
J'ai trouvé un début de solution avec ce JSFiddle : http://jsfiddle.net/puz219/7Hq2E/

Il me reste deux choses à trouver :
- Comment conserver un espace minimum de 20px entre chaque élément (un margin-right sur chaque élément fonctionne mais du coup il y a 20px de vide à chaque fin de ligne)
- Comment aligner les éléments de la dernière ligne à gauche
Modifié par greggy76 (28 Dec 2013 - 17:52)
il y a moyen de simuler un flex-justify avec text-align:justify, ça tombe bien , tes images sont des boites en lignes.
Pour la marge, en restant dans l'idée de gerer ces boites comme du texte , nous avons letter-spacing (ou word-spacing).
Enfin, un pseudo en boite en ligne , pour ajouter une ligne vide, qui activera la justification des boites j'usqu'a la derniere ligne , enfin tant qu'il en restera plus que une sur la dernière ligne.
demo : http://codepen.io/gc-nomade/pen/qIdyG (déjà vue ici Smiley smile )

<edit> Sinon, si tu te fou de la derniere ligne, text-align:justify pour des images ou des 'inline-block;' suffit, après tout pourquoi faire compliquer Smiley cligne
Modifié par gc-nomade (28 Dec 2013 - 21:11)
Super ! La simulation des flexbox fonctionne mais pas la marge de 20px (entre chaque affiche) et la justification à gauche sur la dernière ligne.

upload/52807-image2.jpg
En fait quand je dis affiche, c'est une affiche + un peu de texte en dessous (mais le conteneur peut être mis en inline-block donc ça pose pas de probleme particulier. Voilà un de mes items :

<a class="movie-item" itemscope itemtype="http://schema.org/Movie">
    <div class="poster">
        <img itemprop="image" src="/assets/img/_temp/poster.png" width="165">
    </div>
    <h2 itemprop="name">Le Hobbit : La désaulation de Smaug</h2>
    <p itemprop="genre">Aventure/Fantastique</p>
</a>


Ton premier codepen, pose les mêmes soucis que précédemment (dernière ligne non justifiée à gauche, pas d'espacement minimum entre les affiches)

Le second est mieux. La dernière ligne est justifiée, et il y a un espacement minimum. Je sais pas si c'est améliorable, mais l'espacement entre les affiches sur la dernière ligne justifiée n'est pas le même que sur les autres lignes (ça me parait difficilement jouable mais t'auras peut être une idée .. ?)
JE viens de voir que mes codepen avaient , un coup sur deux, besoin d'un rafraichissement pour s'afficher correctement.

Je reprend ton code avec la première version. http://codepen.io/anon/pen/FJevL

Pour la dernière ligne, soit elle est justifiée (avec la pseudo ligne en plus) et si deux éléments il y en a un à droite et un à gauche, soit elle s'aligne à gauche avec l'espace que l'on retrouve entre les mots/lettre par défaut ou redéfinis dans la feuille de style.

Il y a aussi la piste CSS du column , sans en donner le nombre, mais largeur et espace entre, http://codepen.io/anon/pen/mzovw , du coup, on pense immanquablement au script http://masonry.desandro.com/
++
C'est cette version qui se rapproche le plus de ce que je cherche à faire :
http://codepen.io/anon/pen/mzovw

Cela dit, selon la largeur les 2/3 dernières lignes n'ont pas d'affiches sur leur dernière colonne.

Je vais étudier Masonry, que je n'ai jamais utilisé, je vais voir si je peux obtenir ce que je souhaite avec lui.
okay,

je te recommande de faire un test dans une page html sans en passer par codepen, qui peut provoquer ou cacher des défauts, le code est affiché dans une iframe et quelques script entre en jeux aussi (prefixage automatique, quelques protections/garde-fous pour ne pas planter l'interface de codepen ...)

Bonne continuation,
Même souci sur une page HTML hors codepen ...
Selon la largeur de la fenêtre, j'ai les dernières colonnes vides (sur 1 ou plusieurs lignes, toujours à partir du bas).

upload/52807-Capture-de.png
J'ai étudié Masonry, et j'ai réussi à obtenir le rendu que je souhaite.
Toutefois je n'ai pas trouvé de prise en charge de gouttières fluides, je les ai donc calculées en javascript. Elles sont calculées au chargement de la page, puis lorsque la page est redimensionnée.

Au chargement tout se passe bien, mais au redimensionnement de la fenêtre, j'ai parfois la dernière colonne qui ne se remplit pas. A ce moment là, si je recharge la page, tout fonctionne bien.

Masonry se déclenche quand il faut réorganiser les items, mais du coup ça doit interférer avec les déclenchements que je fait manuellement lorsque je redimensionne la fenêtre (afin de reporter la bonne valeur de gouttière)

Ce n'est pas très problématique, mais si quelqu'un a une idée je suis preneur Smiley smile
Voilà j'ai enfin réussi Smiley smile J'ai amélioré mon calcul de gouttière, et c'est impeccable !

Si ça intéresse quelqu'un, voilà mon calcul :

var container_width = $container.width();
var item_width = 165;
var gutter_min = 20;
var per_line = Math.floor(container_width / item_width);
var rest = container_width - (per_line*item_width);
				
if (rest < (gutter_min*(per_line-1))) { 
    per_line = per_line - 1;
    rest = container_width - (per_line*item_width);
}

var gutter_width = Math.floor(rest / (per_line-1));


Ce bout de code, couplé à Masonry, permet d'avoir un système de grille aux gouttières fluides Smiley smile

Merci à tous ceux qui m'ont aiguillé, notamment à gc-nomade Smiley cligne