28111 sujets

CSS et mise en forme, CSS3

Modérateur
Hello,
Avec la structure suivante, j'aurais voulu avoir un comportement qui aligne les différents card-header, -body et -footer en 2, 3, 4 ou 5 columns.
<main>
	<div class="card">
		<div class="card-header"></div>
		<div class="card-body"></div>
		<div class="card-footer"></div>
	</div>
	<div class="card">
		<div class="card-header"></div>
		<div class="card-body"></div>
		<div class="card-footer"></div>
	</div>
	<div class="card">
		<div class="card-header"></div>
		<div class="card-body"></div>
		<div class="card-footer"></div>
	</div>
	<div class="card">
		<div class="card-header"></div>
		<div class="card-body"></div>
		<div class="card-footer"></div>
	</div>
</main>

Pour un rendu comme celui là:
card-header1   -- card-header2 -- card-header3
 card-body1    --  card-body2    --  card-body3
 card-footer1   --card-footer2   --card-footer3

card-header4   -- card-header5 -- card-header6
 card-body4    --  card-body5    --  card-body6
card-footer4   --card-footer5   --card-footer6


Dans l'idée, je me suis dit qu'un `display: grid` sur <main> avec un `display: contents` sur les .card devrait être une bonne base mais je n'arrive pas à écrire le template qui fait qu'on affiche d'abord en vertical les card et puis en horizontal…

L'idée est bien d'avoir la même hauteur pour ces 3 sections de card (toujours basé sur une hauteur inconnue)

Quelqu'un pour une piste ? Smiley smile
Modifié par Yordi (11 Feb 2019 - 17:33)
Modérateur
Bonsoir,

qu'attends tu de la regle : display:contents; ?
Car celle ci en principe fait disparaitre le conteneur , donc à priori , le visuel que tu décrit est cohérent, au moins dans Firefox qui implémente cette règle depuis un bon moment déjà.

si l'anglais ne te rebute pas : https://css-tricks.com/get-ready-for-display-contents/ et pour grid : (exemples) https://gridbyexample.com/ et un tuto ou aide-mémoire https://css-tricks.com/snippets/css/complete-guide-grid/

cordialement

EDIT avec les liens précédent tu peut faire ceci (demo sur codepen) https://codepen.io/gc-nomade/pen/XOqEpN

CSS :
main {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;/* 3 col*/

  /*extra pour la demo de grid */
  min-height: 90vh;
  grid-auto-rows:1fr;
  grid-gap: 1em;
}
.card {
  border: solid;/* pour les voir */

/* imbrication pas essentiel pour le grid de main  */
  display: flex; /* flex peut aussi aider a ce niveau au lieu d'imbriquer un autre grid et reduire la confusion */
  flex-direction: column;
}
.card > *:before {/* pour les voir */
  content: attr(class);
  display:block;
}
.card-body {
/* au choix,
pour repousser header et footer aux extremités */
  /*flex: 1; ou selon besoin de mise en forme */
  margin:auto;
}


P.S. J'ai ajouté un exemple dans la démo en lien avec un display:contents qui pour le coup peut-être utile si compris par le navigateur.
Modifié par gcyrillus (11 Feb 2019 - 21:58)
Modérateur
Hello,
Merci pour le réponse, j'avais pensé aussi au flex aussi pour la card mais du coup, pas possible d'avoir un alignement sur les header/body/footer si le contenu n'est pas identique.
J'ai forké pour simplement ajouter du contenu et ainsi mieux comprendre ce que je recherche à faire Smiley smile

Du coup, mon idée du `display: contents` était bien de supprimer ce layer pour avoir accès à tout les items et avoir le conteneur en grid pour avoir l'alignement mais je ne trouve pas le pattern qui fait que les items s'afficheront dans cet ordre:
1  | 4  | 7  | 10
2  | 5  | 8  | 11
3  | 6  | 9  | 12
-----------------
13 | 16 | 19 | 22
14 | 17 | 20 | 23
15 | 18 | 21 | 24
-----------------
25 | ...
26 | ...
27 | ...
Modérateur
Bonjour,

Une possibilité serait de se servir de :nth-child(n) pour dispatcher les enfants dans les colonnes .
Pour quatre colonnes , la base serait :nth-child(4n) et pour le remplissage de la grille
grid-auto-flow: dense; pour ne pas avoir de trous.

main {
  display: grid;
  grid-template-columns: repeat(4,1fr);
  grid-auto-flow: dense;
}
.card {
  display: contents;
}
/* positionnement des enfants dans la grille */
main .card:nth-child(4n - 3) > div {
  grid-column: 1;
}
main .card:nth-child(4n - 2) > div {
  grid-column: 2;
}
main .card:nth-child(4n - 1) > div {
  grid-column: 3;
}
main .card:nth-child(4n) > div {
  grid-column: 4;
}


demo/fork https://codepen.io/gc-nomade/pen/wNXbrr

Cdt
Meilleure solution
Modérateur
C'est génial, c'est exactement ça, grand merci gcyrillus ! J'adore parce que ça reste super simple et robuste comme approche Smiley biggrin

Pour celui que ça intéresse, j'ai "sassé" la chose pour automatiser la génération de columns :
$cardsColumns-gap: 1rem;
$cardsColumns-min: 2;
$cardsColumns-max: 8;

@mixin cardColumns($n: 2, $cls: $n){
	.card-aligned-#{$cls}-columns{
		display: grid;
		grid-template-columns: repeat(#{$n}, 1fr);
		grid-auto-flow: dense;
		grid-column-gap: $cardsColumns-gap;

		.card{
			display: contents;

			@for $i from 0 through $n{
				&:nth-child(#{$n}n - #{$n - $i}) > div{grid-column: #{$i}}
			}
		}
	}
}

@for $i from $cardsColumns-min through $cardsColumns-max{
	@include cardColumns($i);
}


Et le codepen qui va bien avec en plus une version "auto".

Tous commentaires pour améliorer est le bienvenu évidement !