Components: bug(drag-drop): moved item doesn't retain inherited styles

Created on 24 Sep 2018  路  23Comments  路  Source: angular/components

Bug, feature request, or proposal:

Bug

What is the expected behavior?

When dragging around an item, all styles (included the inherited ones) shall be retained to keep the look&feel consistent

What is the current behavior?

Inherithed styles are not retained

What are the steps to reproduce?

  1. Create a list of elements suitable for D&D
  2. Add mat-typography class on the cdk-drop container
  3. Drag one item of the list and notice that it doesn't retain Roboto font

What is the use-case or motivation for changing an existing behavior?

Consistency

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Angular 6.1.8
Material 6.4.7

Is there anything else we should know?

As a workaround it's possible to add to items a class with all needed styles which would have been inherited from the container.

Being moved to root level (aka out of it's normal containers and CSS rules flow) for the duration of the dragging event, the item should have all currently applied inherited CSS rules copied to avoid inconsistent look&feel

P3 cddrag-drop feature has pr

Most helpful comment

This is especially cumbersome when working with mat-list-items that need to be children of a mat-list in order for their styling to be applied correctly.

All 23 comments

This is tricky to do without breaking something else. The reason for the element to be moved to the bottom of the body is to avoid issues with z-index and overflow. We may be able to get away with keeping the element in place since it's position: fixed, however its z-index is still bound by the z-index of its parent elements.

Is it possible & feasible to find out, using JS, all inherited CSS properties, apply them as inline style for the duration of the drag and then remove them when drag ends?

Otherwise, in absence of a clean solution, putting in the docs a disclaimer about this behaviour (and why it is like this in the first place) together with the workaround I wrote can be enough I guess.
Even if this will not be feasible if the developer doesn't know the container inside which he's enabling the drag&drop (edge case, but still possible maybe).

A dedicated class added to the moving placeholder can be a good thing too, which let the developer know that this behaviour is known and is currently fixed via a workaround.

Copying all of the styles probably won't be feasible. Also, for what it's worth, there's the cdk-drag-preview class which can be used to style the preview as it's being dragged.

Makes sense, I already saw that class but didn't actually though about using it.
I don't have other ideas about how to solve the issue currently (:

This is especially cumbersome when working with mat-list-items that need to be children of a mat-list in order for their styling to be applied correctly.

I experience the same issue with mat-selection-list and mat-list-option

same issue :

<mat-nav-list class="p-0 " perfectScrollbar> <mat-list dense cdkDropList [cdkDropListData]="sharedService.sharedUserProfiles" [cdkDropListConnectedTo]="getCategoryIds()" class="top-margin"> <mat-divider></mat-divider> <mat-list-item class="cust-display-list" mat-line *ngFor="let profile of sharedService.sharedUserProfiles, let i = index" cdkDrag> <img matListAvatar class="fix-avatar-height" src="/assets/user.jpg" alt="..."> <h3 matLine>{{profile.info.fullname}} </h3> <p matLine> <span> {{profile.info.title}}</span> </p> <button mat-icon-button> <mat-icon>drag_indicator</mat-icon> </button> <mat-divider></mat-divider> </mat-list-item> </mat-list> </mat-nav-list>

drag_style

Has anyone figured out a workaround, other than adding styles inline?

for me styling the .cdk-drag-preview class (which is on the drag preview element) worked. Maybe this helps in some of your cases too.

there's the cdk-drag-preview class which can be used to style the preview as it's being dragged.

This is the official way I guess.
Just define a placeholder in SCSS and extend it both on its normal selector and on cdk-drag-preview

I noticed that CSS id's are not being rendered inside the cdk-drag-preview div. I replaced every id with a css class which was then passed through to the preview element. That fixed our problem.

My solution was to extend/use the same styles.
e.g using scss it can be look like this:

.element {
 // some styles properties
}

.cdk-drag-preview {
  @extend .element; 
}

Or simply take the common selector.

// html
<element class="element-class" cdkDrag>

// css

.cdk-drag-preview,
.element-class {
 // here common styles
}

Also experiencing the same issues with mat-nav-list items.

same issue here, with their official example modified to mat-list and mat-list-item.

https://stackblitz.com/edit/angular-s8tsj1?file=src/app/cdk-drag-drop-sorting-example.html

I'm having the same issue. In my case, none of the above fixes are working for me.

               <mat-list role="list" dense cdkDropList class="example-list" (cdkDropListDropped)="orderReport($event)">
                    <mat-list-item role="listitem" class="report-list-item" *ngFor="let selectedReport of selectedReports;let i=index" cdkDrag>
                        <mat-icon matListIcon>drag_indicator</mat-icon>
                        <h4 matLine>{{selectedReport.name}}</h4>
                        <p matLine class="category"> {{selectedReport.categoryId}} </p>
                        <mat-icon class="icon-close" (click)=removeReport(i)>close</mat-icon>
                        <mat-divider></mat-divider>
                    </mat-list-item>
                </mat-list>

Any lead for this?

Seems ::ng-deep is an alternative.

```
::ng-deep .cdk-drag-preview .mat-list-item-content{
display: flex;
flex-direction: row;
align-items: center;
box-sizing: border-box;
padding: 0 16px;
position: relative;
height: inherit;
}

Any update on this issue?

I have this issue is well. The problem for me is that my styling comes from a CDN and is very much based on hierarchy of id's and classes. When the preview is rendered outside this hierarchy, all styling is lost. Manually applying the style is not really an option for me. Anyone has any (other) workarounds?

for me the problem is solved by copying the css from the example in the official docs
cdk-drag-drop-sorting-example

My solution was to extend/use the same styles.
e.g using scss it can be look like this:

.element {
 // some styles properties
}

.cdk-drag-preview {
  @extend .element; 
}

Or simply take the common selector.

// html
<element class="element-class" cdkDrag>

// css

.cdk-drag-preview,
.element-class {
 // here common styles
}

this actually is not even a workaround its simple, clean, breaks nothing, and just easily works. although it will only work if you got one draglist, if you have another one it will get the same css

I've just put in a PR which may help here,
It allows for you to control where the cdkDrag preview clone is appended to.
I appreciate this may not work for all situations (z-index specifically)

In my case, when I was dragging an item, the newly created element appended to the end of the body had lost a class that some angular material child elements were using so I added it using PreviewClass property in the CdkDrag element and it worked.

[cdkDragPreviewClass]="'default-theme'"

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

3mp3ri0r picture 3mp3ri0r  路  3Comments

LoganDupont picture LoganDupont  路  3Comments

crutchcorn picture crutchcorn  路  3Comments

xtianus79 picture xtianus79  路  3Comments

kara picture kara  路  3Comments