28111 sujets

CSS et mise en forme, CSS3

Bonjour à vous tous,

Je bute sur un problème que je n'arrive pas à résoudre en CSS.
Voici le code HTML :
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="utf-8">
    <link href="styles.css" type="text/css" rel="stylesheet">
    <link href="reset.css" type="text/css" rel="stylesheet">
    <title>Flexbox</title>
</head>
<body>
    <div class="cartouche">
        <div class="noir marge-bas largeur"></div>
        <div class="jaune marge-bas largeur"></div>
        <div class="bleu marge-bas largeur"></div>
        <div class="violet marge-bas largeur"></div>
        <div class="vert marge-bas largeur"></div>
        <div class="orange marge-bas largeur"></div>
        <div class="gris marge-bas largeur"></div>
        <div class="cyan marge-bas largeur"></div>
        <div class="magenta marge-bas largeur"></div>
        <div class="rouge marge-bas largeur"></div>
        <div class="marron marge-bas largeur"></div>
        <div class="turquoise marge-bas largeur"></div>
        <div class="noir marge-bas largeur"></div>
        <div class="jaune marge-bas largeur"></div>
        <div class="bleu marge-bas largeur"></div>
        <div class="violet marge-bas largeur"></div>
    </div>
</body>
</html>


Voici le code CSS :

.noir {background-color: black; height: 200px;}
.jaune {background-color: yellow; height: 400px;}
.bleu {background-color: blue; height: 300px;}
.violet {background-color: purple; height: 100px;}
.vert {background-color: green; height: 200px;}
.orange {background-color: orange; height: 300px;}
.gris {background-color: gray; height: 400px;}
.cyan {background-color: cyan; height: 300px;}
.magenta {background-color: magenta; height: 300px;}
.rouge {background-color: red; height: 300px;}
.marron {background-color: brown; height: 300px;}
.turquoise {background-color: turquoise; height: 300px;}
  
.cartouche {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    padding: 30px 30px 0 30px;
    background-color: silver;
}
  
.marge-bas {
    margin-bottom: 2em;
}
  
.largeur {
    width: 300px;
}


Et voici ce que j'obtiens :

upload/1607503820-62242-capture1.png

Mais, en réalité, je voudrais obtenir ça :

upload/1607503850-62242-capture2.jpg

Je voudrais que les blocs qui se trouvent en-dessous viennent s'encastrer sous ceux qui se trouvent au-dessus. J'ai essayé le float: left; j'ai essayé aussi le clear: both; mais rien ne fonctionne.

J'ai modifié le code CSS de la classe .cartouche en remplaçant justify-content: flex-start; par flex-direction: column; et j'ai aussi ajouté une hauteur height: 60em;

.cartouche {
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  padding: 30px 30px 0 30px;
  background-color: silver;
  height: 60em;
}


Mais j'obtiens ça :

upload/1607503947-62242-capture3.jpg

Les blocs de couleur débordent sur le côté droit en sortant du cartouche gris. Si j'augmente la hauteur du cartouche gris, les blocs de couleur passent à la ligne et rentrent dans le cartouche. Mais, quand je passe en mode d'affichage smartphone, le cartouche gris se réduit pour entrer dans la largeur du smartphone et les blocs de couleur ne passent pas à la ligne mais continuent à déborder.

Je ne comprends pas pourquoi les blocs de couleur se comportent comme ça.
Quelqu'un saurait m'aider ?
Modifié par ObiJuanKenobi (09 Dec 2020 - 09:54)
Modérateur
Bonjour,

ObiJuanKenobi a écrit :

Les blocs de couleur débordent sur le côté droit en sortant du cartouche gris. Si j'augmente la hauteur du cartouche gris, les blocs de couleur passent à la ligne et rentrent dans le cartouche. Mais, quand je passe en mode d'affichage smartphone, le cartouche gris se réduit pour entrer dans la largeur du smartphone et les blocs de couleur ne passent pas à la ligne mais continuent à déborder.

Je ne comprends pas pourquoi les blocs de couleur se comportent comme ça.
Quelqu'un saurait m'aider ?


Pour ton dernier essai, du fait que le conteneur a une hauteur fixée, et comme on est en flex-direction: column; le navigateur va chercher à rajouter des colonnes vers la droite, éventuellement en dépassant.

Il faudrait qu'on soit en flex-direction: row;, pour que le navigateur cherche à ajouter des lignes vers le bas. Or ton problème, c'est qu'avec flex-direction:row (comme tu l'as d'ailleurs compris), les boites ne s'emboiteront pas les unes dans les autres (puisqu'on affiche des lignes et non pas des colonnes dans ce cas).

Pour l'instant, et en supposant que tout est inconnu a priori (nombre de boite, hauteur des boites et largeurs des boites), je ne vois pas de solution à ton problème en css pur (ce qui ne veut pas dire qu'il n'y en a pas).

Si par contre certaines de ces informations étaient connues a priori, on peut peut-être imaginer des solutions. Par exemple, si l'on connaissait a priori plus ou moins le nombre de boites, la largeur des boites et les hauteurs des boites, on peut avec des media-queries, et en utilisant ta dernière variante, se contenter de modifier la hauteur du conteneur en fonction de la largeur disponible, et ainsi avoir assez de place en hauteur pour que ça ne déborde pas en largeur.

Amicalement,
Modifié par parsimonhi (09 Dec 2020 - 12:45)
Je connais la largeur de chaque bloc coloré, c'est celle de la largeur du smartphone (je crois que c'est 430 px). Par contre, je ne connais pas à l'avance sa hauteur car le contenu variera (ce sera du texte et des images). Je ne connais pas non plus le nombre de blocs à placer. Ce que je cherche à faire c'est une présentation comme dans pinterest.fr où ce sont des blocs contenant des images et du texte, qui s'affichent de façon aléatoire les uns sous les autres et s'imbriquent en fonction de leur contenu aléatoire aussi. Voici un exemple d'affichage de pinterest.fr :
upload/1607517388-62242-capture.jpg

Je voudrais obtenir le même principe d'affichage car je trouve que c'est dynamique et ça sort de la logique de tous les sites internet qu'on voit tous les jours.

J'ai donc compris que je dois m'orienter vers les Media Queries pour résoudre mon problème. Mais je ne connais pas encore cette propriété CSS pour le responsive. Je verrais cela plus tard quand j'aborderai ce chapitre car je débute dans le HTML et CSS.

En attendant, je vais remettre flex-direction: row, enlever la hauteur du conteneur et placer la même hauteur pour chaque bloc. Tant pis si le texte est plus court et qu'il y aura du vide dans les blocs. Comme ça, tout sera placé les uns en dessous des autres.

Merci pour ta réponse, parsimonhi.
Modifié par ObiJuanKenobi (09 Dec 2020 - 13:46)
Modérateur
Salut,

parsimonhi a écrit :
Pour l'instant, et en supposant que tout est inconnu a priori (nombre de boite, hauteur des boites et largeurs des boites), je ne vois pas de solution à ton problème en css pur (ce qui ne veut pas dire qu'il n'y en a pas).

+1

C'est un des grands fossé design / CSS only (il y en a de moins en moins mais celui-ci est sympa). Beaucoup veulent faire des murs de tuiles comme ça mais c'est assez compliqué et pas faisable en CSS que je sache... Et même en Js c'est relou pour bien répartir les bloc et que les différentes colonnes ne soient pas disproportionnée (coucou le cas ou tout les petits blocs se retrouvent dans la même colonne par pur hasard).

Bref compliqué comme design. Une des solution les plus simple pour moi c'est de mettre des hauteurs fixes à tes block pour pouvoir les répartir plus facilement (mais ca sera quand même pas automatique...)

Bon courage et fais nous un retour si jamais tu trouves une solution c'est toujours intéressant !

Bonne journée
Modérateur
Bonjour,

Si on connait la largeur des colonnes, et maintenant que je vois un peu mieux ce que tu veux faire, tu peux utiliser la propriété "columns" couplée à des media-queries.

Exemple vite fait de css qui marche avec ton html :
.cartouche {
    columns:4;
    padding: 30px 30px 0 30px;
    background-color: silver;
}
  
.marge-bas {
    margin-bottom: 30px;
}
  
.largeur {
    width: 300px;
    break-inside: avoid;
}
@media only screen and (max-width: 1300px) {
	.cartouche {
    	columns:3;
    }
}
@media only screen and (max-width: 1000px) {
	.cartouche {
    	columns:2;
    }
}
@media only screen and (max-width: 700px) {
	.cartouche {
    	columns:1;
    }
}

Amicalement,
Meilleure solution
Modérateur
pour l'instant, avec grid si l'on ne veut ou ne peut pas determiner à l'avance le nombre de ligne/colonnes a occupé , on peut avec JavaScript , récupérer la hauteur de chaque élément pour lui attribuer un nombre de lignes à occuper (même principe pour les colonnes/largeur) , enfin auto-fit/auto-fill pour construire la grille avec le mot clé dense pour la remplir.

Cependant petit soucis avec de longues pages et chrome qui est limité a 999 lignes ...

si l'on prend 1px = 1 ligne = 999px de hauteur, on se retrouve très vite à la valeur max gérable par Chrome, si l'on prend 10px on passe a 9990 et ainsi de suite mais avec de moins en moins de précisions dans la tailles des cellules.

Ton exemple, avec des valeurs basé sur 100px, permet de facilement gérer des lignes de 100px . Ton exemple repris en grid et column pour voir les différences d'affichage : https://codepen.io/gc-nomade/pen/MWjbWzz

le principe sur javascript et grid https://codepen.io/gc-nomade/pen/GRqwwdg (reprise d'un exemple masonry mais avec juste une boucle pour attribuer un nombre de ligne en fonction de la hauteur ) et qui bug dans chrome passer les 999 lignes (row) (peut dépanner pour quelques éléments).

il y a aussi flex et js .. et matchmedia https://codepen.io/gc-nomade/pen/aboRWRe en rapport avec ce sujet qui aborde https://forum.alsacreations.com/topic-4-85619-1-Affichage-Masonry-CSS-pour-commentaires.html ( plein d'autres infos et référence dans les interventions) sans oublier cet autre sujet Smiley cligne https://forum.alsacreations.com/topic-4-81880-1-A-quand-un-module-CSS-pour-un-effet-Masonry-no-JS-Y.html , il y avait aussi ce sujet similaire : https://forum.alsacreations.com/topic-4-86948-1-Affichage-miniatures-differentes-tailles.html


Alors en attendant que https://drafts.csswg.org/css-grid-3/#propdef-masonry-auto-flow commence a être implémenter dans nos navigateur les choix CSS sont limites (même avec un minimum de js) et se rabattre directement sur le script masonry est probablement la meilleure chose pour éviter une calvitie précoce Smiley cligne , Il y a plein de choses déjà prévues https://masonry.desandro.com/layout.html .


Cdt
Modifié par gcyrillus (10 Dec 2020 - 15:59)
@gcyrillus : deux années plus tard en répondant à un autre intervenant... je viens de tester ta méthode avec un script trouvé sur le net, génial : Masonry with CSS Grid Layout & JavaScript.

Testé avec 600 items, le script mouline un peu mais Chrome ne plante pas.
Modifié par Olivier C (04 Sep 2022 - 22:28)