angular / components

Component infrastructure and Material Design components for Angular
https://material.angular.io
MIT License
24.24k stars 6.7k forks source link

[Card] Extra margins show when using ripple #10898

Open andrewseguin opened 6 years ago

andrewseguin commented 6 years ago

When matRipple is added to a <mat-card>, the card expands on click.

Reproduction: https://stackblitz.com/edit/angular-1mherw?file=app/card-overview-example.html

This is due to the styling rule that says every element in the card except for the last should have bottom margin. When the ripple is added, the last element is no longer last and so it gains the margin bottom.

https://github.com/angular/material2/blob/master/src/lib/card/card.scss#L190

simeyla commented 6 years ago

Same for mat-table : https://github.com/angular/material2/issues/11165 (well technically the opposite problem where the padding disappears!)

devversion commented 6 years ago

@andrewseguin I tried looking into the issue but couldn't find anything that allows us to skip .mat-ripple-element items when querying for the :last-child.

Technically the ripple elements are valid children that can be also the last element. If we try something like: nth-last-child(1):not(.mat-ripple-element) the counter won't reset, and we'd never reach mat-card-content.

I also tried to select the element before the first .mat-ripple-element if there are ripples, but apparently CSS is not providing a selector to query for elements before another one.

image

Just wanted to summarize my findings real quick. Maybe someone does have some other ideas. I will keep looking into it.

dulikmixail commented 5 years ago

Problem not resolve

kfrankiewicz commented 5 years ago

Please take a look at this thread: https://github.com/angular/material2/issues/14981 - @devversion explanation is clear, To fix the problem, add this code to your global CSS file:

div.mat-ripple-element {
  position: absolute !important;
}
william-lohan commented 5 years ago

Work around doesn't work https://stackblitz.com/edit/angular-material2-card-ripple?file=styles.scss

xgui3783 commented 4 years ago

Stumbled on this issue as well. After some inspection, it seems adding and empty (or not empty) <mat-card-footer> as the last child solves the issue.

https://stackblitz.com/edit/angular-material2-card-ripple-adgv8u

non4me commented 4 years ago

The bug appears not only on the <mat-card>, but also on any other container. Its essence is that during animation matRipple adds side margin to the last element of the container, equal to the gap between the elements inside the container. This means that it ignores the CSS rule: div:last-child {margin-left: 0} (or in case column: div:last-child {margin-bottom: 0}).

A possible workaround is to add the margin to the last element on its own, if design allows it. Or wrap container to other and set matRipple on wrapper.

In this particular topic starter case, the workaround may look like:

<mat-card matRipple>
  <div style="margin-bottom: -15px">
    <mat-card-content>  Click this card to see it expand  </mat-card-content>
  </div>
</mat-card>

More details here: https://stackblitz.com/edit/angular-material2-matripple-i5ugtwissie?file=app/app.component.html

william-lohan commented 4 years ago

I wonder if a ripple solution that uses CSS paint worklet could avoid this issue.

devversion commented 4 years ago

The ripple implementation we currently provide, relies on actual HTML elements being added to the DOM. This could indeed be an issue for any container that relies on order (e.g. through CSS last-child).

We are working on MDC components that might also involve a new implementation of ripples. At time of writing, MDC uses pseudo elements for those. That might fix this issue, but could cause other issues due to conflicting pseudo elements. I don't believe there is a good ripple solution that works in all cases though.

Skrigueztep commented 3 years ago

I´m some time ago, do this:

<mat-card matRipple class="technologies__card">
    <div class="card__container">
        <img class="card__image" alt="text" src="url" >
         <span class="card__title">name</span>
   </div>
</mat-card>

Adding a div inside a mat-card element this problem was fixed but after an update to v9 of angular framework, doesn´t work. A posible solution is add to global styles the following code:

.mat-ripple-element {
   display: none;
}

But this, delete a ripple effect, so as well im tryed replace display: none; by padding/margin: 0 !important; and doesn´t work...

Somebody have another workaround solution?

UPDATE:

Same problem occurs at mat-slide-toggle inside container with display flex <- A solution for this, can be:

.mat-ripple-element {
   display: none;
}

This not affect at functionality or effect of mat-slide-toggle

jelbourn commented 3 years ago

Confirming that this is still an issue with the MDC-based card: https://stackblitz.com/edit/angular-mdc-issue-rqjw6o?file=src%2Fapp%2Fmdc%2Fmdc-example-module.ts

The issue is still the :last-child style that adds margin and the ripple becoming the last-child while active.

litwin90 commented 3 years ago

I faced the same issue. I managed to avoid it by using an empty mat-card-footer . In this case :last-child won't be applied

stefanolsenn commented 3 years ago

Temporary workaround is to add a <span style="position: absolute"></span> as the last child of the matRipple container

stnor commented 2 years ago

margin-bottom: 0 on the last element in a mat-card works fine too.