web-dev-qa-db-fra.com

Aligner le contenu des cartes mat (image, texte et boutons)

Je travaille avec mat-card dans une liste et j'ai un problème d'alignement.

Voici ce que j'ai:

enter image description here

Voici ce que je veux:

enter image description here

Le code :

<div class="margin-top-20" fxFlexFill fxLayout="row wrap" fxLayout.xs="column" fxLayout.sm="column" fxLayoutGap="15px grid">
  <div fxFlex="20" fxFlex.md="33" *ngFor="let advert of adverts; let i = index" class="padding-fix">

    <div fxFlexFill fxLayoutAlign="center stretch">
      <mat-card class="ad">
        <div fxLayoutAlign="space-between center">
          <img mat-card-image src="test" alt="test">
        </div>
        <mat-card-title>test</mat-card-title>
        <mat-card-content>
          <p>
            test
          </p>
        </mat-card-content>

        <mat-card-actions align="end">
        </mat-card-actions>
      </mat-card>
    </div>
  </div>
</div>

Je ne comprenais pas que je pouvais centrer l'image (la redimensionner si nécessaire).

EDIT: Merci à la réponse du coreuter, je suis proche d'obtenir ce que je veux.

enter image description here

le premier bloc n'est pas à la même hauteur que les autres. Et j'ai un espace vide à la fin de chaque ligne (je voudrais 5 éléments par ligne).

Le code mis à jour:

<div class="margin-top-20" fxLayout="row wrap" fxLayoutAlign="start center" fxLayoutGap="15px">

                            <mat-card fxFlex="20" (click)="addProduct()" class="mat-card-add-button">
                                <div>
                                    <span style="font-size:32px;text-align:center">+<br />Add product</span>
                                </div>
                            </mat-card>

                            <mat-card fxFlex="20" *ngFor="let product of products; let i = index" class="product">
                                <img class="image" mat-card-image src="{{product.picture.uri}}" alt="photo">
                                <mat-card-title>{{product.name}}</mat-card-title>
                                <mat-card-content>
                                    <p>
                                        test
                                    </p>
                                </mat-card-content>
                                <mat-card-actions align="end">

                                </mat-card-actions>
                            </mat-card>
                        </div>

EDIT 2:

Je pense que c'est presque parfait. J'ai essayé avec un gros contenu dans la div mat-card-content et je ne sais pas si c'est bon. Voici une capture d'écran de ce que j'ai:

enter image description here

Pensez-vous qu'il soit possible d'obtenir les boutons à la même hauteur que la grande carte mat (la dernière)? Une autre chose, je ne vois pas la bordure gauche du premier élément de chaque ligne.

Voici le code mis à jour:

<div class="margin-top-20" fxFlexFill fxLayout="row wrap" fxLayoutAlign="start start" fxLayoutGap="20px">

                            <mat-card fxLayoutAlign="center center" fxFlex="0 1 calc(20% - 20px)" (click)="addProduct()" class="product" style="height:413px">
                                <div>
                                    <span fxLayoutAlign="center center" style="font-size:32px;text-align:center">+<br />Add product</span>
                                </div>
                            </mat-card>

                            <mat-card fxFlexFill fxFlex="0 1 calc(20% - 20px)" *ngFor="let product of products; let i = index" class="product">
                                <img class="image" mat-card-image src="{{product.picture.uri}}" alt="photo">
                                <mat-card-title>{{product.name}}</mat-card-title>
                                <mat-card-content>
                                    <p *ngIf="i == 3">
                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam dapibus, leo id pulvinar vestibulum, ligula nisl tincidunt magna, eu volutpat leo neque quis justo. Fusce semper ante id mi porta porta. Pellentesque nec pretium purus. Curabitur lobortis tempus consectetur. Nam ullamcorper gravida erat sed suscipit. Morbi quis porttitor nunc. Suspendisse lacinia a turpis vitae laoreet. Aliquam pellentesque scelerisque urna. Cras vulputate nisi sed elit commodo cursus. Aenean interdum, erat at convallis dictum, urna enim tincidunt nisi, vitae tempor nisi nisi a tellus. Aliquam volutpat dui eget gravida eleifend. Nullam pulvinar justo eget tellus commodo, eget molestie dui convallis. Curabitur at fermentum lorem. Maecenas porttitor sem ut enim efficitur bibendum et vel metus.
                                    </p>
                                    <p *ngIf="i != 3">
                                           test
                                    </p>
                                </mat-card-content>
                                <mat-card-actions align="end">
                                    <button mat-icon-button>
                                        <mat-icon>mode_edit</mat-icon>
                                    </button>

                                    <button mat-icon-button>
                                        <mat-icon>delete</mat-icon>
                                    </button>
                                </mat-card-actions>
                            </mat-card>
                        </div>

Merci encore pour votre aide, j'apprécie vraiment!

EDIT 3 : Cette version fonctionne !!! Merci beaucoup coreuter! ( https://stackblitz.com/edit/angular-xprafs )

Le contenu de la carte mat n'est pas fixé par la propriété "fxFlex". Le contenu sort de la carte mat. (Cela fonctionne sur le dernier stackblitz mais pas pour moi).

enter image description here

 <div *ngIf="products.length > 0" style="margin-left:10px;">
                        <div fxLayout="row wrap" fxLayoutAlign="start stretch" fxLayoutGap="20px">

                            <mat-card fxLayoutAlign="center center" fxFlex="0 1 calc(20% - 20px)" fxFlex.md="0 1 calc(25% - 20px)" fxFlex.sm="0 1 calc(33% - 20px)" fxHide.xs="true" (click)="addProduct()" class="product mat-card-add-button">
                                <div fxLayoutAlign="center center" style="font-size:32px;text-align:center">+<br />Add product</div>
                            </mat-card>

                            <mat-card fxLayout="column" fxFlex.md="0 1 calc(25% - 20px)" fxFlex="0 1 calc(20% - 20px)" fxFlex.sm="0 1 calc(33% - 20px)" fxFlex.xs="100" *ngFor="let product of products; let i = index" class="product">
                                <img mat-card-image src="{{product.picture.uri}}" alt="photo">
                                <mat-card-title>{{product.name}}</mat-card-title>
                                <mat-card-content fxFlex>
                                        <p *ngIf="i == 3">
                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam dapibus, leo id pulvinar vestibulum, ligula nisl tincidunt
                                            magna, eu volutpat leo neque quis justo. Fusce semper ante id mi porta porta. Pellentesque nec pretium purus. Curabitur
                                            lobortis tempus consectetur. Nam ullamcorper gravida erat sed suscipit. Morbi quis porttitor nunc. Suspendisse lacinia
                                            a turpis vitae laoreet. Aliquam pellentesque scelerisque urna. Cras vulputate nisi sed elit commodo cursus. Aenean interdum,
                                            erat at convallis dictum, urna enim tincidunt nisi, vitae tempor nisi nisi a tellus. Aliquam volutpat dui eget gravida
                                            eleifend. Nullam pulvinar justo eget tellus commodo, eget molestie dui convallis. Curabitur at fermentum lorem. Maecenas
                                            porttitor sem ut enim efficitur bibendum et vel metus.
                                        </p>
                                        <p *ngIf="i != 3">
                                            test
                                        </p>
                                </mat-card-content>
                                <mat-card-actions fxFlexAlign="end" align="end">
                                    <button mat-icon-button>
                                        <mat-icon>mode_edit</mat-icon>
                                    </button>

                                    <button mat-icon-button>
                                        <mat-icon>delete</mat-icon>
                                    </button>
                                </mat-card-actions>
                            </mat-card>
                        </div>
                    </div>

Le css:

.mat-card {
    padding: 18px !important; // less padding than per default
}

.mat-card-image {
    width: calc(100% + 36px) !important; // update padding
    margin: 0 -24px 16px -18px !important; // update padding
}

.mat-tab-label {
    font-size: 16px !important;
}

.mat-card-title {
    font-size:24px !important;
    font-weight: 500 !important;
}

.mat-card-content {
    font-size: 14px !important;
    min-height: 30px; // <--- to remove !!!
}

.product {
    margin-bottom: 25px;
    /*min-width: 180px;
    text-align: center;*/
} 

/* desktop button */
.mat-card-add-button {
    border: 1px dashed grey;
    box-shadow:none !important;
    cursor:pointer;
}

.product img {
    height: 250px;
    object-fit: contain;
}
6
Joe Allen

Puisque j'ai répondu à votre précédente SO question , je vais construire ma réponse à cette question sur ma réponse précédente. Veuillez vous référer à cette mise à jour Stackblitz avec des images de largeur et de hauteur différentes.

Preview

[~ # ~] modifier [~ # ~] : Ajustement de la réponse/stackblitz pour créer une ligne contenant 5 éléments.

Explication

Afin de garder l'image toujours à la même hauteur, j'ai ajouté la classe "image" au <img>- tag (vous pouvez bien sûr appliquer le css à la balise img- directement avec .product img{...} ainsi que).

<img class="image" mat-card-image src="{{product.picture.url}}" alt="photo">

et appliqué le CSS suivant:

.image{
  height: 150px; /* adjust as needed */
  object-fit: contain;
}

Avec object-fit: contain votre image sera toujours correctement mise à l'échelle et entièrement visible dans la zone disponible.

Garde en tête que object-fit est actuellement uniquement entièrement pris en charge par les navigateurs suivants .

MODIFIER:

Pour obtenir 5 éléments dans chaque ligne, vous devez ajuster le fxLayoutGap et le calcul de la largeur de chaque élément en utilisant l'attribut fxFlex. Veuillez modifier votre code comme suit ..

<div class="container" fxLayout="row wrap" fxLayoutAlign="center center" fxLayoutGap="20px">

    <!-- Add addProduct-button outside loop -->
    <mat-card fxFlex="0 1 calc(20% - 20px)" (click)="addProduct()" class="product">
     ...
    </mat-card>

        <!-- loop over the products -->
    <mat-card fxFlex="0 1 calc(20% - 20px)" *ngFor="let product of products; let i = index" class="product">
      ...
    </mat-card>

</div>

.. et changez le 20px défini sur fxLayoutGap et dans le calcul de fxFlex à la valeur souhaitée.

Avec ces valeurs maintenant définies, vous devez appliquer une valeur de largeur minimale, sinon tous les éléments deviendront plus petits en largeur et la ligne ne sera pas bouclée:

.product{
  min-width: 180px; /* adjust as desired */
  min-height: 250px;
  margin-bottom: 20px; /* same as fxLayoutGap for even distribution */
}

EDIT 2

Pour que le premier élément ait la même hauteur que les autres, vous devez régler sur (min-)height de la classe CSS .product doit être égal à la hauteur du produit le plus élevé.

EDIT 3 (pour répondre éditez 2 de la question)

Comme vous n'avez pas encore marqué de réponse à votre question, j'ai modifié le code que vous avez fourni dans votre édition # 2 pour accomplir la conception souhaitée: stackblitz

J'ai changé ce qui suit:

  • changé le fxLayoutAlign du conteneur en "space-evenly stretch" au lieu de fxLayoutAlign="start start" ceci distribue tous les éléments d'une ligne sur l'axe des X de manière uniforme et les fait s'étirer aussi haut que l'élément le plus haut de la ligne.
  • supprimé tout fxFlexFill
  • fxFlex ajouté au contenu de la carte mat
  • supprimé la hauteur de la classe CSS .product

En ce qui concerne la bordure sur le côté gauche .. Je suppose que votre conteneur est trop proche du côté gauche des fenêtres du navigateur. J'ai également changé le conteneur CSS dans mon stackblitz.

6
coreuter

Vous devrez peut-être travailler avec des tailles fixes pour le mat-card et assurez-vous simplement que les images tiennent dans l'espace disponible.

.margin-top-20>div>div {
  display: flex;
  width: 100%;
}

.ad {
  width: 200px;
  height: 250px;
  min-height: 250px;
  max-width: 200px;
  border: thin solid #eee;
}

.ad>div {
  width: 100%;
  height: 200px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.ad>div>img {
  flex: 0 1;
  width: 100%;
  height: auto;
}
<div class="margin-top-20" fxFlexFill fxLayout="row wrap" fxLayout.xs="column" fxLayout.sm="column" fxLayoutGap="15px grid">
  <div fxFlex="20" fxFlex.md="33" *ngFor="let advert of adverts; let i = index" class="padding-fix">
    <div fxFlexFill fxLayoutAlign="center stretch">
      <mat-card class="ad">
        <div fxLayoutAlign="space-between center">
          <img mat-card-image src="https://via.placeholder.com/150x50" alt="test">
        </div>
        <mat-card-title>test</mat-card-title>
        <mat-card-content>
          <p>
            test
          </p>
        </mat-card-content>
        <mat-card-actions align="end">
        </mat-card-actions>
      </mat-card>
      <mat-card class="ad">
        <div fxLayoutAlign="space-between center">
          <img mat-card-image src="https://via.placeholder.com/50x150" alt="test">
        </div>
        <mat-card-title>test</mat-card-title>
        <mat-card-content>
          <p>
            test
          </p>
        </mat-card-content>
        <mat-card-actions align="end">
        </mat-card-actions>
      </mat-card>
      <mat-card class="ad">
        <div fxLayoutAlign="space-between center">
          <img mat-card-image src="https://via.placeholder.com/350x150" alt="test">
        </div>
        <mat-card-title>test</mat-card-title>
        <mat-card-content>
          <p>
            test
          </p>
        </mat-card-content>
        <mat-card-actions align="end">
        </mat-card-actions>
      </mat-card>
    </div>
  </div>
</div>
0
Gerard
.ad{
 display:flex;
 flex-direction:coloumn;
 height:100%;
}
img,mat-card-content{
flex-grow: 1;
}
mat-card-actions{
display: inline-block;
align-self: flex-end;
}

Vous pouvez essayer ça.

0
mkk